# HG changeset patch # User Frank Benoit # Date 1220830690 -7200 # Node ID 71ec57b4c8f387c74801f14f5ecf6f5ef561a7f3 # Parent 20cdc983a4116d57b37af87dc93ac7a6d45c1433# Parent e5dd0081ccba178b15214c9771cb2b46b361aebc merge diff -r 20cdc983a411 -r 71ec57b4c8f3 collectionimp.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/collectionimp.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,93 @@ +module packageimport; + +import tango.io.FilePath; +import tango.io.File; +import tango.io.Buffer; +import tango.io.stream.FileStream; +import tango.io.stream.TextFileStream; +import tango.util.log.Trace; +import tango.text.Regex; +import tango.text.Util; +import tango.text.stream.LineIterator; +import tango.text.convert.Format; + +const char[][] javaimps = [ +"import java.util.ArrayList;", +"import java.util.Arrays;", +"import java.util.Collection;", +"import java.util.Collections;", +"import java.util.HashMap;", +"import java.util.HashSet;", +"import java.util.IdentityHashMap;", +"import java.util.Iterator;", +"import java.util.LinkedHashMap;", +"import java.util.LinkedList;", +"import java.util.List;", +"import java.util.ListIterator;", +"import java.util.Map;", +"import java.util.Map.Entry;", +"import java.util.Set;", +"import java.util.Comparator;", +"import java.util.Stack;" +]; +void processDir( char[] dir ){ + auto pack = dir.dup.replace( '/', '.' ); + auto fp = FilePath(dir); + char[][] mods; + // read all module names + foreach( fileinfo; fp ){ + if( fileinfo.folder ){ + processDir( fileinfo.path ~ fileinfo.name ); + continue; + } + if( fileinfo.name.length > 2 && fileinfo.name[ $-2 .. $ ] == ".d" ){ + mods ~= fileinfo.name.dup; + } + } + // foreach module + foreach( mod; mods ){ + auto filename = Format("{}/{}", dir, mod ); + auto cont = cast(char[])File( filename ).read; + char[][] lines = cont.splitLines(); + char[][] outlines = lines.dup; + bool found = true; + foreach( uint idx, char[] line; lines ){ + foreach( javaimp; javaimps ){ + if( line == javaimp ){ + outlines[idx] = found ? "import dwtx.dwtxhelper.Collection;" : ""; + found = false; + } + } + } + if( !found ){ + Trace.formatln( "{} ", filename ); + bool first = true; + auto output = new TextFileOutput( filename ); + foreach( line; outlines ){ + if( !first ){ + output.write( \n ); + } + first = false; + output.write( line ); + } + output.flush(); + output.close(); + } + } + // read content into buffer + // search module statement and print to outfile + // write package imports + // write all remaining lines +} + +void main(){ + processDir( "dwtx/text" ); + processDir( "dwtx/jface/text" ); + processDir( "dwtx/jface/internal/text" ); +} + + + + + + diff -r 20cdc983a411 -r 71ec57b4c8f3 dsss.conf --- a/dsss.conf Mon Sep 08 01:37:00 2008 +0200 +++ b/dsss.conf Mon Sep 08 01:38:10 2008 +0200 @@ -1,7 +1,17 @@ + +[fixmodule.d] +[collectionimp.d] [dwtx] type=library buildflags+=-Jres + +#exclude the incomplete JFace.Text +exclude+=dwtx/text +exclude+=dwtx/jface/contentassist +exclude+=dwtx/jface/text +exclude+=dwtx/jface/internal/text + version(linux){ buildflags+=-I../dwt-linux } diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/core/internal/jobs/ThreadJob.d --- a/dwtx/core/internal/jobs/ThreadJob.d Mon Sep 08 01:37:00 2008 +0200 +++ b/dwtx/core/internal/jobs/ThreadJob.d Mon Sep 08 01:38:10 2008 +0200 @@ -119,7 +119,7 @@ String msg = buf.toString(); if (JobManager.DEBUG || JobManager.DEBUG_BEGIN_END) { Stdout.formatln("{}",msg); - Exception t = lastPush is null ? new IllegalArgumentException("") : lastPush; + Exception t = lastPush is null ? cast(Exception)new IllegalArgumentException("") : cast(Exception)lastPush; IStatus error = new Status(IStatus.ERROR, JobManager.PI_JOBS, 1, msg, t); RuntimeLog.log(error); } diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/core/runtime/ILog.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/core/runtime/ILog.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,68 @@ +/******************************************************************************* + * 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 + * 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.core.runtime.ILog; + +import dwt.dwthelper.utils; +import dwtx.core.runtime.ILogListener; +import dwtx.core.runtime.IStatus; + +import dwtx.org.osgi.framework.Bundle; + +/** + * A log to which status events can be written. Logs appear on individual + * plug-ins and on the platform itself. Clients can register log listeners which + * will receive notification of all log events as they come in. + *

+ * XXX Need to create a new log interface on common plugin. That interface should be a super interface of this ILog. + * getBundle() would stay here. In the super interface we would have getName() + *

+ * + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ILog { + /** + * Adds the given log listener to this log. Subsequently the log listener will + * receive notification of all log events passing through this log. + * This method has no affect if the identical listener is already registered on this log. + * + * @param listener the listener to add to this log + * @see Platform#addLogListener(ILogListener) + */ + public void addLogListener(ILogListener listener); + + /** + * Returns the plug-in with which this log is associated. + * + * @return the plug-in with which this log is associated + * @since 3.0 + */ + public Bundle getBundle(); + + /** + * Logs the given status. The status is distributed to the log listeners + * installed on this log and then to the log listeners installed on the platform. + * + * @param status the status to log + */ + public void log(IStatus status); + + /** + * Removes the given log listener to this log. Subsequently the log listener will + * no longer receive notification of log events passing through this log. + * This method has no affect if the identical listener is not registered on this log. + * + * @param listener the listener to remove + * @see Platform#removeLogListener(ILogListener) + */ + public void removeLogListener(ILogListener listener); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/core/runtime/Platform.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/core/runtime/Platform.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,1578 @@ +/******************************************************************************* + * 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 + * 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.core.runtime.Platform; + +import dwt.dwthelper.utils; + +import dwtx.core.runtime.IPath; +import dwtx.core.runtime.ILog; +// import java.io.IOException; +// import java.lang.reflect.Method; +// import java.net.URL; +// import java.util.HashMap; +// import java.util.Map; +// import java.util.MissingResourceException; +// import java.util.ResourceBundle; +// +import dwtx.org.osgi.framework.Bundle; +// import org.osgi.service.packageadmin.PackageAdmin; +// +// import dwtx.core.internal.runtime.CompatibilityHelper; +// import dwtx.core.internal.runtime.InternalPlatform; +// import dwtx.core.internal.runtime.Messages; +// import dwtx.core.internal.runtime.PlatformActivator; +// import dwtx.core.internal.runtime.auth.AuthorizationHandler; +// import dwtx.core.runtime.content.IContentTypeManager; +// import dwtx.core.runtime.jobs.IJobManager; +// import dwtx.core.runtime.jobs.Job; +// import dwtx.core.runtime.preferences.IPreferencesService; +// import dwtx.osgi.service.datalocation.Location; +// import dwtx.osgi.service.debug.DebugOptions; +// import dwtx.osgi.service.environment.EnvironmentInfo; +// import dwtx.osgi.service.resolver.PlatformAdmin; + +/** + * The central class of the Eclipse Platform Runtime. This class cannot + * be instantiated or subclassed by clients; all functionality is provided + * by static methods. Features include: + *
    + *
  • the platform registry of installed plug-ins
  • + *
  • the platform adapter manager
  • + *
  • the platform log
  • + *
  • the authorization info management
  • + *
+ *

+ * Most users don't have to worry about Platform's lifecycle. However, if your + * code can call methods of this class when Platform is not running, it becomes + * necessary to check {@link #isRunning()} before making the call. A runtime + * exception might be thrown or incorrect result might be returned if a method + * from this class is called while Platform is not running. + *

+ */ +public final class Platform { + +// /** +// * The unique identifier constant (value "dwtx.core.runtime") +// * of the Core Runtime (pseudo-) plug-in. +// */ +// public static final String PI_RUNTIME = "dwtx.core.runtime"; //$NON-NLS-1$ +// +// /** +// * The simple identifier constant (value "applications") of +// * the extension point of the Core Runtime plug-in where plug-ins declare +// * the existence of runnable applications. A plug-in may define any +// * number of applications; however, the platform is only capable +// * of running one application at a time. +// * +// */ +// public static final String PT_APPLICATIONS = "applications"; //$NON-NLS-1$ +// +// /** +// * The simple identifier constant (value "adapters") of +// * the extension point of the Core Runtime plug-in where plug-ins declare +// * the existence of adapter factories. A plug-in may define any +// * number of adapters. +// * +// * @see IAdapterManager#hasAdapter(Object, String) +// * @since 3.0 +// */ +// public static final String PT_ADAPTERS = "adapters"; //$NON-NLS-1$ +// +// /** +// * The simple identifier constant (value "preferences") of +// * the extension point of the Core Runtime plug-in where plug-ins declare +// * extensions to the preference facility. A plug-in may define any number +// * of preference extensions. +// * +// * @see #getPreferencesService() +// * @since 3.0 +// */ +// public static final String PT_PREFERENCES = Preferences.PT_PREFERENCES; +// +// /** +// * The simple identifier constant (value "products") of +// * the extension point of the Core Runtime plug-in where plug-ins declare +// * the existence of a product. A plug-in may define any +// * number of products; however, the platform is only capable +// * of running one product at a time. +// * +// * @see #getProduct() +// * @since 3.0 +// */ +// public static final String PT_PRODUCT = "products"; //$NON-NLS-1$ +// +// /** +// * Debug option value denoting the time at which the platform runtime +// * was started. This constant can be used in conjunction with +// * getDebugOption to find the string value of +// * System.currentTimeMillis() when the platform was started. +// */ +// public static final String OPTION_STARTTIME = PI_RUNTIME + "/starttime"; //$NON-NLS-1$ +// +// /** +// * Name of a preference for configuring the performance level for this system. +// * +// *

+// * This value can be used by all components to customize features to suit the +// * speed of the user's machine. The platform job manager uses this value to make +// * scheduling decisions about background jobs. +// *

+// *

+// * The preference value must be an integer between the constant values +// * MIN_PERFORMANCE and MAX_PERFORMANCE +// *

+// * @see #MIN_PERFORMANCE +// * @see #MAX_PERFORMANCE +// * @since 3.0 +// */ +// public static final String PREF_PLATFORM_PERFORMANCE = "runtime.performance"; //$NON-NLS-1$ +// +// /** +// * Constant (value "line.separator") name of the preference used for storing +// * the line separator. +// * +// * @see #knownPlatformLineSeparators +// * @since 3.1 +// */ +// public static final String PREF_LINE_SEPARATOR = "line.separator"; //$NON-NLS-1$ +// +// /** +// * Constant (value 1) indicating the minimum allowed value for the +// * PREF_PLATFORM_PERFORMANCE preference setting. +// * @since 3.0 +// */ +// public static final int MIN_PERFORMANCE = 1; +// +// /** +// * Constant (value 5) indicating the maximum allowed value for the +// * PREF_PLATFORM_PERFORMANCE preference setting. +// * @since 3.0 +// */ +// public static final int MAX_PERFORMANCE = 5; +// +// /** +// * Status code constant (value 1) indicating a problem in a plug-in +// * manifest (plugin.xml) file. +// */ +// public static final int PARSE_PROBLEM = 1; +// +// /** +// * Status code constant (value 2) indicating an error occurred while running a plug-in. +// */ +// public static final int PLUGIN_ERROR = 2; +// +// /** +// * Status code constant (value 3) indicating an error internal to the +// * platform has occurred. +// */ +// public static final int INTERNAL_ERROR = 3; +// +// /** +// * Status code constant (value 4) indicating the platform could not read +// * some of its metadata. +// */ +// public static final int FAILED_READ_METADATA = 4; +// +// /** +// * Status code constant (value 5) indicating the platform could not write +// * some of its metadata. +// */ +// public static final int FAILED_WRITE_METADATA = 5; +// +// /** +// * Status code constant (value 6) indicating the platform could not delete +// * some of its metadata. +// */ +// public static final int FAILED_DELETE_METADATA = 6; +// +// /** +// * Constant string (value "win32") indicating the platform is running on a +// * Window 32-bit operating system (e.g., Windows 98, NT, 2000). +// *

+// * Note this constant has been moved from the deprecated +// * dwtx.core.boot.BootLoader class and its value has not changed. +// *

+// * @since 3.0 +// */ +// public static final String OS_WIN32 = "win32";//$NON-NLS-1$ +// +// /** +// * Constant string (value "linux") indicating the platform is running on a +// * Linux-based operating system. +// *

+// * Note this constant has been moved from the deprecated +// * dwtx.core.boot.BootLoader class and its value has not changed. +// *

+// * @since 3.0 +// */ +// public static final String OS_LINUX = "linux";//$NON-NLS-1$ +// +// /** +// * Constant string (value "aix") indicating the platform is running on an +// * AIX-based operating system. +// *

+// * Note this constant has been moved from the deprecated +// * dwtx.core.boot.BootLoader class and its value has not changed. +// *

+// * @since 3.0 +// */ +// public static final String OS_AIX = "aix";//$NON-NLS-1$ +// +// /** +// * Constant string (value "solaris") indicating the platform is running on a +// * Solaris-based operating system. +// *

+// * Note this constant has been moved from the deprecated +// * dwtx.core.boot.BootLoader class and its value has not changed. +// *

+// * @since 3.0 +// */ +// public static final String OS_SOLARIS = "solaris";//$NON-NLS-1$ +// +// /** +// * Constant string (value "hpux") indicating the platform is running on an +// * HP/UX-based operating system. +// *

+// * Note this constant has been moved from the deprecated +// * dwtx.core.boot.BootLoader class and its value has not changed. +// *

+// * @since 3.0 +// */ +// public static final String OS_HPUX = "hpux";//$NON-NLS-1$ +// +// /** +// * Constant string (value "qnx") indicating the platform is running on a +// * QNX-based operating system. +// *

+// * Note this constant has been moved from the deprecated +// * dwtx.core.boot.BootLoader class and its value has not changed. +// *

+// * @since 3.0 +// */ +// public static final String OS_QNX = "qnx";//$NON-NLS-1$ +// +// /** +// * Constant string (value "macosx") indicating the platform is running on a +// * Mac OS X operating system. +// *

+// * Note this constant has been moved from the deprecated +// * dwtx.core.boot.BootLoader class and its value has not changed. +// *

+// * @since 3.0 +// */ +// public static final String OS_MACOSX = "macosx";//$NON-NLS-1$ +// +// /** +// * Constant string (value "unknown") indicating the platform is running on a +// * machine running an unknown operating system. +// *

+// * Note this constant has been moved from the deprecated +// * dwtx.core.boot.BootLoader class and its value has not changed. +// *

+// * @since 3.0 +// */ +// public static final String OS_UNKNOWN = "unknown";//$NON-NLS-1$ +// +// /** +// * Constant string (value "x86") indicating the platform is running on an +// * x86-based architecture. +// *

+// * Note this constant has been moved from the deprecated +// * dwtx.core.boot.BootLoader class and its value has not changed. +// *

+// * @since 3.0 +// */ +// public static final String ARCH_X86 = "x86";//$NON-NLS-1$ +// +// /** +// * Constant string (value "PA_RISC") indicating the platform is running on an +// * PA_RISC-based architecture. +// *

+// * Note this constant has been moved from the deprecated +// * dwtx.core.boot.BootLoader class and its value has not changed. +// *

+// * @since 3.0 +// */ +// public static final String ARCH_PA_RISC = "PA_RISC";//$NON-NLS-1$ +// +// /** +// * Constant string (value "ppc") indicating the platform is running on an +// * PowerPC-based architecture. +// *

+// * Note this constant has been moved from the deprecated +// * dwtx.core.boot.BootLoader class and its value has not changed. +// *

+// * @since 3.0 +// */ +// public static final String ARCH_PPC = "ppc";//$NON-NLS-1$ +// +// /** +// * Constant string (value "sparc") indicating the platform is running on an +// * Sparc-based architecture. +// *

+// * Note this constant has been moved from the deprecated +// * dwtx.core.boot.BootLoader class and its value has not changed. +// *

+// * @since 3.0 +// */ +// public static final String ARCH_SPARC = "sparc";//$NON-NLS-1$ +// +// /** +// * Constant string (value "x86_64") indicating the platform is running on an +// * x86 64bit-based architecture. +// * +// * @since 3.1 +// */ +// public static final String ARCH_X86_64 = "x86_64";//$NON-NLS-1$ +// +// /** +// * Constant string (value "amd64") indicating the platform is running on an +// * AMD64-based architecture. +// * +// * @since 3.0 +// * @deprecated use ARCH_X86_64 instead. Note the values +// * has been changed to be the value of the ARCH_X86_64 constant. +// */ +// public static final String ARCH_AMD64 = ARCH_X86_64; +// +// /** +// * Constant string (value "ia64") indicating the platform is running on an +// * IA64-based architecture. +// * +// * @since 3.0 +// */ +// public static final String ARCH_IA64 = "ia64"; //$NON-NLS-1$ +// +// /** +// * Constant string (value "ia64_32") indicating the platform is running on an +// * IA64 32bit-based architecture. +// * +// * @since 3.1 +// */ +// public static final String ARCH_IA64_32 = "ia64_32";//$NON-NLS-1$ +// +// /** +// * Constant string (value "win32") indicating the platform is running on a +// * machine using the Windows windowing system. +// *

+// * Note this constant has been moved from the deprecated +// * dwtx.core.boot.BootLoader class and its value has not changed. +// *

+// * @since 3.0 +// */ +// public static final String WS_WIN32 = "win32";//$NON-NLS-1$ +// +// /** +// * Constant string (value "motif") indicating the platform is running on a +// * machine using the Motif windowing system. +// *

+// * Note this constant has been moved from the deprecated +// * dwtx.core.boot.BootLoader class and its value has not changed. +// *

+// * @since 3.0 +// */ +// public static final String WS_MOTIF = "motif";//$NON-NLS-1$ +// +// /** +// * Constant string (value "gtk") indicating the platform is running on a +// * machine using the GTK windowing system. +// *

+// * Note this constant has been moved from the deprecated +// * dwtx.core.boot.BootLoader class and its value has not changed. +// *

+// * @since 3.0 +// */ +// public static final String WS_GTK = "gtk";//$NON-NLS-1$ +// +// /** +// * Constant string (value "photon") indicating the platform is running on a +// * machine using the Photon windowing system. +// *

+// * Note this constant has been moved from the deprecated +// * dwtx.core.boot.BootLoader class and its value has not changed. +// *

+// * @since 3.0 +// */ +// public static final String WS_PHOTON = "photon";//$NON-NLS-1$ +// +// /** +// * Constant string (value "carbon") indicating the platform is running on a +// * machine using the Carbon windowing system (Mac OS X). +// *

+// * Note this constant has been moved from the deprecated +// * dwtx.core.boot.BootLoader class and its value has not changed. +// *

+// * @since 3.0 +// */ +// public static final String WS_CARBON = "carbon";//$NON-NLS-1$ +// +// /** +// * Constant string (value "wpf") indicating the platform is running on a +// * machine using the WPF windowing system. +// * @since 3.3 +// */ +// public static final String WS_WPF = "wpf";//$NON-NLS-1$ +// +// /** +// * Constant string (value "unknown") indicating the platform is running on a +// * machine running an unknown windowing system. +// *

+// * Note this constant has been moved from the deprecated +// * dwtx.core.boot.BootLoader class and its value has not changed. +// *

+// * @since 3.0 +// */ +// public static final String WS_UNKNOWN = "unknown";//$NON-NLS-1$ +// +// // private constants for platform line separators and their associated platform names +// private static final String LINE_SEPARATOR_KEY_MAC_OS_9 = Messages.line_separator_platform_mac_os_9; +// private static final String LINE_SEPARATOR_KEY_UNIX = Messages.line_separator_platform_unix; +// private static final String LINE_SEPARATOR_KEY_WINDOWS = Messages.line_separator_platform_windows; +// +// private static final String LINE_SEPARATOR_VALUE_CR = "\r"; //$NON-NLS-1$ +// private static final String LINE_SEPARATOR_VALUE_LF = "\n"; //$NON-NLS-1$ +// private static final String LINE_SEPARATOR_VALUE_CRLF = "\r\n"; //$NON-NLS-1$ +// +// /** +// * Private constructor to block instance creation. +// */ +// private Platform() { +// super(); +// } +// +// /** +// * Adds the given authorization information to the key ring. The +// * information is relevant for the specified protection space and the +// * given authorization scheme. The protection space is defined by the +// * combination of the given server URL and realm. The authorization +// * scheme determines what the authorization information contains and how +// * it should be used. The authorization information is a Map +// * of String to String and typically +// * contains information such as user names and passwords. +// * +// * @param serverUrl the URL identifying the server for this authorization +// * information. For example, "http://www.example.com/". +// * @param realm the subsection of the given server to which this +// * authorization information applies. For example, +// * "realm1@example.com" or "" for no realm. +// * @param authScheme the scheme for which this authorization information +// * applies. For example, "Basic" or "" for no authorization scheme +// * @param info a Map containing authorization information +// * such as user names and passwords (key type : String, +// * value type : String) +// * @exception CoreException if there are problems setting the +// * authorization information. Reasons include: +// *
    +// *
  • The keyring could not be saved.
  • +// *
+// * @deprecated Authorization database is superseded by the Equinox secure storage. +// * Use dwtx.equinox.security.storage.SecurePreferencesFactory +// * to obtain secure preferences and dwtx.equinox.security.storage.ISecurePreferences +// * for data access and modifications. +// * Consider using ISecurePreferences#put(String, String, bool) as a replacement of this method. +// */ +// public static void addAuthorizationInfo(URL serverUrl, String realm, String authScheme, Map info) throws CoreException { +// try { +// AuthorizationHandler.addAuthorizationInfo(serverUrl, realm, authScheme, info); +// } catch (NoClassDefFoundError e) { +// // The authorization code is not available so just log and continue +// logAuthNotAvailable(e); +// } +// } +// +// /** +// * Adds the given log listener to the notification list of the platform. +// *

+// * Once registered, a listener starts receiving notification as entries +// * are added to plug-in logs via ILog.log(). The listener continues to +// * receive notifications until it is replaced or removed. +// *

+// * +// * @param listener the listener to register +// * @see ILog#addLogListener(ILogListener) +// * @see #removeLogListener(ILogListener) +// * XXX Use the LogMgr service. +// */ +// public static void addLogListener(ILogListener listener) { +// InternalPlatform.getDefault().addLogListener(listener); +// } +// +// /** +// * Adds the specified resource to the protection space specified by the +// * given realm. All targets at or deeper than the depth of the last +// * symbolic element in the path of the given resource URL are assumed to +// * be in the same protection space. +// * +// * @param resourceUrl the URL identifying the resources to be added to +// * the specified protection space. For example, +// * "http://www.example.com/folder/". +// * @param realm the name of the protection space. For example, +// * "realm1@example.com" +// * @exception CoreException if there are problems setting the +// * authorization information. Reasons include: +// *
    +// *
  • The key ring could not be saved.
  • +// *
+// * @deprecated Authorization database is superseded by the Equinox secure storage. +// * Use dwtx.equinox.security.storage.SecurePreferencesFactory +// * to obtain secure preferences and dwtx.equinox.security.storage.ISecurePreferences +// * for data access and modifications. +// */ +// public static void addProtectionSpace(URL resourceUrl, String realm) throws CoreException { +// try { +// AuthorizationHandler.addProtectionSpace(resourceUrl, realm); +// } catch (NoClassDefFoundError e) { +// // The authorization code is not available so just log and continue +// logAuthNotAvailable(e); +// } +// } +// +// /** +// * Returns a URL that is the local equivalent of the +// * supplied URL. This method is expected to be used with the +// * plug-in-relative URLs returned by IPluginDescriptor, Bundle.getEntry() +// * and Platform.find(). +// * If the specified URL is not a plug-in-relative URL, it +// * is returned as is. If the specified URL is a plug-in-relative +// * URL of a file (including .jar archive), it is returned as +// * a locally accessible URL using "file:" protocol +// * (extracting/caching the file locally, if required). If the specified URL +// * is a plug-in-relative URL of a directory, the directory and any files and directories +// * under it are made locally accessible likewise. +// * +// * @param url original plug-in-relative URL. +// * @return the resolved URL +// * @exception IOException if unable to resolve URL +// * @see #resolve(URL) +// * @see #find(Bundle, IPath) +// * @see Bundle#getEntry(String) +// * @deprecated use {@link FileLocator#toFileURL(URL)} instead +// */ +// public static URL asLocalURL(URL url) throws IOException { +// return FileLocator.toFileURL(url); +// } +// +// /** +// * Takes down the splash screen if one was put up. +// * XXX this is application life cycle. Need to have the appropriate method on IApplication. +// */ +// public static void endSplash() { +// InternalPlatform.getDefault().endSplash(); +// } +// +// /** +// * Removes the authorization information for the specified protection +// * space and given authorization scheme. The protection space is defined +// * by the given server URL and realm. +// * +// * @param serverUrl the URL identifying the server to remove the +// * authorization information for. For example, +// * "http://www.example.com/". +// * @param realm the subsection of the given server to remove the +// * authorization information for. For example, +// * "realm1@example.com" or "" for no realm. +// * @param authScheme the scheme for which the authorization information +// * to remove applies. For example, "Basic" or "" for no +// * authorization scheme. +// * @exception CoreException if there are problems removing the +// * authorization information. Reasons include: +// *
    +// *
  • The keyring could not be saved.
  • +// *
+// * @deprecated Authorization database is superseded by the Equinox secure storage. +// * Use dwtx.equinox.security.storage.SecurePreferencesFactory +// * to obtain secure preferences and dwtx.equinox.security.storage.ISecurePreferences +// * for data access and modifications. +// * Consider using ISecurePreferences#clear() as a replacement of this method. +// */ +// public static void flushAuthorizationInfo(URL serverUrl, String realm, String authScheme) throws CoreException { +// try { +// AuthorizationHandler.flushAuthorizationInfo(serverUrl, realm, authScheme); +// } catch (NoClassDefFoundError e) { +// // The authorization code is not available so just log and continue +// logAuthNotAvailable(e); +// } +// } +// +// private static void logAuthNotAvailable(Throwable e) { +// InternalPlatform.getDefault().log(new Status(IStatus.WARNING, Platform.PI_RUNTIME, 0, Messages.auth_notAvailable, null)); +// } +// +// /** +// * Returns the adapter manager used for extending +// * IAdaptable objects. +// * +// * @return the adapter manager for this platform +// * @see IAdapterManager +// * XXX register as a service (same pattern than Jobs) +// * Do we want to make it available as a singleton? +// */ +// public static IAdapterManager getAdapterManager() { +// return InternalPlatform.getDefault().getAdapterManager(); +// } +// +// /** +// * Returns the authorization information for the specified protection +// * space and given authorization scheme. The protection space is defined +// * by the given server URL and realm. Returns null if no +// * such information exists. +// * +// * @param serverUrl the URL identifying the server for the authorization +// * information. For example, "http://www.example.com/". +// * @param realm the subsection of the given server to which the +// * authorization information applies. For example, +// * "realm1@example.com" or "" for no realm. +// * @param authScheme the scheme for which the authorization information +// * applies. For example, "Basic" or "" for no authorization scheme +// * @return the authorization information for the specified protection +// * space and given authorization scheme, or null if no +// * such information exists +// * @deprecated Authorization database is superseded by the Equinox secure storage. +// * Use dwtx.equinox.security.storage.SecurePreferencesFactory +// * to obtain secure preferences and dwtx.equinox.security.storage.ISecurePreferences +// * for data access and modifications. +// * Consider using ISecurePreferences#get(String, String) as a replacement of this method. +// */ +// public static Map getAuthorizationInfo(URL serverUrl, String realm, String authScheme) { +// try { +// return AuthorizationHandler.getAuthorizationInfo(serverUrl, realm, authScheme); +// } catch (NoClassDefFoundError e) { +// // The authorization code is not available so just log and continue +// logAuthNotAvailable(e); +// } +// return null; +// } +// +// /** +// * Returns the command line args provided to the Eclipse runtime layer when it was first run. +// * The returned value does not include arguments consumed by the lower levels of Eclipse +// * (e.g., OSGi or the launcher). +// * Note that individual platform runnables may be provided with different arguments +// * if they are being run individually rather than with Platform.run(). +// *

+// * Clients are also able to acquire the {@link EnvironmentInfo} service and query it for +// * the command-line arguments. +// *

+// * @return the command line used to start the platform +// */ +// public static String[] getCommandLineArgs() { +// return InternalPlatform.getDefault().getCommandLineArgs(); +// } +// +// /** +// * Returns the content type manager. +// *

+// * Clients are also able to acquire the {@link IContentTypeManager} service. +// *

+// * @return the content type manager +// * @since 3.0 +// */ +// public static IContentTypeManager getContentTypeManager() { +// return InternalPlatform.getDefault().getContentTypeManager(); +// } + + /** + * Returns the identified option. null + * is returned if no such option is found. Options are specified + * in the general form <plug-in id>/<option-path>. + * For example, dwtx.core.runtime/debug + *

+ * Clients are also able to acquire the {@link DebugOptions} service + * and query it for debug options. + *

+ * @param option the name of the option to lookup + * @return the value of the requested debug option or null + */ + public static String getDebugOption(String option) { + return null; +// DWT FIXME: impl +// return InternalPlatform.getDefault().getOption(option); + } + +// /** +// * Returns the location of the platform working directory. +// *

+// * Callers of this method should consider using getInstanceLocation +// * instead. In various, typically non IDE-related configurations of Eclipse, the platform +// * working directory may not be on the local file system. As such, the more general +// * form of this location is as a URL. +// *

+// * Alternatively, instead of calling getInstanceLocation clients are +// * able to acquire the {@link Location} service (with the type {@link Location#INSTANCE_FILTER}) +// * and then change the resulting URL to a path. See the javadoc for getInstanceLocation +// * for more details. +// *

+// * @return the location of the platform +// * @see #getInstanceLocation() +// */ +// public static IPath getLocation() throws IllegalStateException { +// return InternalPlatform.getDefault().getLocation(); +// } + + /** + * Returns the location of the platform log file. This file may contain information + * about errors that have previously occurred during this invocation of the Platform. + *

+ * It is recommended not to keep this value, as the log location may vary when an instance + * location is being set.

+ *

+ * Note: it is very important that users of this method do not leave the log + * file open for extended periods of time. Doing so may prevent others + * from writing to the log file, which could result in important error messages + * being lost. It is strongly recommended that clients wanting to read the + * log file for extended periods should copy the log file contents elsewhere, + * and immediately close the original file.

+ * @return the path of the log file on disk. + * + * XXX consider making an ILogger interface that listeners can implements and it allows + * us to implement Platform.getLogLocation() + */ + public static IPath getLogFileLocation() { + implMissing(__FILE__,__LINE__); + return null; + //return InternalPlatform.getDefault().getMetaArea().getLogLocation(); + } + +// /** +// * Returns the plug-in runtime object for the identified plug-in +// * or null if no such plug-in can be found. If +// * the plug-in is defined but not yet activated, the plug-in will +// * be activated before being returned. +// *

+// * Note: This method is only able to find and return plug-in +// * objects for plug-ins described using plugin.xml according to the +// * traditional Eclipse conventions. Eclipse 3.0 permits plug-ins to be +// * described in manifest.mf files and to define their own bundle +// * activators. Such plug-ins cannot be discovered by this method.

+// * +// * @param id the unique identifier of the desired plug-in +// * (e.g., "com.example.acme"). +// * @return the plug-in runtime object, or null +// * @deprecated +// * This method only works if the compatibility layer is installed and must not be used otherwise. +// * See the comments on {@link IPluginDescriptor#getPlugin()} for details. +// */ +// public static Plugin getPlugin(String id) { +// try { +// IPluginRegistry registry = getPluginRegistry(); +// if (registry is null) +// throw new IllegalStateException(); +// IPluginDescriptor pd = registry.getPluginDescriptor(id); +// if (pd is null) +// return null; +// return pd.getPlugin(); +// } catch (CoreException e) { +// // TODO log the exception +// } +// return null; +// } +// +// /** +// * Returns the plug-in registry for this platform. +// * +// * @return the plug-in registry +// * @see IPluginRegistry +// * @deprecated IPluginRegistry was refactored in Eclipse 3.0. +// * This method only works if the compatibility layer is installed and must not be used otherwise. +// * See the comments on {@link IPluginRegistry} and its methods for details. +// */ +// public static IPluginRegistry getPluginRegistry() { +// Bundle compatibility = InternalPlatform.getDefault().getBundle(CompatibilityHelper.PI_RUNTIME_COMPATIBILITY); +// if (compatibility is null) +// throw new IllegalStateException(); +// +// Class oldInternalPlatform = null; +// try { +// oldInternalPlatform = compatibility.loadClass("dwtx.core.internal.plugins.InternalPlatform"); //$NON-NLS-1$ +// Method getPluginRegistry = oldInternalPlatform.getMethod("getPluginRegistry", null); //$NON-NLS-1$ +// return (IPluginRegistry) getPluginRegistry.invoke(oldInternalPlatform, null); +// } catch (Exception e) { +// //Ignore the exceptions, return null +// } +// return null; +// +// } +// +// /** +// * Returns the location in the local file system of the plug-in +// * state area for the given plug-in. +// * The platform must be running. +// *

+// * The plug-in state area is a file directory within the +// * platform's metadata area where a plug-in is free to create files. +// * The content and structure of this area is defined by the plug-in, +// * and the particular plug-in is solely responsible for any files +// * it puts there. It is recommended for plug-in preference settings. +// *

+// * +// * @param plugin the plug-in whose state location is returned +// * @return a local file system path +// * @deprecated clients should call getStateLocation instead +// */ +// public static IPath getPluginStateLocation(Plugin plugin) { +// return plugin.getStateLocation(); +// } +// +// /** +// * Returns the protection space (realm) for the specified resource, or +// * null if the realm is unknown. +// * +// * @param resourceUrl the URL of the resource whose protection space is +// * returned. For example, "http://www.example.com/folder/". +// * @return the protection space (realm) for the specified resource, or +// * null if the realm is unknown +// * @deprecated Authorization database is superseded by the Equinox secure storage. +// * Use dwtx.equinox.security.storage.SecurePreferencesFactory +// * to obtain secure preferences and dwtx.equinox.security.storage.ISecurePreferences +// * for data access and modifications. +// */ +// public static String getProtectionSpace(URL resourceUrl) { +// try { +// return AuthorizationHandler.getProtectionSpace(resourceUrl); +// } catch (NoClassDefFoundError e) { +// // The authorization code is not available so just log and continue +// logAuthNotAvailable(e); +// } +// return null; +// } +// +// /** +// * Removes the indicated (identical) log listener from the notification list +// * of the platform. If no such listener exists, no action is taken. +// * +// * @param listener the listener to de-register +// * @see ILog#removeLogListener(ILogListener) +// * @see #addLogListener(ILogListener) +// * XXX Use the LogMgr service. +// */ +// public static void removeLogListener(ILogListener listener) { +// InternalPlatform.getDefault().removeLogListener(listener); +// } +// +// /** +// * Returns a URL which is the resolved equivalent of the +// * supplied URL. This method is expected to be used with the +// * plug-in-relative URLs returned by IPluginDescriptor, Bundle.getEntry() +// * and Platform.find(). +// *

+// * If the specified URL is not a plug-in-relative URL, it is returned +// * as is. If the specified URL is a plug-in-relative URL, this method +// * attempts to reduce the given URL to one which is native to the Java +// * class library (eg. file, http, etc). +// *

+// * Note however that users of this API should not assume too much about the +// * results of this method. While it may consistently return a file: URL in certain +// * installation configurations, others may result in jar: or http: URLs. +// *

+// * @param url original plug-in-relative URL. +// * @return the resolved URL +// * @exception IOException if unable to resolve URL +// * @see #asLocalURL(URL) +// * @see #find(Bundle, IPath) +// * @see Bundle#getEntry(String) +// * @deprecated use {@link FileLocator#resolve(URL)} instead +// */ +// public static URL resolve(URL url) throws IOException { +// return FileLocator.resolve(url); +// } +// +// /** +// * Runs the given runnable in a protected mode. Exceptions +// * thrown in the runnable are logged and passed to the runnable's +// * exception handler. Such exceptions are not rethrown by this method. +// * +// * @param runnable the runnable to run +// * @deprecated clients should use SafeRunner#run instead +// */ +// public static void run(ISafeRunnable runnable) { +// SafeRunner.run(runnable); +// } +// +// /** +// * Returns the platform job manager. +// * +// * @return the platform's job manager +// * @since 3.0 +// * @deprecated The method {@link Job#getJobManager()} should be used instead. +// */ +// public static IJobManager getJobManager() { +// return Job.getJobManager(); +// } +// +// /** +// * Returns the extension registry for this platform. +// * +// * @return the extension registry +// * @see IExtensionRegistry +// * @since 3.0 +// */ +// public static IExtensionRegistry getExtensionRegistry() { +// return InternalPlatform.getDefault().getRegistry(); +// } +// +// /** +// * Returns a URL for the given path in the given bundle. Returns null if the URL +// * could not be computed or created. +// * +// * @param bundle the bundle in which to search +// * @param path path relative to plug-in installation location +// * @return a URL for the given path or null. The actual form +// * of the returned URL is not specified. +// * @see #find(Bundle, IPath, Map) +// * @see #resolve(URL) +// * @see #asLocalURL(URL) +// * @since 3.0 +// * @deprecated use {@link FileLocator#find(Bundle, IPath, Map)} +// */ +// public static URL find(Bundle bundle, IPath path) { +// return FileLocator.find(bundle, path, null); +// } +// +// /** +// * Returns a URL for the given path in the given bundle. Returns null if the URL +// * could not be computed or created. +// *

+// * find looks for this path in given bundle and any attached fragments. +// * null is returned if no such entry is found. Note that +// * there is no specific order to the fragments. +// *

+// * The following arguments may also be used +// *

+//      *     $nl$ - for language specific information
+//      *     $os$ - for operating system specific information
+//      *     $ws$ - for windowing system specific information
+//      * 
+// *

+// * A path of $nl$/about.properties in an environment with a default +// * locale of en_CA will return a URL corresponding to the first place +// * about.properties is found according to the following order: +// *

+//      *     plugin root/nl/en/CA/about.properties
+//      *     fragment1 root/nl/en/CA/about.properties
+//      *     fragment2 root/nl/en/CA/about.properties
+//      *     ...
+//      *     plugin root/nl/en/about.properties
+//      *     fragment1 root/nl/en/about.properties
+//      *     fragment2 root/nl/en/about.properties
+//      *     ...
+//      *     plugin root/about.properties
+//      *     fragment1 root/about.properties
+//      *     fragment2 root/about.properties
+//      *     ...
+//      * 
+// *

+// * The current environment variable values can be overridden using +// * the override map argument. +// *

+// * +// * @param bundle the bundle in which to search +// * @param path file path relative to plug-in installation location +// * @param override map of override substitution arguments to be used for +// * any $arg$ path elements. The map keys correspond to the substitution +// * arguments (eg. "$nl$" or "$os$"). The resulting +// * values must be of type java.lang.String. If the map is null, +// * or does not contain the required substitution argument, the default +// * is used. +// * @return a URL for the given path or null. The actual form +// * of the returned URL is not specified. +// * @see #resolve(URL) +// * @see #asLocalURL(URL) +// * @since 3.0 +// * @deprecated use {@link FileLocator#find(Bundle, IPath, Map)} instead +// */ +// public static URL find(Bundle bundle, IPath path, Map override) { +// return FileLocator.find(bundle, path, override); +// } +// +// /** +// * Returns the location in the local file system of the +// * plug-in state area for the given bundle. +// * If the plug-in state area did not exist prior to this call, +// * it is created. +// *

+// * The plug-in state area is a file directory within the +// * platform's metadata area where a plug-in is free to create files. +// * The content and structure of this area is defined by the plug-in, +// * and the particular plug-in is solely responsible for any files +// * it puts there. It is recommended for plug-in preference settings and +// * other configuration parameters. +// *

+// * +// * @param bundle the bundle whose state location if returned +// * @return a local file system path +// * @since 3.0 +// * XXX Investigate the usage of a service factory +// */ +// public static IPath getStateLocation(Bundle bundle) { +// return InternalPlatform.getDefault().getStateLocation(bundle); +// } +// +// /** +// * Returns a number that changes whenever the set of installed plug-ins +// * changes. This can be used for invalidating caches that are based on +// * the set of currently installed plug-ins. (e.g. extensions) +// *

+// * Clients are also able to acquire the {@link PlatformAdmin} service +// * and get the timestamp from its state object. +// *

+// * @return a number related to the set of installed plug-ins +// * @since 3.1 +// */ +// public static long getStateStamp() { +// return InternalPlatform.getDefault().getStateTimeStamp(); +// } + + /** + * Returns the log for the given bundle. If no such log exists, one is created. + * + * @param bundle the bundle whose log is returned + * @return the log for the given bundle + * @since 3.0 + * XXX change this into a LogMgr service that would keep track of the map. See if it can be a service factory. + * It would contain all the methods that are here. + * Relate to RuntimeLog if appropriate. + * The system log listener needs to be optional: turned on or off. What about a system property? :-) + */ + public static ILog getLog(Bundle bundle) { + implMissing(__FILE__,__LINE__); + return null; + //return InternalPlatform.getDefault().getLog(bundle); + } + +// /** +// * Returns the given bundle's resource bundle for the current locale. +// *

+// * This resource bundle is typically stored as the plugin.properties file +// * in the plug-in itself, and contains any translatable strings used in the +// * plug-in manifest file (plugin.xml). +// *

+// *

+// * This mechanism is intended only for +// * externalizing strings found in the plug-in manifest file. Using this +// * method for externalizing strings in your code may result in degraded +// * memory performance. +// *

+// * +// * @param bundle the bundle whose resource bundle is being queried +// * @return the resource bundle +// * @exception MissingResourceException if the resource bundle was not found +// * @since 3.0 +// * XXX this is deprecated. use NLS or BundleFinder.find() +// */ +// public static ResourceBundle getResourceBundle(Bundle bundle) throws MissingResourceException { +// return InternalPlatform.getDefault().getResourceBundle(bundle); +// } +// +// /** +// * Returns a resource string corresponding to the given argument value. +// * If the argument value specifies a resource key, the string +// * is looked up in the default resource bundle for the given runtime bundle. If the argument does not +// * specify a valid key, the argument itself is returned as the +// * resource string. The key lookup is performed in the +// * file referenced in the Bundle-Localization header of the bundle manifest. If a resource string +// * corresponding to the key is not found in the resource bundle +// * the key value, or any default text following the key in the +// * argument value is returned as the resource string. +// * A key is identified as a string beginning with the "%" character. +// * Note, that the "%" character is stripped off prior to lookup +// * in the resource bundle. +// *

+// * Equivalent to getResourceString(bundle, value, getResourceBundle()) +// *

+// * +// * @param bundle the bundle whose resource bundle is being queried +// * @param value the value to look for +// * @return the resource string +// * @see #getResourceBundle(Bundle) +// * @since 3.0 +// * XXX this is deprecated. use NLS or BundleFinder.find() +// */ +// public static String getResourceString(Bundle bundle, String value) { +// return InternalPlatform.getDefault().getResourceString(bundle, value); +// } +// +// /** +// * Returns a resource string corresponding to the given argument +// * value and resource bundle in the given runtime bundle. +// * If the argument value specifies a resource key, the string +// * is looked up in the given resource bundle. If the argument does not +// * specify a valid key, the argument itself is returned as the +// * resource string. The key lookup is performed against the +// * specified resource bundle. If a resource string +// * corresponding to the key is not found in the resource bundle +// * the key value, or any default text following the key in the +// * argument value is returned as the resource string. +// * A key is identified as a string beginning with the "%" character. +// * Note that the "%" character is stripped off prior to lookup +// * in the resource bundle. +// *

+// * For example, assume resource bundle plugin.properties contains +// * name = Project Name +// *

+//      *     getResourceString("Hello World") returns "Hello World"
+//      *     getResourceString("%name") returns "Project Name"
+//      *     getResourceString("%name Hello World") returns "Project Name"
+//      *     getResourceString("%abcd Hello World") returns "Hello World"
+//      *     getResourceString("%abcd") returns "%abcd"
+//      *     getResourceString("%%name") returns "%name"
+//      * 
+// *

+// * +// * @param bundle the bundle whose resource bundle is being queried +// * @param value the value +// * @param resourceBundle the resource bundle to query +// * @return the resource string +// * @see #getResourceBundle(Bundle) +// * @since 3.0 +// * XXX this is deprecated. use NLS or BundleFinder.find() +// */ +// public static String getResourceString(Bundle bundle, String value, ResourceBundle resourceBundle) { +// return InternalPlatform.getDefault().getResourceString(bundle, value, resourceBundle); +// } +// +// /** +// * Returns the string name of the current system architecture. +// * The value is a user-defined string if the architecture is +// * specified on the command line, otherwise it is the value +// * returned by java.lang.System.getProperty("os.arch"). +// *

+// * Clients are also able to acquire the {@link EnvironmentInfo} service and query it for +// * the operating-system architecture. +// *

+// * @return the string name of the current system architecture +// * @since 3.0 +// */ +// public static String getOSArch() { +// return InternalPlatform.getDefault().getOSArch(); +// } +// +// /** +// * Returns the string name of the current locale for use in finding files +// * whose path starts with $nl$. +// *

+// * Clients are also able to acquire the {@link EnvironmentInfo} service and query it for +// * the NL. +// *

+// * @return the string name of the current locale +// * @since 3.0 +// */ +// public static String getNL() { +// return InternalPlatform.getDefault().getNL(); +// } +// +// /** +// * Returns the string name of the current operating system for use in finding +// * files whose path starts with $os$. OS_UNKNOWN is +// * returned if the operating system cannot be determined. +// * The value may indicate one of the operating systems known to the platform +// * (as specified in knownOSValues) or a user-defined string if +// * the operating system name is specified on the command line. +// *

+// * Clients are also able to acquire the {@link EnvironmentInfo} service and query it for +// * the operating-system. +// *

+// * @return the string name of the current operating system +// * @since 3.0 +// */ +// public static String getOS() { +// return InternalPlatform.getDefault().getOS(); +// } +// +// /** +// * Returns the string name of the current window system for use in finding files +// * whose path starts with $ws$. null is returned +// * if the window system cannot be determined. +// *

+// * Clients are also able to acquire the {@link EnvironmentInfo} service and query it for +// * the windowing system. +// *

+// * @return the string name of the current window system or null +// * @since 3.0 +// */ +// public static String getWS() { +// return InternalPlatform.getDefault().getWS(); +// } +// +// /** +// * Returns the arguments not consumed by the framework implementation itself. Which +// * arguments are consumed is implementation specific. These arguments are available +// * for use by the application. +// * +// * @return the array of command line arguments not consumed by the framework. +// * @since 3.0 +// * XXX Use the Environment info service. Need to see how to set the value of the app args. +// */ +// public static String[] getApplicationArgs() { +// return InternalPlatform.getDefault().getApplicationArgs(); +// } +// +// /** +// * Returns the platform administrator for this running Eclipse. +// *

+// * Note: This is an internal method and must not +// * be used by clients which are not part of the Eclipse Platform. +// * This method allows access to classes which are not Eclipse +// * Platform API but are part of the OSGi runtime that the Eclipse +// * Platform is built on. Even as the Eclipse Platform evolves +// * in compatible ways from release to release, the details of +// * the OSGi implementation might not. +// *

+// * Clients can also acquire the {@link PlatformAdmin} service +// * to retrieve this object. +// *

+// * @return the platform admin for this instance of Eclipse +// * @since 3.0 +// */ +// public static PlatformAdmin getPlatformAdmin() { +// return InternalPlatform.getDefault().getPlatformAdmin(); +// } +// +// /** +// * Returns the location of the platform's working directory (also known as the instance data area). +// * null is returned if the platform is running without an instance location. +// *

+// * This method is equivalent to acquiring the dwtx.osgi.service.datalocation.Location +// * service with the property "type" equal to {@link Location#INSTANCE_FILTER}. +// *

+// * @return the location of the platform's instance data area or null if none +// * @since 3.0 +// * @see Location#INSTANCE_FILTER +// */ +// public static Location getInstanceLocation() { +// return InternalPlatform.getDefault().getInstanceLocation(); +// } +// +// /** +// * Returns the currently registered bundle group providers. +// *

+// * Clients are also able to acquire the {@link IBundleGroupProvider} service and query it for +// * the registered bundle group providers. +// *

+// * @return the currently registered bundle group providers +// * @since 3.0 +// */ +// public static IBundleGroupProvider[] getBundleGroupProviders() { +// return InternalPlatform.getDefault().getBundleGroupProviders(); +// } +// +// /** +// * Return the interface into the preference mechanism. The returned +// * object can be used for such operations as searching for preference +// * values across multiple scopes and preference import/export. +// *

+// * Clients are also able to acquire the {@link IPreferencesService} service via +// * OSGi mechanisms and use it for preference functions. +// *

+// * @return an object to interface into the preference mechanism +// * @since 3.0 +// */ +// public static IPreferencesService getPreferencesService() { +// return InternalPlatform.getDefault().getPreferencesService(); +// } +// +// /** +// * Returns the product which was selected when running this Eclipse instance +// * or null if none +// * @return the current product or null if none +// * @since 3.0 +// * XXX move this into the app model. +// */ +// public static IProduct getProduct() { +// return InternalPlatform.getDefault().getProduct(); +// } +// +// /** +// * Registers the given bundle group provider with the platform. +// *

+// * Clients are also able to use the {@link IBundleGroupProvider} service to +// * register themselves as a bundle group provider. +// *

+// * @param provider a provider to register +// * @since 3.0 +// */ +// public static void registerBundleGroupProvider(IBundleGroupProvider provider) { +// InternalPlatform.getDefault().registerBundleGroupProvider(provider); +// } +// +// /** +// * De-registers the given bundle group provider with the platform. +// *

+// * Clients are also able to use the {@link IBundleGroupProvider} service mechanism +// * for unregistering themselves. +// *

+// * @param provider a provider to de-register +// * @since 3.0 +// * @see #registerBundleGroupProvider(IBundleGroupProvider) +// */ +// public static void unregisterBundleGroupProvider(IBundleGroupProvider provider) { +// InternalPlatform.getDefault().unregisterBundleGroupProvider(provider); +// } +// +// /** +// * Returns the location of the configuration information +// * used to run this instance of Eclipse. The configuration area typically +// * contains the list of plug-ins available for use, various settings +// * (those shared across different instances of the same configuration) +// * and any other such data needed by plug-ins. +// * null is returned if the platform is running without a configuration location. +// *

+// * This method is equivalent to acquiring the dwtx.osgi.service.datalocation.Location +// * service with the property "type" equal to {@link Location#CONFIGURATION_FILTER}. +// *

+// * @return the location of the platform's configuration data area or null if none +// * @since 3.0 +// * @see Location#CONFIGURATION_FILTER +// */ +// public static Location getConfigurationLocation() { +// return InternalPlatform.getDefault().getConfigurationLocation(); +// } +// +// /** +// * Returns the location of the platform's user data area. The user data area is a location on the system +// * which is specific to the system's current user. By default it is located relative to the +// * location given by the System property "user.home". +// * null is returned if the platform is running without an user location. +// *

+// * This method is equivalent to acquiring the dwtx.osgi.service.datalocation.Location +// * service with the property "type" equal to {@link Location#USER_FILTER}. +// *

+// * @return the location of the platform's user data area or null if none +// * @since 3.0 +// * @see Location#USER_FILTER +// */ +// public static Location getUserLocation() { +// return InternalPlatform.getDefault().getUserLocation(); +// } +// +// /** +// * Returns the location of the base installation for the running platform +// * null is returned if the platform is running without a configuration location. +// *

+// * This method is equivalent to acquiring the dwtx.osgi.service.datalocation.Location +// * service with the property "type" equal to {@link Location#INSTALL_FILTER}. +// *

+// * @return the location of the platform's installation area or null if none +// * @since 3.0 +// * @see Location#INSTALL_FILTER +// */ +// public static Location getInstallLocation() { +// return InternalPlatform.getDefault().getInstallLocation(); +// } +// +// /** +// * Checks if the specified bundle is a fragment bundle. +// *

+// * Clients are also able to acquire the {@link PackageAdmin} service +// * to query if the given bundle is a fragment by asking for the bundle type +// * and checking against constants on the service interface. +// *

+// * @param bundle the bundle to query +// * @return true if the specified bundle is a fragment bundle; otherwise false is returned. +// * @since 3.0 +// */ +// public static bool isFragment(Bundle bundle) { +// return InternalPlatform.getDefault().isFragment(bundle); +// } +// +// /** +// * Returns an array of attached fragment bundles for the specified bundle. If the +// * specified bundle is a fragment then null is returned. If no fragments are +// * attached to the specified bundle then null is returned. +// *

+// * Clients are also able to acquire the {@link PackageAdmin} service and query +// * it for the fragments of the given bundle. +// *

+// * @param bundle the bundle to get the attached fragment bundles for. +// * @return an array of fragment bundles or null if the bundle does not +// * have any attached fragment bundles. +// * @since 3.0 +// */ +// public static Bundle[] getFragments(Bundle bundle) { +// return InternalPlatform.getDefault().getFragments(bundle); +// } +// + /** + * Returns the resolved bundle with the specified symbolic name that has the + * highest version. If no resolved bundles are installed that have the + * specified symbolic name then null is returned. + *

+ * Clients are also able to acquire the {@link PackageAdmin} service and query + * it for the bundle with the specified symbolic name. Clients can ask the + * service for all bundles with that particular name and then determine the + * one with the highest version. Note that clients may want to filter + * the results based on the state of the bundles. + *

+ * @param symbolicName the symbolic name of the bundle to be returned. + * @return the bundle that has the specified symbolic name with the + * highest version, or null if no bundle is found. + * @since 3.0 + */ + public static Bundle getBundle(String symbolicName) { + implMissing(__FILE__, __LINE__ ); + return null; + //return InternalPlatform.getDefault().getBundle(symbolicName); + } + +// /** +// * Returns all bundles with the specified symbolic name. If no resolved bundles +// * with the specified symbolic name can be found, null is returned. +// * If the version argument is not null then only the Bundles that have +// * the specified symbolic name and a version greater than or equal to the +// * specified version are returned. The returned bundles are ordered in +// * descending bundle version order. +// *

+// * Clients are also able to acquire the {@link PackageAdmin} service and query +// * it for all bundle versions with the given symbolic name, after turning the +// * specific version into a version range. Note that clients may want to filter +// * the results based on the state of the bundles. +// *

+// * @param symbolicName the symbolic name of the bundles that are to be returned. +// * @param version the version that the return bundle versions must match, +// * or null if no version matching is to be done. +// * @return the array of Bundles with the specified name that match the +// * specified version and match rule, or null if no bundles are found. +// */ +// public static Bundle[] getBundles(String symbolicName, String version) { +// return InternalPlatform.getDefault().getBundles(symbolicName, version); +// } +// +// /** +// * Returns an array of host bundles that the specified fragment bundle is +// * attached to or null if the specified bundle is not attached to a host. +// * If the bundle is not a fragment bundle then null is returned. +// *

+// * Clients are also able to acquire the {@link PackageAdmin} service and query +// * it for the hosts for the given bundle. +// *

+// * @param bundle the bundle to get the host bundles for. +// * @return an array of host bundles or null if the bundle does not have any +// * host bundles. +// * @since 3.0 +// */ +// public static Bundle[] getHosts(Bundle bundle) { +// return InternalPlatform.getDefault().getHosts(bundle); +// } +// +// /** +// * Returns whether the platform is running. +// * +// * @return true if the platform is running, +// * and false otherwise +// *@since 3.0 +// *XXX do what you want to do. track osgi, track runtime, or whatever. +// */ +// public static bool isRunning() { +// return InternalPlatform.getDefault().isRunning(); +// } +// +// /** +// * Returns a list of known system architectures. +// *

+// * Note that this list is not authoritative; there may be legal values +// * not included in this list. Indeed, the value returned by +// * getOSArch may not be in this list. Also, this list may +// * change over time as Eclipse comes to run on more operating environments. +// *

+// * +// * @return the list of system architectures known to the system +// * @see #getOSArch() +// * @since 3.0 +// * XXX This is useless +// */ +// public static String[] knownOSArchValues() { +// return InternalPlatform.getDefault().knownOSArchValues(); +// } +// +// /** +// * Returns a list of known operating system names. +// *

+// * Note that this list is not authoritative; there may be legal values +// * not included in this list. Indeed, the value returned by +// * getOS may not be in this list. Also, this list may +// * change over time as Eclipse comes to run on more operating environments. +// *

+// * +// * @return the list of operating systems known to the system +// * @see #getOS() +// * @since 3.0 +// * XXX This is useless +// */ +// public static String[] knownOSValues() { +// return InternalPlatform.getDefault().knownOSValues(); +// } +// +// /** +// * Returns a map of known platform line separators. The keys are +// * translated names of platforms and the values are their associated +// * line separator strings. +// * +// * @return a map of platform to their line separator string +// * @since 3.1 +// */ +// public static Map knownPlatformLineSeparators() { +// Map result = new HashMap(); +// result.put(LINE_SEPARATOR_KEY_MAC_OS_9, LINE_SEPARATOR_VALUE_CR); +// result.put(LINE_SEPARATOR_KEY_UNIX, LINE_SEPARATOR_VALUE_LF); +// result.put(LINE_SEPARATOR_KEY_WINDOWS, LINE_SEPARATOR_VALUE_CRLF); +// return result; +// } +// +// /** +// * Returns a list of known windowing system names. +// *

+// * Note that this list is not authoritative; there may be legal values +// * not included in this list. Indeed, the value returned by +// * getWS may not be in this list. Also, this list may +// * change over time as Eclipse comes to run on more operating environments. +// *

+// * +// * @return the list of window systems known to the system +// * @see #getWS() +// * @since 3.0 +// * XXX This is useless +// */ +// public static String[] knownWSValues() { +// return InternalPlatform.getDefault().knownWSValues(); +// } +// +// /** +// * Returns true if the platform is currently running in +// * debug mode. The platform is typically put in debug mode using the +// * "-debug" command line argument. +// *

+// * Clients are also able to acquire the {@link EnvironmentInfo} service and query it +// * to see if they are in debug mode. +// *

+// * @return whether or not the platform is running in debug mode +// * @since 3.0 +// */ +// public static bool inDebugMode() { +// return PlatformActivator.getContext().getProperty("osgi.debug") !is null; //$NON-NLS-1$ +// } +// +// /** +// * Returns true if the platform is currently running in +// * development mode. That is, if special procedures are to be +// * taken when defining plug-in class paths. The platform is typically put in +// * development mode using the "-dev" command line argument. +// *

+// * Clients are also able to acquire the {@link EnvironmentInfo} service and query it +// * to see if they are in development mode. +// *

+// * @return whether or not the platform is running in development mode +// * @since 3.0 +// */ +// public static bool inDevelopmentMode() { +// return PlatformActivator.getContext().getProperty("osgi.dev") !is null; //$NON-NLS-1$ +// } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/core/runtime/jobs/package.html --- a/dwtx/core/runtime/jobs/package.html Mon Sep 08 01:37:00 2008 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ - - - - - Package-level Javadoc - - -Provides core support for scheduling and interacting with background activity. -

-Package Specification

-

-This package specifies API for scheduling background tasks, or jobs. Jobs can be -scheduled for immediate execution, or for execution after a specified delay. Once -scheduled, jobs can be queried, canceled, or suspended. Rules can be attached to -jobs to indicate when they can run, and whether they can run simultaneously with other -jobs. This package also includes a generic locking facility that includes support for -detecting and responding to deadlock. -

-@since 3.0 -

- - diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/dwtxhelper/BufferedReader.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/dwtxhelper/BufferedReader.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,23 @@ +module dwtx.dwtxhelper.BufferedReader; + +import dwt.dwthelper.utils; + +class BufferedReader : Reader { + this(Reader reader){ + implMissing(__FILE__,__LINE__); + } + public override int read(char[] cbuf, int off, int len){ + implMissing(__FILE__,__LINE__); + return 0; + } + public override void close(){ + implMissing(__FILE__,__LINE__); + } + public String readLine() { + implMissing(__FILE__,__LINE__); + return null; + } +} + + + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/dwtxhelper/CharacterIterator.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/dwtxhelper/CharacterIterator.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,17 @@ +module dwtx.dwtxhelper.CharacterIterator; + +interface CharacterIterator { + static const char DONE = '\u00FF'; + Object clone(); + char current(); + char first(); + int getBeginIndex(); + int getEndIndex(); + int getIndex(); + char last(); + char next(); + char previous(); + char setIndex(int position); +} + + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/dwtxhelper/Collection.d --- a/dwtx/dwtxhelper/Collection.d Mon Sep 08 01:37:00 2008 +0200 +++ b/dwtx/dwtxhelper/Collection.d Mon Sep 08 01:38:10 2008 +0200 @@ -119,6 +119,7 @@ public bool addAll(int index, Collection c); public void clear(); public bool contains(Object o); + public bool contains(String o); public bool containsAll(Collection c); public int opEquals(Object o); public Object get(int index); @@ -362,6 +363,137 @@ } +class IdentityHashMap : Map { + alias tango.util.container.HashMap.HashMap!(Object,Object) MapType; + private MapType map; + + public this(){ + implMissing(__FILE__, __LINE__ ); + map = new MapType(); + } + public this(int initialCapacity){ + implMissing(__FILE__, __LINE__ ); + this(); + } + public this(int initialCapacity, float loadFactor){ + implMissing(__FILE__, __LINE__ ); + map = new MapType(loadFactor); + } + public this(Map m){ + implMissing(__FILE__, __LINE__ ); + this(); + putAll(m); + } + public void clear(){ + map.clear(); + } + public bool containsKey(Object key){ + Object v; + return map.get(key, v ); + } + public bool containsKey(String key){ + return containsKey(stringcast(key)); + } + public bool containsValue(Object value){ + return map.contains(value); + } + public Set entrySet(){ + HashSet res = new HashSet(); + foreach( k, v; map ){ + res.add( new MapEntry(this,k)); + } + return res; + } + public override int opEquals(Object o){ + if( auto other = cast(HashMap) o ){ + if( other.size() !is size() ){ + return false; + } + foreach( k, v; map ){ + Object vo = other.get(k); + if( v != vo ){ + return false; + } + } + return true; + } + return false; + } + public Object get(Object key){ + if( auto v = key in map ){ + return *v; + } + return null; + } + public Object get(String key){ + return get(stringcast(key)); + } + public override hash_t toHash(){ + return super.toHash(); + } + public bool isEmpty(){ + return map.isEmpty(); + } + public Set keySet(){ + HashSet res = new HashSet(); + foreach( k, v; map ){ + res.add(k); + } + return res; + } + public Object put(Object key, Object value){ + Object res = null; + if( auto vold = key in map ){ + res = *vold; + } + map[ key ] = value; + return res; + } + public Object put(String key, Object value){ + return put( stringcast(key), value ); + } + public Object put(Object key, String value){ + return put( key, stringcast(value) ); + } + public Object put(String key, String value){ + return put( stringcast(key), stringcast(value) ); + } + public void putAll(Map t){ + foreach( k, v; t ){ + map[k] = v; + } + } + public Object remove(Object key){ + if( auto v = key in map ){ + Object res = *v; + map.remove(key); + return res; + } + map.remove(key); + return null; + } + public Object remove(String key){ + return remove(stringcast(key)); + } + public int size(){ + return map.size(); + } + public Collection values(){ + ArrayList res = new ArrayList( size() ); + foreach( k, v; map ){ + res.add( v ); + } + return res; + } + + public int opApply (int delegate(ref Object value) dg){ + return map.opApply( dg ); + } + public int opApply (int delegate(ref Object key, ref Object value) dg){ + return map.opApply( dg ); + } +} + class Dictionary { public this(){ } @@ -984,6 +1116,9 @@ public abstract bool addAll(int index, Collection c); public abstract void clear(); public abstract bool contains(Object o); + public bool contains(String str){ + return contains(stringcast(str)); + } public abstract bool containsAll(Collection c); public abstract int opEquals(Object o); public abstract Object get(int index); @@ -1200,6 +1335,9 @@ implMissing( __FILE__, __LINE__ ); return false; } + public bool contains(String str){ + return contains(stringcast(str)); + } public bool containsAll(Collection c){ implMissing( __FILE__, __LINE__ ); return false; @@ -1610,6 +1748,9 @@ bool contains(Object elem){ return list.contains(elem); } + bool contains(String elem){ + return contains(stringcast(elem)); + } bool containsAll(Collection c){ foreach(o; c){ if( !list.contains(o)) return false; @@ -1640,6 +1781,12 @@ Object get(int index){ return list.get(index); } + Object getFirst(){ + return list.get(0); + } + Object getLast(){ + return list.get(list.size()-1); + } hash_t toHash(){ implMissing( __FILE__, __LINE__ ); return 0; @@ -1818,6 +1965,9 @@ } return false; } + bool contains(String o){ + return contains(stringcast(o)); + } bool containsAll(Collection c){ implMissing( __FILE__, __LINE__ ); return false; @@ -1969,7 +2119,7 @@ } class Arrays { - public static bool equals(Object[] a, Object[] b){ + public static bool equals(T)(T[] a, T[] b){ if( a.length !is b.length ){ return false; } @@ -1984,6 +2134,34 @@ } return true; } +/+ public static bool equals(Object[] a, Object[] b){ + if( a.length !is b.length ){ + return false; + } + for( int i = 0; i < a.length; i++ ){ + if( a[i] is null && b[i] is null ){ + continue; + } + if( a[i] !is null && b[i] !is null && a[i] == b[i] ){ + continue; + } + return false; + } + return true; + } ++/ + static void sort( T )( T[] a, Comparator c ){ + bool isLess( T o1, T o2 ){ + return c.compare( cast(Object)o1, cast(Object)o2 ) < 0; + } + tango.core.Array.sort( a, &isLess ); + } + static void sort( T : char[] )( T[] a, Comparator c ){ + bool isLess( T o1, T o2 ){ + return c.compare( stringcast(o1), stringcast(o2) ) < 0; + } + tango.core.Array.sort( a, &isLess ); + } static List asList(Object[] a) { if( a.length is 0 ) return Collections.EMPTY_LIST; ArrayList res = new ArrayList( a.length ); @@ -1992,6 +2170,9 @@ } return res; } + public static void fill( String str, char c ){ + str[] = c; + } } class Collections { @@ -2029,7 +2210,14 @@ } return EMPTY_SET_; } - + static int binarySearch(List list, Object key){ + implMissing( __FILE__, __LINE__ ); + return 0; + } + static int binarySearch(List list, Object key, Comparator c){ + implMissing( __FILE__, __LINE__ ); + return 0; + } public static List unmodifiableList( List list ){ implMissing( __FILE__, __LINE__ ); return null; @@ -2090,4 +2278,8 @@ } } - +class LinkedHashMap : HashMap { + static this(){ + implMissing( __FILE__, __LINE__ ); + } +} \ No newline at end of file diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/dwtxhelper/Date.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/dwtxhelper/Date.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,12 @@ +module dwtx.dwtxhelper.Date; + +import dwt.dwthelper.utils; + +class Date { + long getTime(){ + implMissing(__FILE__,__LINE__); + return 0; + } +} + + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/dwtxhelper/MalformedURLException.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/dwtxhelper/MalformedURLException.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,4 @@ +module dwtx.dwtxhelper.MalformedURLException; + +class MalformedURLException { +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/dwtxhelper/MessageFormat.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/dwtxhelper/MessageFormat.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,20 @@ +module dwtx.dwtxhelper.MessageFormat; + +import dwt.dwthelper.utils; +import tango.text.convert.Format; + +class MessageFormat { + public static String format( String frmt, Object[] args... ){ + switch( args.length ){ + case 0: return Format(frmt); + case 1: return Format(frmt, args[0]); + case 2: return Format(frmt, args[0], args[1]); + case 3: return Format(frmt, args[0], args[1], args[2]); + case 4: return Format(frmt, args[0], args[1], args[2], args[3]); + case 5: return Format(frmt, args[0], args[1], args[2], args[3], args[4]); + default: + implMissing(__FILE__, __LINE__ ); + } + } +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/dwtxhelper/PushbackReader.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/dwtxhelper/PushbackReader.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,11 @@ +module dwtx.dwtxhelper.PushbackReader; + +import dwt.dwthelper.utils; + +class PushbackReader : Reader { + this( Reader reader ){ + } + void unread( char c ){ + } +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/dwtxhelper/StringReader.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/dwtxhelper/StringReader.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,19 @@ +module dwtx.dwtxhelper.StringReader; + +import dwt.dwthelper.utils; + +class StringReader : Reader { + String str; + this( String str ){ + implMissing(__FILE__,__LINE__); + this.str = str; + } + public override int read(char[] cbuf, int off, int len){ + cbuf[ off .. off+len ] = str[ 0 .. len ]; + str = str[ len .. $ ]; + return len; + } + public override void close(){ + } +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/dwtxhelper/StringTokenizer.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/dwtxhelper/StringTokenizer.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,48 @@ +module dwtx.dwtxhelper.StringTokenizer; + +import dwt.dwthelper.utils; + +class StringTokenizer { + + this(String){ + implMissing(__FILE__,__LINE__); + } + + this(String,String){ + implMissing(__FILE__,__LINE__); + } + + this(String,String,bool){ + implMissing(__FILE__,__LINE__); + } + + bool hasMoreTokens(){ + implMissing(__FILE__,__LINE__); + return false; + } + + String nextToken(){ + implMissing(__FILE__,__LINE__); + return null; + } + + String nextToken(String delim){ + implMissing(__FILE__,__LINE__); + return null; + } + + bool hasMoreElements(){ + implMissing(__FILE__,__LINE__); + return false; + } + + Object nextElement(){ + implMissing(__FILE__,__LINE__); + return null; + } + + int countTokens(){ + implMissing(__FILE__,__LINE__); + return 0; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/dwtxhelper/URL.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/dwtxhelper/URL.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,10 @@ +module dwtx.dwtxhelper.URL; + +import dwt.dwthelper.utils; + +class URL { + this(String){ + implMissing(__FILE__,__LINE__); + } +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/dwtxhelper/mangoicu/UBreakIterator.d --- a/dwtx/dwtxhelper/mangoicu/UBreakIterator.d Mon Sep 08 01:37:00 2008 +0200 +++ b/dwtx/dwtxhelper/mangoicu/UBreakIterator.d Mon Sep 08 01:38:10 2008 +0200 @@ -312,6 +312,7 @@ // this is returned by next(), previous() etc ... const uint Done = uint.max; + alias Done DONE; /*********************************************************************** @@ -454,7 +455,7 @@ return ubrk_next (handle); return ubrk_following (handle, offset); } - + alias next following; /*********************************************************************** Determine the text boundary preceding the current text diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/dwtxhelper/regex.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/dwtxhelper/regex.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,76 @@ +module dwtx.dwtxhelper.regex; + +import dwt.dwthelper.utils; + +class Matcher { + public Pattern pattern(){ + implMissing( __FILE__, __LINE__ ); + return null; + } + public String group(){ + implMissing( __FILE__, __LINE__ ); + return null; + } + public String group(int n){ + implMissing( __FILE__, __LINE__ ); + return null; + } + public String replaceFirst(String replacement) { + implMissing( __FILE__, __LINE__ ); + return null; + } + public int start(){ + implMissing( __FILE__, __LINE__ ); + return 0; + } + public int end(){ + implMissing( __FILE__, __LINE__ ); + return 0; + } + public bool find(){ + implMissing( __FILE__, __LINE__ ); + return false; + } + public bool find(int start){ + implMissing( __FILE__, __LINE__ ); + return false; + } +} + +class Pattern { + public static const int MULTILINE; + public static const int CASE_INSENSITIVE ; + public static const int UNICODE_CASE ; + + public String pattern(){ + implMissing( __FILE__, __LINE__ ); + return null; + } + public int flags(){ + implMissing( __FILE__, __LINE__ ); + return 0; + } + public static Pattern compile(String regex){ + implMissing( __FILE__, __LINE__ ); + return null; + } + public static Pattern compile(String regex, int flags){ + implMissing( __FILE__, __LINE__ ); + return null; + } + public Matcher matcher(CharSequence input){ + implMissing( __FILE__, __LINE__ ); + return null; + } + public Matcher matcher(String input){ + implMissing( __FILE__, __LINE__ ); + return null; + } +} + +class PatternSyntaxException : IllegalArgumentException { + this(String desc, String regex, int index) { + super(desc); + } +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/contentassist/IContentAssistSubjectControl.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/contentassist/IContentAssistSubjectControl.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,271 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.contentassist.IContentAssistSubjectControl; + +import dwt.dwthelper.utils; + + + +import dwt.custom.VerifyKeyListener; +import dwt.events.KeyListener; +import dwt.events.SelectionListener; +import dwt.graphics.Point; +import dwt.widgets.Control; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IEventConsumer; + + +/** + * A content assist subject control can request assistance provided by a + * {@linkplain dwtx.jface.contentassist.ISubjectControlContentAssistant subject control content assistant}. + * + * @since 3.0 + */ +public interface IContentAssistSubjectControl { + + /** + * Returns the control of this content assist subject control. + * + * @return the control of this content assist subject control + */ + Control getControl(); + + /** + * Returns the line height. + * + * @return line height in pixel + * @exception dwt.DWTException + *

    + *
  • {@link dwt.DWT#ERROR_WIDGET_DISPOSED} - if the receiver has been + * disposed
  • + *
  • {@link dwt.DWT#ERROR_THREAD_INVALID_ACCESS} - if not called from the + * thread that created the receiver
  • + *
+ */ + int getLineHeight(); + + /** + * Returns the caret position relative to the start of the text in widget + * coordinates. + * + * @return the caret position relative to the start of the text in widget + * coordinates + * @exception dwt.DWTException + *
    + *
  • {@link dwt.DWT#ERROR_WIDGET_DISPOSED} - if the receiver has been + * disposed
  • + *
  • {@link dwt.DWT#ERROR_THREAD_INVALID_ACCESS} - if not called from the + * thread that created the receiver
  • + *
+ */ + int getCaretOffset(); + + /** + * Returns the x, y location of the upper left corner of the character + * bounding box at the specified offset in the text. The point is relative + * to the upper left corner of the widget client area. + * + * @param offset widget offset relative to the start of the content 0 + * <= offset <= getCharCount() + * @return x, y location of the upper left corner of the character bounding + * box at the specified offset in the text + * @exception dwt.DWTException + *
    + *
  • {@link dwt.DWT#ERROR_WIDGET_DISPOSED} - if the receiver has been disposed
  • + *
  • {@link dwt.DWT#ERROR_THREAD_INVALID_ACCESS} - if not called from the thread that created the receiver
  • + *
+ * @exception IllegalArgumentException when the offset is outside the valid range + */ + Point getLocationAtOffset(int offset); + + /** + * Returns the line delimiter used for entering new lines by key down or + * paste operation. + * + * @return line delimiter used for entering new lines by key down or paste + * operation + * @exception dwt.DWTException + *
    + *
  • {@link dwt.DWT#ERROR_WIDGET_DISPOSED} - if the receiver has been disposed
  • + *
  • {@link dwt.DWT#ERROR_THREAD_INVALID_ACCESS} - if not called from the thread that created the receiver
  • + *
+ */ + String getLineDelimiter(); + + /** + * Returns the selected range in the subject's widget. + * + * @return start and length of the selection, x is the offset of the + * @exception dwt.DWTException + *
    + *
  • {@link dwt.DWT#ERROR_WIDGET_DISPOSED} - if the receiver has been disposed
  • + *
  • {@link dwt.DWT#ERROR_THREAD_INVALID_ACCESS} - if not called from the thread that created the receiver
  • + *
+ */ + Point getWidgetSelectionRange(); + + /** + * Returns the selected range. + * + * @return start and length of the selection, x is the offset and y the + * length based on the subject's model (e.g. document) + */ + Point getSelectedRange(); + + /** + * Sets the selected range. Offset and length based on the subject's + * model (e.g. document). + * + * @param offset the offset of the selection based on the subject's model e.g. document + * @param length the length of the selection based on the subject's model e.g. document + */ + void setSelectedRange(int offset, int length); + + /** + * Reveals the given region. Offset and length based on the subject's + * model (e.g. document). + * + * @param offset the offset of the selection based on the subject's model e.g. document + * @param length the length of the selection based on the subject's model e.g. document + */ + void revealRange(int offset, int length); + + /** + * Returns this content assist subject control's document. + * + * @return the viewer's input document + */ + IDocument getDocument(); + + /** + * If supported, appends a verify key listener to the viewer's list of verify key + * listeners. If the listener is already registered with the viewer this + * call moves the listener to the end of the list. + *

+ * Note: This content assist subject control may not support appending a verify + * listener, in which case false will be returned. If this + * content assist subject control only supports addVerifyKeyListener + * then this method can be used but prependVerifyKeyListener + * must return false. + *

+ * + * @param verifyKeyListener the listener to be added + * @return true if the listener was added + */ + bool appendVerifyKeyListener(VerifyKeyListener verifyKeyListener); + + /** + * If supported, inserts the verify key listener at the beginning of this content assist + * subject's list of verify key listeners. If the listener is already + * registered with the viewer this call moves the listener to the beginning + * of the list. + *

+ * Note: This content assist subject control may not support prepending a verify + * listener, in which case false will be returned. However, + * {@link #appendVerifyKeyListener(VerifyKeyListener)} might work. + *

+ * + * @param verifyKeyListener the listener to be inserted + * @return true if the listener was added + */ + bool prependVerifyKeyListener(VerifyKeyListener verifyKeyListener); + + /** + * Removes the verify key listener from this content assist subject control's + * list of verify key listeners. If the listener is not registered, this + * call has no effect. + * + * @param verifyKeyListener the listener to be removed + */ + void removeVerifyKeyListener(VerifyKeyListener verifyKeyListener); + + /** + * Tests whether a verify key listener can be added either using prependVerifyKeyListener + * or {@link #appendVerifyKeyListener(VerifyKeyListener)}. + * + * @return true if adding verify key listeners is supported + */ + bool supportsVerifyKeyListener(); + + /** + * Adds the listener to the collection of listeners who will be notified + * when keys are pressed and released on the system keyboard, by sending it + * one of the messages defined in the {@link KeyListener} interface. + * + * @param keyListener the listener which should be notified + * @exception IllegalArgumentException if the listener is null + * @exception dwt.DWTException + *
    + *
  • {@link dwt.DWT#ERROR_WIDGET_DISPOSED} - if the receiver has been disposed
  • + *
  • {@link dwt.DWT#ERROR_THREAD_INVALID_ACCESS} - if not called from the thread that created the receiver
  • + *
+ * + * @see KeyListener + * @see #removeKeyListener(KeyListener) + */ + void addKeyListener(KeyListener keyListener); + + /** + * Removes the listener from the collection of listeners who will be + * notified when keys are pressed and released on the system keyboard. + * + * @param keyListener the listener which should be notified + * @exception IllegalArgumentException if the listener is null + * @exception dwt.DWTException + *
    + *
  • {@link dwt.DWT#ERROR_WIDGET_DISPOSED} - if the receiver has been disposed
  • + *
  • {@link dwt.DWT#ERROR_THREAD_INVALID_ACCESS} - if not called from the thread that created the receiver
  • + *
+ * @see KeyListener + * @see #addKeyListener(KeyListener) + */ + void removeKeyListener(KeyListener keyListener); + + /** + * If supported, registers an event consumer with this content assist + * subject. + * + * @param eventConsumer the content assist subject control's event consumer. null + * is a valid argument. + */ + void setEventConsumer(IEventConsumer eventConsumer); + + /** + * Removes the specified selection listener. + *

+ * + * @param selectionListener the listener + * @exception dwt.DWTException

    + *
      + *
    • {@link dwt.DWT#ERROR_WIDGET_DISPOSED} - if the receiver has been disposed
    • + *
    • {@link dwt.DWT#ERROR_THREAD_INVALID_ACCESS} - if not called from the thread that created the receiver
    • + *
    + * @exception IllegalArgumentException if listener is null + */ + void removeSelectionListener(SelectionListener selectionListener); + + /** + * If supported, adds a selection listener. A Selection event is sent by the widget when the + * selection has changed. + *

    + * + * @param selectionListener the listener + * @return true if adding a selection listener is supported + *

      + *
    • {@link dwt.DWT#ERROR_WIDGET_DISPOSED} - if the receiver has been disposed
    • + *
    • {@link dwt.DWT#ERROR_THREAD_INVALID_ACCESS} - if not called from the thread that created the receiver
    • + *
    + * @exception IllegalArgumentException if listener is null + */ + bool addSelectionListener(SelectionListener selectionListener); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/contentassist/ISubjectControlContentAssistProcessor.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/contentassist/ISubjectControlContentAssistProcessor.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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 + * 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.contentassist.ISubjectControlContentAssistProcessor; + +import dwt.dwthelper.utils; + +import dwtx.jface.text.contentassist.ICompletionProposal; +import dwtx.jface.text.contentassist.IContentAssistProcessor; +import dwtx.jface.text.contentassist.IContextInformation; +import dwtx.jface.contentassist.IContentAssistSubjectControl; + + +/** + * Extension interface for {@link dwtx.jface.text.contentassist.IContentAssistProcessor} + * which provides the context for the + * {@linkplain dwtx.jface.contentassist.ISubjectControlContentAssistant subject control content assistant}. + * + * @since 3.0 + * @deprecated As of 3.2, replaced by Platform UI's field assist support + */ +public interface ISubjectControlContentAssistProcessor : IContentAssistProcessor { + + /** + * Returns a list of completion proposals based on the specified location + * within the document that corresponds to the current cursor position + * within the text viewer. + * + * @param contentAssistSubjectControl the content assist subject control whose + * document is used to compute the proposals + * @param documentOffset an offset within the document for which + * completions should be computed + * @return an array of completion proposals or null if no + * proposals are possible + */ + ICompletionProposal[] computeCompletionProposals(IContentAssistSubjectControl contentAssistSubjectControl, int documentOffset); + + /** + * Returns information about possible contexts based on the specified + * location within the document that corresponds to the current cursor + * position within the content assist subject control. + * + * @param contentAssistSubjectControl the content assist subject control whose + * document is used to compute the possible contexts + * @param documentOffset an offset within the document for which context + * information should be computed + * @return an array of context information objects or null + * if no context could be found + */ + IContextInformation[] computeContextInformation(IContentAssistSubjectControl contentAssistSubjectControl, int documentOffset); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/contentassist/ISubjectControlContentAssistant.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/contentassist/ISubjectControlContentAssistant.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,36 @@ +/******************************************************************************* + * 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 + * 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.contentassist.ISubjectControlContentAssistant; + +import dwt.dwthelper.utils; + +import dwtx.jface.text.contentassist.IContentAssistant; + + +/** + * Extends {@link dwtx.jface.text.contentassist.IContentAssistant} to + * allow to install a content assistant on the given + * {@linkplain dwtx.jface.contentassist.IContentAssistSubjectControl content assist subject control}. + * + * @since 3.0 + * @deprecated As of 3.2, replaced by Platform UI's field assist support + */ +public interface ISubjectControlContentAssistant : IContentAssistant { + + /** + * Installs content assist support on the given subject. + * + * @param contentAssistSubjectControl the one who requests content assist + */ + void install(IContentAssistSubjectControl contentAssistSubjectControl); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/contentassist/ISubjectControlContextInformationPresenter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/contentassist/ISubjectControlContextInformationPresenter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,39 @@ +/******************************************************************************* + * 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 + * 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.contentassist.ISubjectControlContextInformationPresenter; + +import dwt.dwthelper.utils; + +import dwtx.jface.text.contentassist.IContextInformation; +import dwtx.jface.text.contentassist.IContextInformationPresenter; +import dwtx.jface.contentassist.IContentAssistSubjectControl; + +/** + * Extends {@link dwtx.jface.text.contentassist.IContextInformationPresenter} to + * allow to install a content assistant on the given + * {@linkplain dwtx.jface.contentassist.IContentAssistSubjectControl content assist subject control}. + * + * @since 3.0 + * @deprecated As of 3.2, replaced by Platform UI's field assist support + */ +public interface ISubjectControlContextInformationPresenter : IContextInformationPresenter { + + /** + * Installs this presenter for the given context information. + * + * @param info the context information which this presenter should style + * @param contentAssistSubjectControl the content assist subject control + * @param offset the document offset for which the information has been computed + */ + void install(IContextInformation info, IContentAssistSubjectControl contentAssistSubjectControl, int offset); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/contentassist/ISubjectControlContextInformationValidator.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/contentassist/ISubjectControlContextInformationValidator.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,41 @@ +/******************************************************************************* + * 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 + * 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.contentassist.ISubjectControlContextInformationValidator; + +import dwt.dwthelper.utils; + +import dwtx.jface.text.contentassist.IContextInformation; +import dwtx.jface.text.contentassist.IContextInformationValidator; +import dwtx.jface.contentassist.IContentAssistSubjectControl; + + +/** + * Extends {@link dwtx.jface.text.contentassist.IContextInformationValidator} to + * allow to install a content assistant on the given + * {@linkplain dwtx.jface.contentassist.IContentAssistSubjectControl content assist subject control}. + * + * @since 3.0 + * @deprecated As of 3.2, replaced by Platform UI's field assist support + */ +public interface ISubjectControlContextInformationValidator : IContextInformationValidator { + + /** + * Installs this validator for the given context information. + * + * @param info the context information which this validator should check + * @param contentAssistSubjectControl the content assist subject control + * @param offset the document offset for which the information + * has been computed + */ + void install(IContextInformation info, IContentAssistSubjectControl contentAssistSubjectControl, int offset); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/DelayedInputChangeListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/DelayedInputChangeListener.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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.text.DelayedInputChangeListener; + +import dwtx.jface.internal.text.NonDeletingPositionUpdater; // packageimport +import dwtx.jface.internal.text.InternalAccessor; // packageimport +import dwtx.jface.internal.text.StickyHoverManager; // packageimport +import dwtx.jface.internal.text.InformationControlReplacer; // packageimport +import dwtx.jface.internal.text.TableOwnerDrawSupport; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.IDelayedInputChangeProvider; +import dwtx.jface.text.IInputChangedListener; + + +/** + * A delayed input change listener that forwards delayed input changes to an information control replacer. + * + * @since 3.4 + */ +public final class DelayedInputChangeListener : IInputChangedListener { + + private const IDelayedInputChangeProvider fChangeProvider; + private const InformationControlReplacer fInformationControlReplacer; + + /** + * Creates a new listener. + * + * @param changeProvider the information control with delayed input changes + * @param informationControlReplacer the information control replacer, whose information control should get the new input + */ + public this(IDelayedInputChangeProvider changeProvider, InformationControlReplacer informationControlReplacer) { + fChangeProvider= changeProvider; + fInformationControlReplacer= informationControlReplacer; + } + + /* + * @see dwtx.jface.text.IDelayedInputChangeListener#inputChanged(java.lang.Object) + */ + public void inputChanged(Object newInput) { + fChangeProvider.setDelayedInputChangeListener(null); + fInformationControlReplacer.setDelayedInput(newInput); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/InformationControlReplacer.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/InformationControlReplacer.d Mon Sep 08 01:38:10 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.internal.text.InformationControlReplacer; + +import dwtx.jface.internal.text.NonDeletingPositionUpdater; // packageimport +import dwtx.jface.internal.text.InternalAccessor; // packageimport +import dwtx.jface.internal.text.StickyHoverManager; // packageimport +import dwtx.jface.internal.text.TableOwnerDrawSupport; // packageimport +import dwtx.jface.internal.text.DelayedInputChangeListener; // packageimport + + +import dwt.dwthelper.utils; + + + +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Shell; +import dwtx.jface.text.AbstractInformationControlManager; +import dwtx.jface.text.AbstractReusableInformationControlCreator; +import dwtx.jface.text.DefaultInformationControl; +import dwtx.jface.text.IInformationControl; +import dwtx.jface.text.IInformationControlCreator; +import dwtx.jface.text.IInformationControlExtension2; +import dwtx.jface.text.IInformationControlExtension3; +import dwtx.jface.util.Geometry; + + +/** + * An information control replacer can replace an + * {@link AbstractInformationControlManager}'s control. + * + * @see AbstractInformationControlManager#setInformationControlReplacer(InformationControlReplacer) + * @since 3.4 + */ +public class InformationControlReplacer : AbstractInformationControlManager { + alias AbstractInformationControlManager.showInformationControl showInformationControl; + /** + * Minimal width in pixels. + */ + private static const int MIN_WIDTH= 80; + /** + * Minimal height in pixels. + */ + private static const int MIN_HEIGHT= 50; + + /** + * Default control creator. + */ + protected static class DefaultInformationControlCreator : AbstractReusableInformationControlCreator { + public IInformationControl doCreateInformationControl(Shell shell) { + return new DefaultInformationControl(shell, true); + } + } + + private bool fIsReplacing; + private Object fReplacableInformation; + private bool fDelayedInformationSet; + private Rectangle fReplaceableArea; + private Rectangle fContentBounds; + + + /** + * Creates a new information control replacer. + * + * @param creator the default information control creator + */ + public this(IInformationControlCreator creator) { + super(creator); + takesFocusWhenVisible(false); + } + + /** + * Replace the information control. + * + * @param informationPresenterControlCreator the information presenter control creator + * @param contentBounds the bounds of the content area of the information control + * @param information the information to show + * @param subjectArea the subject area + * @param takeFocus true iff the replacing information control should take focus + */ + public void replaceInformationControl(IInformationControlCreator informationPresenterControlCreator, Rectangle contentBounds, Object information, Rectangle subjectArea, bool takeFocus) { + + try { + fIsReplacing= true; + if (! fDelayedInformationSet) + fReplacableInformation= information; + else + takeFocus= true; // delayed input has been set, so the original info control must have been focused + fContentBounds= contentBounds; + fReplaceableArea= subjectArea; + + setCustomInformationControlCreator(informationPresenterControlCreator); + + takesFocusWhenVisible(takeFocus); + + showInformation(); + } finally { + fIsReplacing= false; + fReplacableInformation= null; + fDelayedInformationSet= false; + fReplaceableArea= null; + setCustomInformationControlCreator(null); + } + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#computeInformation() + */ + protected void computeInformation() { + if (fIsReplacing && fReplacableInformation !is null) { + setInformation(fReplacableInformation, fReplaceableArea); + return; + } + + if (DEBUG) + System.out_.println("InformationControlReplacer: no active replaceable"); //$NON-NLS-1$ + } + + /** + * Opens the information control with the given information and the specified + * subject area. It also activates the information control closer. + * + * @param subjectArea the information area + * @param information the information + */ + public void showInformationControl(Rectangle subjectArea, Object information) { + IInformationControl informationControl= getInformationControl(); + + Rectangle controlBounds= fContentBounds; + if ( cast(IInformationControlExtension3)informationControl ) { + IInformationControlExtension3 iControl3= cast(IInformationControlExtension3) informationControl; + Rectangle trim= iControl3.computeTrim(); + controlBounds= Geometry.add(controlBounds, trim); + + /* + * Ensure minimal size. Interacting with a tiny information control + * (resizing, selecting text) would be a pain. + */ + controlBounds.width= Math.max(controlBounds.width, MIN_WIDTH); + controlBounds.height= Math.max(controlBounds.height, MIN_HEIGHT); + + getInternalAccessor().cropToClosestMonitor(controlBounds); + } + + Point location= Geometry.getLocation(controlBounds); + Point size= Geometry.getSize(controlBounds); + + // Caveat: some IInformationControls fail unless setSizeConstraints(..) is called with concrete values + informationControl.setSizeConstraints(size.x, size.y); + + if ( cast(IInformationControlExtension2)informationControl ) + (cast(IInformationControlExtension2) informationControl).setInput(information); + else + informationControl.setInformation(information.toString()); + + informationControl.setLocation(location); + informationControl.setSize(size.x, size.y); + + showInformationControl(subjectArea); + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#hideInformationControl() + */ + public void hideInformationControl() { + super.hideInformationControl(); + } + + /** + * @param input the delayed input, or null to request cancellation + */ + public void setDelayedInput(Object input) { + fReplacableInformation= input; + if (! isReplacing()) { + fDelayedInformationSet= true; + } else if (cast(IInformationControlExtension2)getCurrentInformationControl2() ) { + (cast(IInformationControlExtension2) getCurrentInformationControl2()).setInput(input); + } else if (getCurrentInformationControl2() !is null) { + getCurrentInformationControl2().setInformation(input.toString()); + } + } + + /** + * Tells whether the replacer is currently replacing another information control. + * + * @return true while code from {@link #replaceInformationControl(IInformationControlCreator, Rectangle, Object, Rectangle, bool)} is run + */ + public bool isReplacing() { + return fIsReplacing; + } + + /** + * @return the current information control, or null if none available + */ + public IInformationControl getCurrentInformationControl2() { + return getInternalAccessor().getCurrentInformationControl(); + } + + /** + * The number of pixels to blow up the keep-up zone. + * + * @return the margin in pixels + */ + public int getKeepUpMargin() { + return 15; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/InternalAccessor.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/InternalAccessor.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,114 @@ +/******************************************************************************* + * 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.text.InternalAccessor; + +import dwtx.jface.internal.text.NonDeletingPositionUpdater; // packageimport +import dwtx.jface.internal.text.StickyHoverManager; // packageimport +import dwtx.jface.internal.text.InformationControlReplacer; // packageimport +import dwtx.jface.internal.text.TableOwnerDrawSupport; // packageimport +import dwtx.jface.internal.text.DelayedInputChangeListener; // packageimport + + +import dwt.dwthelper.utils; + + + +import dwt.graphics.Rectangle; +import dwtx.jface.text.AbstractInformationControlManager; +import dwtx.jface.text.IInformationControl; +import dwtx.jface.text.IInformationControlExtension3; +import dwtx.jface.text.ITextViewerExtension8; +import dwtx.jface.text.ITextViewerExtension8; + + +/** + * An internal class that gives access to internal methods of {@link + * AbstractInformationControlManager} and subclasses. + * + * @since 3.4 + */ +public abstract class InternalAccessor { + + /** + * Returns the current information control, or null if none. + * + * @return the current information control, or null if none + */ + public abstract IInformationControl getCurrentInformationControl(); + + /** + * Sets the information control replacer for this manager and disposes the + * old one if set. + * + * @param replacer the information control replacer for this manager, or + * null if no information control replacing should + * take place + */ + public abstract void setInformationControlReplacer(InformationControlReplacer replacer); + + /** + * Returns the current information control replacer or null if none has been installed. + * + * @return the current information control replacer or null if none has been installed + */ + public abstract InformationControlReplacer getInformationControlReplacer(); + + /** + * Tests whether the given information control is replaceable. + * + * @param iControl information control or null if none + * @return true if information control is replaceable, false otherwise + */ + public abstract bool canReplace(IInformationControl iControl); + + /** + * Tells whether this manager's information control is currently being replaced. + * + * @return true if a replace is in progress + */ + public abstract bool isReplaceInProgress(); + + /** + * Crops the given bounds such that they lie completely on the closest monitor. + * + * @param bounds shell bounds to crop + */ + public abstract void cropToClosestMonitor(Rectangle bounds); + + /** + * Sets the hover enrich mode. Only applicable when an information + * control replacer has been set with + * {@link #setInformationControlReplacer(InformationControlReplacer)} . + * + * @param mode the enrich mode + * @see ITextViewerExtension8#setHoverEnrichMode(dwtx.jface.text.ITextViewerExtension8.EnrichMode) + */ + public abstract void setHoverEnrichMode(ITextViewerExtension8_EnrichMode mode); + + /** + * Indicates whether the mouse cursor is allowed to leave the subject area without closing the hover. + * + * @return whether the mouse cursor is allowed to leave the subject area without closing the hover + */ + public abstract bool getAllowMouseExit(); + + /** + * Replaces this manager's information control as defined by + * the information control replacer. + * Must only be called when the information control is instanceof {@link IInformationControlExtension3}! + * + * @param takeFocus true iff the replacing information control should take focus + */ + public abstract void replaceInformationControl(bool takeFocus); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/NonDeletingPositionUpdater.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/NonDeletingPositionUpdater.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,118 @@ +/******************************************************************************* + * 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.internal.text.NonDeletingPositionUpdater; + +import dwtx.jface.internal.text.InternalAccessor; // packageimport +import dwtx.jface.internal.text.StickyHoverManager; // packageimport +import dwtx.jface.internal.text.InformationControlReplacer; // packageimport +import dwtx.jface.internal.text.TableOwnerDrawSupport; // packageimport +import dwtx.jface.internal.text.DelayedInputChangeListener; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.BadPositionCategoryException; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IPositionUpdater; +import dwtx.jface.text.Position; + + +/** + * A position updater that never deletes a position. If the region containing + * the position is deleted, the position is moved to the beginning/end (falling + * together) of the change. If the region containing the position is replaced, + * the position is placed at the same location inside the replacement text, but + * always inside the replacement text. + * + * @since 3.1 + */ +public final class NonDeletingPositionUpdater : IPositionUpdater { + /** The position category. */ + private const String fCategory; + + /** + * Creates a new updater for the given category. + * + * @param category the new category. + */ + public this(String category) { + fCategory= category; + } + + /* + * @see dwtx.jface.text.IPositionUpdater#update(dwtx.jface.text.DocumentEvent) + */ + public void update(DocumentEvent event) { + + int eventOffset= event.getOffset(); + int eventOldEndOffset= eventOffset + event.getLength(); + int eventNewLength= event.getText() is null ? 0 : event.getText().length(); + int eventNewEndOffset= eventOffset + eventNewLength; + int deltaLength= eventNewLength - event.getLength(); + + try { + Position[] positions= event.getDocument().getPositions(fCategory); + + for (int i= 0; i !is positions.length; i++) { + + Position position= positions[i]; + + if (position.isDeleted()) + continue; + + int offset= position.getOffset(); + int length= position.getLength(); + int end= offset + length; + + if (offset > eventOldEndOffset) { + // position comes way after change - shift + position.setOffset(offset + deltaLength); + } else if (end < eventOffset) { + // position comes way before change - leave alone + } else if (offset <= eventOffset && end >= eventOldEndOffset) { + // event completely internal to the position - adjust length + position.setLength(length + deltaLength); + } else if (offset < eventOffset) { + // event extends over end of position - include the + // replacement text into the position + position.setLength(eventNewEndOffset - offset); + } else if (end > eventOldEndOffset) { + // event extends from before position into it - adjust + // offset and length, including the replacement text into + // the position + position.setOffset(eventOffset); + int deleted= eventOldEndOffset - offset; + position.setLength(length - deleted + eventNewLength); + } else { + // event comprises the position - keep it at the same + // position, but always inside the replacement text + int newOffset= Math.min(offset, eventNewEndOffset); + int newEndOffset= Math.min(end, eventNewEndOffset); + position.setOffset(newOffset); + position.setLength(newEndOffset - newOffset); + } + } + } catch (BadPositionCategoryException e) { + // ignore and return + } + } + + /** + * Returns the position category. + * + * @return the position category + */ + public String getCategory() { + return fCategory; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/StickyHoverManager.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/StickyHoverManager.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,385 @@ +/******************************************************************************* + * 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 + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.internal.text.StickyHoverManager; + +import dwtx.jface.internal.text.NonDeletingPositionUpdater; // packageimport +import dwtx.jface.internal.text.InternalAccessor; // packageimport +import dwtx.jface.internal.text.InformationControlReplacer; // packageimport +import dwtx.jface.internal.text.TableOwnerDrawSupport; // packageimport +import dwtx.jface.internal.text.DelayedInputChangeListener; // packageimport + +import dwt.dwthelper.utils; +import tango.text.convert.Format; + +import dwt.DWT; +import dwt.events.ControlEvent; +import dwt.events.ControlListener; +import dwt.events.FocusEvent; +import dwt.events.FocusListener; +import dwt.events.KeyEvent; +import dwt.events.KeyListener; +import dwt.events.MouseEvent; +import dwt.events.MouseListener; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Listener; +import dwtx.jface.text.IInformationControl; +import dwtx.jface.text.IInformationControlExtension3; +import dwtx.jface.text.IInformationControlExtension5; +import dwtx.jface.text.IViewportListener; +import dwtx.jface.text.IWidgetTokenKeeper; +import dwtx.jface.text.IWidgetTokenKeeperExtension; +import dwtx.jface.text.IWidgetTokenOwner; +import dwtx.jface.text.TextViewer; +import dwtx.jface.util.Geometry; + +/** + * Implements a sticky hover control, i.e. a control that replaces a hover + * with an enriched and focusable control. + *

    + * The information control is made visible on request by calling + * {@link #showInformationControl(Rectangle)}. + *

    + *

    + * Clients usually instantiate and configure this class before using it. The configuration + * must be consistent: This means the used {@link dwtx.jface.text.IInformationControlCreator} + * must create an information control expecting information in the same format the configured + * {@link dwtx.jface.text.information.IInformationProvider}s use to encode the information they provide. + *

    + * + * @since 3.4 + */ +public class StickyHoverManager : InformationControlReplacer , IWidgetTokenKeeper, IWidgetTokenKeeperExtension { + + /** + * Priority of the info controls managed by this sticky hover manager. + *

    + * Note: Only applicable when info control does not have focus. + * -5 as value has been chosen in order to be beaten by the hovers of TextViewerHoverManager. + *

    + */ + private static const int WIDGET_PRIORITY= -5; + + + /** + * Internal information control closer. Listens to several events issued by its subject control + * and closes the information control when necessary. + */ + class Closer : IInformationControlCloser, ControlListener, MouseListener, IViewportListener, KeyListener, FocusListener, Listener { + //TODO: Catch 'Esc' key in fInformationControlToClose: Don't dispose, just hideInformationControl(). + // This would allow to reuse the information control also when the user explicitly closes it. + + //TODO: if subject control is a Scrollable, should add selection listeners to both scroll bars + // (and remove the ViewPortListener, which only listens to vertical scrolling) + + /** The subject control. */ + private Control fSubjectControl; + /** Indicates whether this closer is active. */ + private bool fIsActive= false; + /** The display. */ + private Display fDisplay; + + /* + * @see IInformationControlCloser#setSubjectControl(Control) + */ + public void setSubjectControl(Control control) { + fSubjectControl= control; + } + + /* + * @see IInformationControlCloser#setInformationControl(IInformationControl) + */ + public void setInformationControl(IInformationControl control) { + // NOTE: we use getCurrentInformationControl2() from the outer class + } + + /* + * @see IInformationControlCloser#start(Rectangle) + */ + public void start(Rectangle informationArea) { + + if (fIsActive) + return; + fIsActive= true; + + if (fSubjectControl !is null && !fSubjectControl.isDisposed()) { + fSubjectControl.addControlListener(this); + fSubjectControl.addMouseListener(this); + fSubjectControl.addKeyListener(this); + } + + fTextViewer.addViewportListener(this); + + IInformationControl fInformationControlToClose= getCurrentInformationControl2(); + if (fInformationControlToClose !is null) + fInformationControlToClose.addFocusListener(this); + + fDisplay= fSubjectControl.getDisplay(); + if (!fDisplay.isDisposed()) { + fDisplay.addFilter(DWT.MouseMove, this); + fDisplay.addFilter(DWT.FocusOut, this); + } + } + + /* + * @see IInformationControlCloser#stop() + */ + public void stop() { + + if (!fIsActive) + return; + fIsActive= false; + + fTextViewer.removeViewportListener(this); + + if (fSubjectControl !is null && !fSubjectControl.isDisposed()) { + fSubjectControl.removeControlListener(this); + fSubjectControl.removeMouseListener(this); + fSubjectControl.removeKeyListener(this); + } + + IInformationControl fInformationControlToClose= getCurrentInformationControl2(); + if (fInformationControlToClose !is null) + fInformationControlToClose.removeFocusListener(this); + + if (fDisplay !is null && !fDisplay.isDisposed()) { + fDisplay.removeFilter(DWT.MouseMove, this); + fDisplay.removeFilter(DWT.FocusOut, this); + } + + fDisplay= null; + } + + /* + * @see ControlListener#controlResized(ControlEvent) + */ + public void controlResized(ControlEvent e) { + hideInformationControl(); + } + + /* + * @see ControlListener#controlMoved(ControlEvent) + */ + public void controlMoved(ControlEvent e) { + hideInformationControl(); + } + + /* + * @see MouseListener#mouseDown(MouseEvent) + */ + public void mouseDown(MouseEvent e) { + hideInformationControl(); + } + + /* + * @see MouseListener#mouseUp(MouseEvent) + */ + public void mouseUp(MouseEvent e) { + } + + /* + * @see MouseListener#mouseDoubleClick(MouseEvent) + */ + public void mouseDoubleClick(MouseEvent e) { + hideInformationControl(); + } + + /* + * @see IViewportListenerListener#viewportChanged(int) + */ + public void viewportChanged(int topIndex) { + hideInformationControl(); + } + + /* + * @see KeyListener#keyPressed(KeyEvent) + */ + public void keyPressed(KeyEvent e) { + hideInformationControl(); + } + + /* + * @see KeyListener#keyReleased(KeyEvent) + */ + public void keyReleased(KeyEvent e) { + } + + /* + * @see dwt.events.FocusListener#focusGained(dwt.events.FocusEvent) + */ + public void focusGained(FocusEvent e) { + } + + /* + * @see dwt.events.FocusListener#focusLost(dwt.events.FocusEvent) + */ + public void focusLost(FocusEvent e) { + if (DEBUG) System.out_.println(Format("StickyHoverManager.Closer.focusLost(): {}", e)); //$NON-NLS-1$ + Display d= fSubjectControl.getDisplay(); + d.asyncExec(new class() Runnable { + // Without the asyncExec, mouse clicks to the workbench window are swallowed. + public void run() { + hideInformationControl(); + } + }); + } + + /* + * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event) + */ + public void handleEvent(Event event) { + if (event.type is DWT.MouseMove) { + if (!( cast(Control)event.widget ) || event.widget.isDisposed()) + return; + + IInformationControl infoControl= getCurrentInformationControl2(); + if (infoControl !is null && !infoControl.isFocusControl() && cast(IInformationControlExtension3)infoControl ) { +// if (DEBUG) System.out_.println("StickyHoverManager.Closer.handleEvent(): activeShell= " + fDisplay.getActiveShell()); //$NON-NLS-1$ + IInformationControlExtension3 iControl3= cast(IInformationControlExtension3) infoControl; + Rectangle controlBounds= iControl3.getBounds(); + if (controlBounds !is null) { + Point mouseLoc= event.display.map(cast(Control) event.widget, null, event.x, event.y); + int margin= getKeepUpMargin(); + Geometry.expand(controlBounds, margin, margin, margin, margin); + if (!controlBounds.contains(mouseLoc)) { + hideInformationControl(); + } + } + + } else { + /* + * TODO: need better understanding of why/if this is needed. + * Looks like the same panic code we have in dwtx.jface.text.AbstractHoverInformationControlManager.Closer.handleMouseMove(Event) + */ + if (fDisplay !is null && !fDisplay.isDisposed()) + fDisplay.removeFilter(DWT.MouseMove, this); + } + + } else if (event.type is DWT.FocusOut) { + if (DEBUG) System.out_.println(Format("StickyHoverManager.Closer.handleEvent(): focusOut: {}", event)); //$NON-NLS-1$ + IInformationControl iControl= getCurrentInformationControl2(); + if (iControl !is null && ! iControl.isFocusControl()) + hideInformationControl(); + } + } + } + + + private const TextViewer fTextViewer; + + + /** + * Creates a new sticky hover manager. + * + * @param textViewer the text viewer + */ + public this(TextViewer textViewer) { + super(new DefaultInformationControlCreator()); + + fTextViewer= textViewer; + setCloser(new Closer()); + + install(fTextViewer.getTextWidget()); + } + + /* + * @see AbstractInformationControlManager#showInformationControl(Rectangle) + */ + protected void showInformationControl(Rectangle subjectArea) { + if (fTextViewer !is null && fTextViewer.requestWidgetToken(this, WIDGET_PRIORITY)) + super.showInformationControl(subjectArea); + else + if (DEBUG) + System.out_.println("cancelled StickyHoverManager.showInformationControl(..): did not get widget token (with prio)"); //$NON-NLS-1$ + } + + /* + * @see AbstractInformationControlManager#hideInformationControl() + */ + public void hideInformationControl() { + try { + super.hideInformationControl(); + } finally { + if (fTextViewer !is null) + fTextViewer.releaseWidgetToken(this); + } + } + + /* + * @see AbstractInformationControlManager#handleInformationControlDisposed() + */ + protected void handleInformationControlDisposed() { + try { + super.handleInformationControlDisposed(); + } finally { + if (fTextViewer !is null) + fTextViewer.releaseWidgetToken(this); + } + } + + /* + * @see dwtx.jface.text.IWidgetTokenKeeper#requestWidgetToken(IWidgetTokenOwner) + */ + public bool requestWidgetToken(IWidgetTokenOwner owner) { + hideInformationControl(); + if (DEBUG) + System.out_.println("StickyHoverManager gave up widget token (no prio)"); //$NON-NLS-1$ + return true; + } + + /* + * @see dwtx.jface.text.IWidgetTokenKeeperExtension#requestWidgetToken(dwtx.jface.text.IWidgetTokenOwner, int) + */ + public bool requestWidgetToken(IWidgetTokenOwner owner, int priority) { + if (getCurrentInformationControl2() !is null) { + if (getCurrentInformationControl2().isFocusControl()) { + if (DEBUG) + System.out_.println("StickyHoverManager kept widget token (focused)"); //$NON-NLS-1$ + return false; + } else if (priority > WIDGET_PRIORITY) { + hideInformationControl(); + if (DEBUG) + System.out_.println("StickyHoverManager gave up widget token (prio)"); //$NON-NLS-1$ + return true; + } else { + if (DEBUG) + System.out_.println("StickyHoverManager kept widget token (prio)"); //$NON-NLS-1$ + return false; + } + } + if (DEBUG) + System.out_.println("StickyHoverManager gave up widget token (no iControl)"); //$NON-NLS-1$ + return true; + } + + /* + * @see dwtx.jface.text.IWidgetTokenKeeperExtension#setFocus(dwtx.jface.text.IWidgetTokenOwner) + */ + public bool setFocus(IWidgetTokenOwner owner) { + IInformationControl iControl= getCurrentInformationControl2(); + if ( cast(IInformationControlExtension5)iControl ) { + IInformationControlExtension5 iControl5= cast(IInformationControlExtension5) iControl; + if (iControl5.isVisible()) { + iControl.setFocus(); + return iControl.isFocusControl(); + } + return false; + } + iControl.setFocus(); + return iControl.isFocusControl(); + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/TableOwnerDrawSupport.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/TableOwnerDrawSupport.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,179 @@ +/******************************************************************************* + * 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.text.TableOwnerDrawSupport; + +import dwtx.jface.internal.text.NonDeletingPositionUpdater; // packageimport +import dwtx.jface.internal.text.InternalAccessor; // packageimport +import dwtx.jface.internal.text.StickyHoverManager; // packageimport +import dwtx.jface.internal.text.InformationControlReplacer; // packageimport +import dwtx.jface.internal.text.DelayedInputChangeListener; // packageimport + + +import dwt.dwthelper.utils; + +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.Event; +import dwt.widgets.Listener; +import dwt.widgets.Table; +import dwt.widgets.TableItem; + + +/** + * Adds owner draw support for tables. + * + * @since 3.4 + */ +public class TableOwnerDrawSupport : Listener { + + private static const String STYLED_RANGES_KEY= "styled_ranges"; //$NON-NLS-1$ + + private TextLayout fLayout; + + public static void install(Table table) { + TableOwnerDrawSupport listener= new TableOwnerDrawSupport(table); + table.addListener(DWT.Dispose, listener); + table.addListener(DWT.MeasureItem, listener); + table.addListener(DWT.EraseItem, listener); + table.addListener(DWT.PaintItem, listener); + } + + /** + * Stores the styled ranges in the given table item. + * + * @param item table item + * @param column the column index + * @param ranges the styled ranges or null to remove them + */ + public static void storeStyleRanges(TableItem item, int column, StyleRange[] ranges) { + item.setData(STYLED_RANGES_KEY ~ Integer.toString(column), new ArrayWrapperObject(arraycast!(Object)(ranges))); + } + + /** + * Returns the styled ranges which are stored in the given table item. + * + * @param item table item + * @param column the column index + * @return the styled ranges + */ + private static StyleRange[] getStyledRanges(TableItem item, int column) { + return arrayFromObject!(StyleRange)(item.getData(STYLED_RANGES_KEY ~ Integer.toString(column))); + } + + private this(Table table) { + int orientation= table.getStyle() & (DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT); + fLayout= new TextLayout(table.getDisplay()); + fLayout.setOrientation(orientation); + } + + /* + * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event) + */ + public void handleEvent(Event event) { + switch (event.type) { + case DWT.MeasureItem: + break; + case DWT.EraseItem: + event.detail &= ~DWT.FOREGROUND; + break; + case DWT.PaintItem: + performPaint(event); + break; + case DWT.Dispose: + widgetDisposed(); + break; + } + } + + /** + * Performs the paint operation. + * + * @param event the event + */ + private void performPaint(Event event) { + TableItem item= cast(TableItem) event.item; + GC gc= event.gc; + int index= event.index; + + bool isSelected= (event.detail & DWT.SELECTED) !is 0; + + // Remember colors to restore the GC later + Color oldForeground= gc.getForeground(); + Color oldBackground= gc.getBackground(); + + if (!isSelected) { + Color foreground= item.getForeground(index); + gc.setForeground(foreground); + + Color background= item.getBackground(index); + gc.setBackground(background); + } + + Image image=item.getImage(index); + if (image !is null) { + Rectangle imageBounds=item.getImageBounds(index); + Rectangle bounds=image.getBounds(); + 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); + } + + fLayout.setFont(item.getFont(index)); + + // XXX: needed to clear the style info, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=226090 + fLayout.setText(""); //$NON-NLS-1$ + + fLayout.setText(item.getText(index)); + + StyleRange[] ranges= getStyledRanges(item, index); + if (ranges !is null) { + for (int i= 0; i < ranges.length; i++) { + StyleRange curr= ranges[i]; + if (isSelected) { + curr= cast(StyleRange) curr.clone(); + curr.foreground= null; + curr.background= null; + } + fLayout.setStyle(curr, curr.start, curr.start + curr.length - 1); + } + } + + Rectangle textBounds=item.getTextBounds(index); + if (textBounds !is null) { + Rectangle layoutBounds=fLayout.getBounds(); + int x=textBounds.x; + int y=textBounds.y + Math.max(0, (textBounds.height - layoutBounds.height) / 2); + fLayout.draw(gc, x, y); + } + + if ((event.detail & DWT.FOCUSED) !is 0) { + Rectangle focusBounds=item.getBounds(); + gc.drawFocus(focusBounds.x, focusBounds.y, focusBounds.width, focusBounds.height); + } + + if (!isSelected) { + gc.setForeground(oldForeground); + gc.setBackground(oldBackground); + } + } + + private void widgetDisposed() { + fLayout.dispose(); + } +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/html/BrowserInformationControl.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/html/BrowserInformationControl.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,663 @@ +/******************************************************************************* + * 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 + * 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.text.html.BrowserInformationControl; + +import dwtx.jface.internal.text.html.HTML2TextReader; // packageimport +import dwtx.jface.internal.text.html.HTMLPrinter; // packageimport +import dwtx.jface.internal.text.html.SubstitutionTextReader; // packageimport +import dwtx.jface.internal.text.html.HTMLTextPresenter; // packageimport +import dwtx.jface.internal.text.html.BrowserInput; // packageimport +import dwtx.jface.internal.text.html.SingleCharReader; // packageimport +import dwtx.jface.internal.text.html.BrowserInformationControlInput; // packageimport +import dwtx.jface.internal.text.html.HTMLMessages; // packageimport + +import dwt.dwthelper.utils; + +import dwt.widgets.Shell; +import dwt.widgets.Composite; +import dwtx.jface.text.AbstractInformationControl; +import dwtx.jface.text.IInformationControlExtension2; +import dwtx.jface.text.IDelayedInputChangeProvider; +import dwtx.jface.text.IInputChangedListener; + +pragma( msg, "dwtx.jface.internal.text.html.BrowserInformationControl: SWT browser control missing" ); +class BrowserInformationControl : AbstractInformationControl , IInformationControlExtension2, IDelayedInputChangeProvider { + public this(Shell parent, String symbolicFontName, bool resizable){} + public static bool isAvailable(Composite parent){} + public void setInformation(String content) {} + protected void createContent(Composite parent) { + } + public void setInput(Object input) {} + public void setDelayedInputChangeListener(IInputChangedListener inputChangeListener) {} + public bool hasContents() { + return false; + } +} + +// FIXME needs Browser :/ +/++ + +import dwtx.dwtxhelper.StringReader; +import dwtx.dwtxhelper.Collection; + +import dwt.DWT; +import dwt.DWTError; +import dwt.browser.Browser; +import dwt.browser.LocationListener; +import dwt.browser.ProgressAdapter; +import dwt.browser.ProgressEvent; +import dwt.custom.StyleRange; +import dwt.events.KeyEvent; +import dwt.events.KeyListener; +import dwt.graphics.Color; +import dwt.graphics.Font; +import dwt.graphics.FontData; +import dwt.graphics.GC; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.graphics.TextLayout; +import dwt.graphics.TextStyle; +import dwt.widgets.Composite; +import dwt.widgets.Display; +import dwt.widgets.Menu; +import dwt.widgets.Shell; +import dwt.widgets.Slider; +import dwtx.core.runtime.Assert; +import dwtx.core.runtime.ListenerList; +import dwtx.jface.action.ToolBarManager; +import dwtx.jface.resource.JFaceResources; +import dwtx.jface.text.AbstractInformationControl; +import dwtx.jface.text.IDelayedInputChangeProvider; +import dwtx.jface.text.IInformationControlExtension2; +import dwtx.jface.text.IInputChangedListener; +import dwtx.jface.text.TextPresentation; + + +/** + * Displays HTML information in a {@link dwt.browser.Browser} widget. + *

    + * This {@link IInformationControlExtension2} expects {@link #setInput(Object)} to be + * called with an argument of type {@link BrowserInformationControlInput}. + *

    + *

    + * Moved into this package from dwtx.jface.internal.text.revisions.

    + *

    + * This class may be instantiated; it is not intended to be subclassed.

    + *

    + * Current problems: + *

      + *
    • the size computation is too small
    • + *
    • focusLost event is not sent - see https://bugs.eclipse.org/bugs/show_bug.cgi?id=84532
    • + *
    + *

    + * + * @since 3.2 + */ +public class BrowserInformationControl : AbstractInformationControl , IInformationControlExtension2, IDelayedInputChangeProvider { + + + /** + * Tells whether the DWT Browser widget and hence this information + * control is available. + * + * @param parent the parent component used for checking or null if none + * @return true if this control is available + */ + public static bool isAvailable(Composite parent) { + if (!fgAvailabilityChecked) { + try { + Browser browser= new Browser(parent, DWT.NONE); + browser.dispose(); + fgIsAvailable= true; + + Slider sliderV= new Slider(parent, DWT.VERTICAL); + Slider sliderH= new Slider(parent, DWT.HORIZONTAL); + int width= sliderV.computeSize(DWT.DEFAULT, DWT.DEFAULT).x; + int height= sliderH.computeSize(DWT.DEFAULT, DWT.DEFAULT).y; + fgScrollBarSize= new Point(width, height); + sliderV.dispose(); + sliderH.dispose(); + } catch (DWTError er) { + fgIsAvailable= false; + } finally { + fgAvailabilityChecked= true; + } + } + + return fgIsAvailable; + } + + + /** + * Minimal size constraints. + * @since 3.2 + */ + private static const int MIN_WIDTH= 80; + private static const int MIN_HEIGHT= 50; + + + /** + * Availability checking cache. + */ + private static bool fgIsAvailable= false; + private static bool fgAvailabilityChecked= false; + + /** + * Cached scroll bar width and height + * @since 3.4 + */ + private static Point fgScrollBarSize; + + /** The control's browser widget */ + private Browser fBrowser; + /** Tells whether the browser has content */ + private bool fBrowserHasContent; + /** Text layout used to approximate size of content when rendered in browser */ + private TextLayout fTextLayout; + /** Bold text style */ + private TextStyle fBoldStyle; + + private BrowserInformationControlInput fInput; + + /** + * true iff the browser has completed loading of the last + * input set via {@link #setInformation(String)}. + * @since 3.4 + */ + private bool fCompleted= false; + + /** + * The listener to be notified when a delayed location changing event happened. + * @since 3.4 + */ + private IInputChangedListener fDelayedInputChangeListener; + + /** + * The listeners to be notified when the input changed. + * @since 3.4 + */ + private ListenerList/**/ fInputChangeListeners= new ListenerList(ListenerList.IDENTITY); + + /** + * The symbolic name of the font used for size computations, or null to use dialog font. + * @since 3.4 + */ + private const String fSymbolicFontName; + + + /** + * Creates a browser information control with the given shell as parent. + * + * @param parent the parent shell + * @param symbolicFontName the symbolic name of the font used for size computations + * @param resizable true if the control should be resizable + * @since 3.4 + */ + public this(Shell parent, String symbolicFontName, bool resizable) { + super(parent, resizable); + fSymbolicFontName= symbolicFontName; + create(); + } + + /** + * Creates a browser information control with the given shell as parent. + * + * @param parent the parent shell + * @param symbolicFontName the symbolic name of the font used for size computations + * @param statusFieldText the text to be used in the optional status field + * or null if the status field should be hidden + * @since 3.4 + */ + public this(Shell parent, String symbolicFontName, String statusFieldText) { + super(parent, statusFieldText); + fSymbolicFontName= symbolicFontName; + create(); + } + + /** + * Creates a browser information control with the given shell as parent. + * + * @param parent the parent shell + * @param symbolicFontName the symbolic name of the font used for size computations + * @param toolBarManager the manager or null if toolbar is not desired + * @since 3.4 + */ + public this(Shell parent, String symbolicFontName, ToolBarManager toolBarManager) { + super(parent, toolBarManager); + fSymbolicFontName= symbolicFontName; + create(); + } + + /* + * @see dwtx.jface.text.AbstractInformationControl#createContent(dwt.widgets.Composite) + */ + protected void createContent(Composite parent) { + fBrowser= new Browser(parent, DWT.NONE); + + Display display= getShell().getDisplay(); + fBrowser.setForeground(display.getSystemColor(DWT.COLOR_INFO_FOREGROUND)); + fBrowser.setBackground(display.getSystemColor(DWT.COLOR_INFO_BACKGROUND)); + fBrowser.addKeyListener(new class() KeyListener { + + public void keyPressed(KeyEvent e) { + if (e.character is 0x1B) // ESC + getShell().dispose(); // XXX: Just hide? Would avoid constant recreations. + } + + public void keyReleased(KeyEvent e) {} + }); + + fBrowser.addProgressListener(new class() ProgressAdapter { + public void completed(ProgressEvent event) { + fCompleted= true; + } + }); + + // Replace browser's built-in context menu with none + fBrowser.setMenu(new Menu(getShell(), DWT.NONE)); + + createTextLayout(); + } + + /** + * {@inheritDoc} + * @deprecated use {@link #setInput(Object)} + */ + public void setInformation(String content) { + setInput(new class(null,content) BrowserInformationControlInput { + String content_; + this(BrowserInformationControlInput input, String a){ + super(input); + content_=a; + } + public String getHtml() { + return content_; + } + + public String getInputName() { + return ""; //$NON-NLS-1$ + } + + public Object getInputElement() { + return stringcast(content_); + } + }); + } + + /** + * {@inheritDoc} This control can handle {@link String} and + * {@link BrowserInformationControlInput}. + */ + public void setInput(Object input) { + Assert.isLegal(input is null || cast(String)input || cast(BrowserInformationControlInput)input ); + + if ( cast(String)input ) { + setInformation(cast(String)input); + return; + } + + fInput= cast(BrowserInformationControlInput)input; + + String content= null; + if (fInput !is null) + content= fInput.getHtml(); + + fBrowserHasContent= content !is null && content.length() > 0; + + if (!fBrowserHasContent) + content= ""; //$NON-NLS-1$ + + bool RTL= (getShell().getStyle() & DWT.RIGHT_TO_LEFT) !is 0; + bool resizable= isResizable(); + + // The default "overflow:auto" would not result in a predictable width for the client area + // and the re-wrapping would cause visual noise + String[] styles= null; + if (RTL && resizable) + styles= [ "direction:rtl;", "overflow:scroll;", "word-wrap:break-word;" ]; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + else if (RTL && !resizable) + styles= [ "direction:rtl;", "overflow:hidden;", "word-wrap:break-word;" ]; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + else if (!resizable) + //XXX: In IE, "word-wrap: break-word;" causes bogus wrapping even in non-broken words :-(see e.g. Javadoc of String). + // Re-check whether we really still need this now that the Javadoc Hover header already sets this style. + styles= [ "overflow:hidden;"/*, "word-wrap: break-word;"*/ ]; //$NON-NLS-1$ + else + styles= [ "overflow:scroll;" ]; //$NON-NLS-1$ + + StringBuffer buffer= new StringBuffer(content); + HTMLPrinter.insertStyles(buffer, styles); + content= buffer.toString(); + + /* + * XXX: Should add some JavaScript here that shows something like + * "(continued...)" or "..." at the end of the visible area when the page overflowed + * with "overflow:hidden;". + */ + + fCompleted= false; + fBrowser.setText(content); + + Object[] listeners= fInputChangeListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) + (cast(IInputChangedListener)listeners[i]).inputChanged(fInput); + } + + /* + * @see IInformationControl#setVisible(bool) + */ + public void setVisible(bool visible) { + Shell shell= getShell(); + if (shell.isVisible() is visible) + return; + + if (!visible) { + super.setVisible(false); + setInput(null); + return; + } + + /* + * The Browser widget flickers when made visible while it is not completely loaded. + * The fix is to delay the call to setVisible until either loading is completed + * (see ProgressListener in constructor), or a timeout has been reached. + */ + final Display display= shell.getDisplay(); + + // Make sure the display wakes from sleep after timeout: + display.timerExec(100, new class() Runnable { + public void run() { + fCompleted= true; + } + }); + + while (!fCompleted) { + // Drive the event loop to process the events required to load the browser widget's contents: + if (!display.readAndDispatch()) { + display.sleep(); + } + } + + shell= getShell(); + if (shell is null || shell.isDisposed()) + return; + + /* + * Avoids flickering when replacing hovers, especially on Vista in ON_CLICK mode. + * Causes flickering on GTK. Carbon does not care. + */ + if ("win32".equals(DWT.getPlatform())) //$NON-NLS-1$ + shell.moveAbove(null); + + super.setVisible(true); + } + + /* + * @see dwtx.jface.text.AbstractInformationControl#setSize(int, int) + */ + public void setSize(int width, int height) { + fBrowser.setRedraw(false); // avoid flickering + try { + super.setSize(width, height); + } finally { + fBrowser.setRedraw(true); + } + } + + /** + * Creates and initializes the text layout used + * to compute the size hint. + * + * @since 3.2 + */ + private void createTextLayout() { + fTextLayout= new TextLayout(fBrowser.getDisplay()); + + // Initialize fonts + Font font= fSymbolicFontName is null ? JFaceResources.getDialogFont() : JFaceResources.getFont(fSymbolicFontName); + fTextLayout.setFont(font); + fTextLayout.setWidth(-1); + FontData[] fontData= font.getFontData(); + for (int i= 0; i < fontData.length; i++) + fontData[i].setStyle(DWT.BOLD); + font= new Font(getShell().getDisplay(), fontData); + fBoldStyle= new TextStyle(font, null, null); + + // Compute and set tab width + fTextLayout.setText(" "); //$NON-NLS-1$ + int tabWidth = fTextLayout.getBounds().width; + fTextLayout.setTabs([tabWidth]); + + fTextLayout.setText(""); //$NON-NLS-1$ + } + + /* + * @see IInformationControl#dispose() + */ + public void dispose() { + if (fTextLayout !is null) { + fTextLayout.dispose(); + fTextLayout= null; + } + if (fBoldStyle !is null) { + fBoldStyle.font.dispose(); + fBoldStyle= null; + } + fBrowser= null; + + super.dispose(); + } + + /* + * @see IInformationControl#computeSizeHint() + */ + public Point computeSizeHint() { + Point sizeConstraints= getSizeConstraints(); + Rectangle trim= computeTrim(); + int height= trim.height; + + //FIXME: The HTML2TextReader does not render

    like a browser. + // Instead of inserting an empty line, it just adds a single line break. + // Furthermore, the indentation of

    elements is too small (e.g with a long @see line) + TextPresentation presentation= new TextPresentation(); + HTML2TextReader reader= new HTML2TextReader(new StringReader(fInput.getHtml()), presentation); + String text; + try { + text= reader.getString(); + } catch (IOException e) { + text= ""; //$NON-NLS-1$ + } + + fTextLayout.setText(text); + fTextLayout.setWidth(sizeConstraints is null ? DWT.DEFAULT : sizeConstraints.x - trim.width); + Iterator iter= presentation.getAllStyleRangeIterator(); + while (iter.hasNext()) { + StyleRange sr= cast(StyleRange)iter.next(); + if (sr.fontStyle is DWT.BOLD) + fTextLayout.setStyle(fBoldStyle, sr.start, sr.start + sr.length - 1); + } + + Rectangle bounds= fTextLayout.getBounds(); // does not return minimum width, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=217446 + int lineCount= fTextLayout.getLineCount(); + int textWidth= 0; + for (int i= 0; i < lineCount; i++) { + Rectangle rect= fTextLayout.getLineBounds(i); + int lineWidth= rect.x + rect.width; + if (i is 0) + lineWidth += fInput.getLeadingImageWidth(); + textWidth= Math.max(textWidth, lineWidth); + } + bounds.width= textWidth; + fTextLayout.setText(""); //$NON-NLS-1$ + + int minWidth= bounds.width; + height= height + bounds.height; + + // Add some air to accommodate for different browser renderings + minWidth+= 15; + height+= 15; + + + // Apply max size constraints + if (sizeConstraints !is null) { + if (sizeConstraints.x !is DWT.DEFAULT) + minWidth= Math.min(sizeConstraints.x, minWidth + trim.width); + if (sizeConstraints.y !is DWT.DEFAULT) + height= Math.min(sizeConstraints.y, height); + } + + // Ensure minimal size + int width= Math.max(MIN_WIDTH, minWidth); + height= Math.max(MIN_HEIGHT, height); + + return new Point(width, height); + } + + /* + * @see dwtx.jface.text.IInformationControlExtension3#computeTrim() + */ + public Rectangle computeTrim() { + Rectangle trim= super.computeTrim(); + if (isResizable()) { + bool RTL= (getShell().getStyle() & DWT.RIGHT_TO_LEFT) !is 0; + if (RTL) { + trim.x-= fgScrollBarSize.x; + } + trim.width+= fgScrollBarSize.x; + trim.height+= fgScrollBarSize.y; + } + return trim; + } + + /** + * Adds the listener to the collection of listeners who will be + * notified when the current location has changed or is about to change. + * + * @param listener the location listener + * @since 3.4 + */ + public void addLocationListener(LocationListener listener) { + fBrowser.addLocationListener(listener); + } + + /* + * @see IInformationControl#setForegroundColor(Color) + */ + public void setForegroundColor(Color foreground) { + super.setForegroundColor(foreground); + fBrowser.setForeground(foreground); + } + + /* + * @see IInformationControl#setBackgroundColor(Color) + */ + public void setBackgroundColor(Color background) { + super.setBackgroundColor(background); + fBrowser.setBackground(background); + } + + /* + * @see IInformationControlExtension#hasContents() + */ + public bool hasContents() { + return fBrowserHasContent; + } + + /** + * Adds a listener for input changes to this input change provider. + * Has no effect if an identical listener is already registered. + * + * @param inputChangeListener the listener to add + * @since 3.4 + */ + public void addInputChangeListener(IInputChangedListener inputChangeListener) { + Assert.isNotNull(inputChangeListener); + fInputChangeListeners.add(inputChangeListener); + } + + /** + * Removes the given input change listener from this input change provider. + * Has no effect if an identical listener is not registered. + * + * @param inputChangeListener the listener to remove + * @since 3.4 + */ + public void removeInputChangeListener(IInputChangedListener inputChangeListener) { + fInputChangeListeners.remove(inputChangeListener); + } + + /* + * @see dwtx.jface.text.IDelayedInputChangeProvider#setDelayedInputChangeListener(dwtx.jface.text.IInputChangedListener) + * @since 3.4 + */ + public void setDelayedInputChangeListener(IInputChangedListener inputChangeListener) { + fDelayedInputChangeListener= inputChangeListener; + } + + /** + * Tells whether a delayed input change listener is registered. + * + * @return true iff a delayed input change + * listener is currently registered + * @since 3.4 + */ + public bool hasDelayedInputChangeListener() { + return fDelayedInputChangeListener !is null; + } + + /** + * Notifies listeners of a delayed input change. + * + * @param newInput the new input, or null to request cancellation + * @since 3.4 + */ + public void notifyDelayedInputChange(Object newInput) { + if (fDelayedInputChangeListener !is null) + fDelayedInputChangeListener.inputChanged(newInput); + } + + /* + * @see java.lang.Object#toString() + * @since 3.4 + */ + public override String toString() { + String style= (getShell().getStyle() & DWT.RESIZE) is 0 ? "fixed" : "resizeable"; //$NON-NLS-1$ //$NON-NLS-2$ + return super.toString() + " - style: " + style; //$NON-NLS-1$ + } + + /** + * @return the current browser input or null + */ + public BrowserInformationControlInput getInput() { + return fInput; + } + + /* + * @see dwtx.jface.text.IInformationControlExtension5#computeSizeConstraints(int, int) + */ + public Point computeSizeConstraints(int widthInChars, int heightInChars) { + if (fSymbolicFontName is null) + return null; + + GC gc= new GC(fBrowser); + Font font= fSymbolicFontName is null ? JFaceResources.getDialogFont() : JFaceResources.getFont(fSymbolicFontName); + gc.setFont(font); + int width= gc.getFontMetrics().getAverageCharWidth(); + int height= gc.getFontMetrics().getHeight(); + gc.dispose(); + + return new Point(widthInChars * width, heightInChars * height); + } + +} + +++/ diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/html/BrowserInformationControlInput.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/html/BrowserInformationControlInput.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,71 @@ +/******************************************************************************* + * 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.text.html.BrowserInformationControlInput; + +import dwtx.jface.internal.text.html.HTML2TextReader; // packageimport +import dwtx.jface.internal.text.html.HTMLPrinter; // packageimport +import dwtx.jface.internal.text.html.BrowserInformationControl; // packageimport +import dwtx.jface.internal.text.html.SubstitutionTextReader; // packageimport +import dwtx.jface.internal.text.html.HTMLTextPresenter; // packageimport +import dwtx.jface.internal.text.html.BrowserInput; // packageimport +import dwtx.jface.internal.text.html.SingleCharReader; // packageimport +import dwtx.jface.internal.text.html.HTMLMessages; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.DefaultInformationControl; + + +/** + * Provides input for a {@link BrowserInformationControl}. + * + * @since 3.4 + */ +public abstract class BrowserInformationControlInput : BrowserInput { + + /** + * Returns the leading image width. + * + * @return the size of the leading image, by default 0 is returned + * @since 3.4 + */ + public int getLeadingImageWidth() { + return 0; + } + + /** + * Creates the next browser input with the given input as previous one. + * + * @param previous the previous input or null if none + */ + public this(BrowserInformationControlInput previous) { + super(previous); + } + + /** + * @return the HTML contents + */ + public abstract String getHtml(); + + /** + * Returns the HTML from {@link #getHtml()}. + * This is a fallback mode for platforms where the {@link BrowserInformationControl} + * is not available and this input is passed to a {@link DefaultInformationControl}. + * + * @return {@link #getHtml()} + */ + public override String toString() { + return getHtml(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/html/BrowserInput.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/html/BrowserInput.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,86 @@ +/******************************************************************************* + * 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.text.html.BrowserInput; + +import dwtx.jface.internal.text.html.HTML2TextReader; // packageimport +import dwtx.jface.internal.text.html.HTMLPrinter; // packageimport +import dwtx.jface.internal.text.html.BrowserInformationControl; // packageimport +import dwtx.jface.internal.text.html.SubstitutionTextReader; // packageimport +import dwtx.jface.internal.text.html.HTMLTextPresenter; // packageimport +import dwtx.jface.internal.text.html.SingleCharReader; // packageimport +import dwtx.jface.internal.text.html.BrowserInformationControlInput; // packageimport +import dwtx.jface.internal.text.html.HTMLMessages; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * A browser input contains an input element and + * a previous and a next input, if available. + * + * The browser input also provides a human readable + * name of its input element. + * + * @since 3.4 + */ +public abstract class BrowserInput { + + private const BrowserInput fPrevious; + private BrowserInput fNext; + + /** + * Create a new Browser input. + * + * @param previous the input previous to this or null if this is the first + */ + public this(BrowserInput previous) { + fPrevious= previous; + if (previous !is null) + previous.fNext= this; + } + + /** + * The previous input or null if this + * is the first. + * + * @return the previous input or null + */ + public BrowserInput getPrevious() { + return fPrevious; + } + + /** + * The next input or null if this + * is the last. + * + * @return the next input or null + */ + public BrowserInput getNext() { + return fNext; + } + + /** + * The element to use to set the browsers input. + * + * @return the input element + */ + public abstract Object getInputElement(); + + /** + * A human readable name for the input. + * + * @return the input name + */ + public abstract String getInputName(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/html/HTML2TextReader.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/html/HTML2TextReader.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,344 @@ +/******************************************************************************* + * 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 + * 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.text.html.HTML2TextReader; + +import dwtx.jface.internal.text.html.HTMLPrinter; // packageimport +import dwtx.jface.internal.text.html.BrowserInformationControl; // packageimport +import dwtx.jface.internal.text.html.SubstitutionTextReader; // packageimport +import dwtx.jface.internal.text.html.HTMLTextPresenter; // packageimport +import dwtx.jface.internal.text.html.BrowserInput; // packageimport +import dwtx.jface.internal.text.html.SingleCharReader; // packageimport +import dwtx.jface.internal.text.html.BrowserInformationControlInput; // packageimport +import dwtx.jface.internal.text.html.HTMLMessages; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.PushbackReader; +import dwtx.dwtxhelper.Collection; +static import tango.text.convert.Utf; + +import dwt.DWT; +import dwt.custom.StyleRange; +import dwtx.jface.text.TextPresentation; + + +/** + * Reads the text contents from a reader of HTML contents and translates + * the tags or cut them out. + *

    + * Moved into this package from dwtx.jface.internal.text.revisions.

    + */ +public class HTML2TextReader : SubstitutionTextReader { + + private static const String EMPTY_STRING= ""; //$NON-NLS-1$ + private static const Map fgEntityLookup; + private static const Set fgTags; + + static this() { + + fgTags= new HashSet(); + fgTags.add("b"); //$NON-NLS-1$ + fgTags.add("br"); //$NON-NLS-1$ + fgTags.add("br/"); //$NON-NLS-1$ + fgTags.add("div"); //$NON-NLS-1$ + fgTags.add("h1"); //$NON-NLS-1$ + fgTags.add("h2"); //$NON-NLS-1$ + fgTags.add("h3"); //$NON-NLS-1$ + fgTags.add("h4"); //$NON-NLS-1$ + fgTags.add("h5"); //$NON-NLS-1$ + fgTags.add("p"); //$NON-NLS-1$ + fgTags.add("dl"); //$NON-NLS-1$ + fgTags.add("dt"); //$NON-NLS-1$ + fgTags.add("dd"); //$NON-NLS-1$ + fgTags.add("li"); //$NON-NLS-1$ + fgTags.add("ul"); //$NON-NLS-1$ + fgTags.add("pre"); //$NON-NLS-1$ + fgTags.add("head"); //$NON-NLS-1$ + + fgEntityLookup= new HashMap(7); + fgEntityLookup.put("lt", "<"); //$NON-NLS-1$ //$NON-NLS-2$ + fgEntityLookup.put("gt", ">"); //$NON-NLS-1$ //$NON-NLS-2$ + fgEntityLookup.put("nbsp", " "); //$NON-NLS-1$ //$NON-NLS-2$ + fgEntityLookup.put("amp", "&"); //$NON-NLS-1$ //$NON-NLS-2$ + fgEntityLookup.put("circ", "^"); //$NON-NLS-1$ //$NON-NLS-2$ + fgEntityLookup.put("tilde", "~"); //$NON-NLS-2$ //$NON-NLS-1$ + fgEntityLookup.put("quot", "\""); //$NON-NLS-1$ //$NON-NLS-2$ + } + + private int fCounter= 0; + private TextPresentation fTextPresentation; + private int fBold= 0; + private int fStartOffset= -1; + private bool fInParagraph= false; + private bool fIsPreformattedText= false; + private bool fIgnore= false; + private bool fHeaderDetected= false; + + /** + * Transforms the HTML text from the reader to formatted text. + * + * @param reader the reader + * @param presentation If not null, formattings will be applied to + * the presentation. + */ + public this(Reader reader, TextPresentation presentation) { + super(new PushbackReader(reader)); + fTextPresentation= presentation; + } + + public int read() { + int c= super.read(); + if (c !is -1) + ++ fCounter; + return c; + } + + protected void startBold() { + if (fBold is 0) + fStartOffset= fCounter; + ++ fBold; + } + + protected void startPreformattedText() { + fIsPreformattedText= true; + setSkipWhitespace(false); + } + + protected void stopPreformattedText() { + fIsPreformattedText= false; + setSkipWhitespace(true); + } + + protected void stopBold() { + -- fBold; + if (fBold is 0) { + if (fTextPresentation !is null) { + fTextPresentation.addStyleRange(new StyleRange(fStartOffset, fCounter - fStartOffset, null, null, DWT.BOLD)); + } + fStartOffset= -1; + } + } + + /* + * @see dwtx.jdt.internal.ui.text.SubstitutionTextReader#computeSubstitution(int) + */ + protected String computeSubstitution(int c) { + + if (c is '<') + return processHTMLTag(); + else if (fIgnore) + return EMPTY_STRING; + else if (c is '&') + return processEntity(); + else if (fIsPreformattedText) + return processPreformattedText(c); + + return null; + } + + private String html2Text(String html) { + + if (html is null || html.length() is 0) + return EMPTY_STRING; + + html= html.toLowerCase(); + + String tag= html; + if ('/' is tag.charAt(0)) + tag= tag.substring(1); + + if (!fgTags.contains(tag)) + return EMPTY_STRING; + + + if ("pre".equals(html)) { //$NON-NLS-1$ + startPreformattedText(); + return EMPTY_STRING; + } + + if ("/pre".equals(html)) { //$NON-NLS-1$ + stopPreformattedText(); + return EMPTY_STRING; + } + + if (fIsPreformattedText) + return EMPTY_STRING; + + if ("b".equals(html)) { //$NON-NLS-1$ + startBold(); + return EMPTY_STRING; + } + + if ((html.length() > 1 && html.charAt(0) is 'h' && Character.isDigit(html.charAt(1))) || "dt".equals(html)) { //$NON-NLS-1$ + startBold(); + return EMPTY_STRING; + } + + if ("dl".equals(html)) //$NON-NLS-1$ + return LINE_DELIM; + + if ("dd".equals(html)) //$NON-NLS-1$ + return "\t"; //$NON-NLS-1$ + + if ("li".equals(html)) //$NON-NLS-1$ + // FIXME: this hard-coded prefix does not work for RTL languages, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=91682 + return LINE_DELIM ~ HTMLMessages.getString("HTML2TextReader.listItemPrefix"); //$NON-NLS-1$ + + if ("/b".equals(html)) { //$NON-NLS-1$ + stopBold(); + return EMPTY_STRING; + } + + if ("p".equals(html)) { //$NON-NLS-1$ + fInParagraph= true; + return LINE_DELIM; + } + + if ("br".equals(html) || "br/".equals(html) || "div".equals(html)) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + return LINE_DELIM; + + if ("/p".equals(html)) { //$NON-NLS-1$ + bool inParagraph= fInParagraph; + fInParagraph= false; + return inParagraph ? EMPTY_STRING : LINE_DELIM; + } + + if ((html.startsWith("/h") && html.length() > 2 && Character.isDigit(html.charAt(2))) || "/dt".equals(html)) { //$NON-NLS-1$ //$NON-NLS-2$ + stopBold(); + return LINE_DELIM; + } + + if ("/dd".equals(html)) //$NON-NLS-1$ + return LINE_DELIM; + + if ("head".equals(html) && !fHeaderDetected) { //$NON-NLS-1$ + fHeaderDetected= true; + fIgnore= true; + return EMPTY_STRING; + } + + if ("/head".equals(html) && fHeaderDetected && fIgnore) { //$NON-NLS-1$ + fIgnore= false; + return EMPTY_STRING; + } + + return EMPTY_STRING; + } + + /* + * A '<' has been read. Process a html tag + */ + private String processHTMLTag() { + + StringBuffer buf= new StringBuffer(); + int ch; + do { + + ch= nextDChar(); + + while (ch !is -1 && ch !is '>') { + buf.append(dcharToString(Character.toLowerCase(cast(dchar) ch))); + ch= nextDChar(); + if (ch is '"'){ + buf.append(dcharToString(Character.toLowerCase(cast(dchar) ch))); + ch= nextDChar(); + while (ch !is -1 && ch !is '"'){ + buf.append(dcharToString(Character.toLowerCase(cast(dchar) ch))); + ch= nextDChar(); + } + } + if (ch is '<' && !isInComment(buf)) { + unreadDChar(ch); + return '<' ~ buf.toString(); + } + } + + if (ch is -1) + return null; + + if (!isInComment(buf) || isCommentEnd(buf)) { + break; + } + // unfinished comment + buf.append(dcharToString(cast(dchar) ch)); + } while (true); + + return html2Text(buf.toString()); + } + + private static bool isInComment(StringBuffer buf) { + return buf.length() >= 3 && "!--".equals(buf.slice().substring(0, 3)); //$NON-NLS-1$ + } + + private static bool isCommentEnd(StringBuffer buf) { + int tagLen= buf.length(); + return tagLen >= 5 && "--".equals(buf.slice().substring(tagLen - 2)); //$NON-NLS-1$ + } + + private String processPreformattedText(int c) { + if (c is '\r' || c is '\n') + fCounter++; + return null; + } + + + private void unreadDChar(dchar ch) { + char[4] buf; + dchar[1] ibuf; + ibuf[0] = ch; + foreach( char c; tango.text.convert.Utf.toString( ibuf[], buf[] )){ + (cast(PushbackReader) getReader()).unread(c); + } + } + + protected String entity2Text(String symbol) { + if (symbol.length() > 1 && symbol.charAt(0) is '#') { + int ch; + try { + if (symbol.charAt(1) is 'x') { + ch= Integer.parseInt(symbol.substring(2), 16); + } else { + ch= Integer.parseInt(symbol.substring(1), 10); + } + return dcharToString( cast(dchar)ch); + } catch (NumberFormatException e) { + } + } else { + String str= stringcast( fgEntityLookup.get(symbol)); + if (str !is null) { + return str; + } + } + return "&" ~ symbol; // not found //$NON-NLS-1$ + } + + /* + * A '&' has been read. Process a entity + */ + private String processEntity() { + StringBuffer buf= new StringBuffer(); + int ch= nextDChar(); + while (Character.isLetterOrDigit(cast(dchar)ch) || ch is '#') { + buf.append(dcharToString(cast(dchar) ch)); + ch= nextDChar(); + } + + if (ch is ';') + return entity2Text(buf.toString()); + + buf.select(0, 0); + buf.prepend("&"); + if (ch !is -1) + buf.append(dcharToString(cast(dchar) ch)); + return buf.toString(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/html/HTMLMessages.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/html/HTMLMessages.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,81 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.internal.text.html.HTMLMessages; + +import dwtx.jface.internal.text.html.HTML2TextReader; // packageimport +import dwtx.jface.internal.text.html.HTMLPrinter; // packageimport +import dwtx.jface.internal.text.html.BrowserInformationControl; // packageimport +import dwtx.jface.internal.text.html.SubstitutionTextReader; // packageimport +import dwtx.jface.internal.text.html.HTMLTextPresenter; // packageimport +import dwtx.jface.internal.text.html.BrowserInput; // packageimport +import dwtx.jface.internal.text.html.SingleCharReader; // packageimport +import dwtx.jface.internal.text.html.BrowserInformationControlInput; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.dwthelper.ResourceBundle; +import dwtx.dwtxhelper.MessageFormat; + + +/** + * Helper class to get NLSed messages. + * + * @since 3.3 + */ +class HTMLMessages { + +// private static const String RESOURCE_BUNDLE= HTMLMessages.classinfo.getName(); + + private static ResourceBundle fgResourceBundle;//= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + static this() { + fgResourceBundle = ResourceBundle.getBundle( + getImportData!("dwtx.jface.internal.text.html.HTMLMessages.properties")); + } + + private this() { + } + + /** + * Gets a string from the resource bundle. + * + * @param key the string used to get the bundle value, must not be null + * @return the string from the resource bundle + */ + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" ~ key ~ "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + } + + /** + * Gets a string from the resource bundle and formats it with the given arguments. + * + * @param key the string used to get the bundle value, must not be null + * @param args the arguments used to format the string + * @return the formatted string + */ + public static String getFormattedString(String key, Object[] args...) { + String format= null; + try { + format= fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" ~ key ~ "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + return MessageFormat.format(format, args); + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/html/HTMLPrinter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/html/HTMLPrinter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,317 @@ +/******************************************************************************* + * 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 + * 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.text.html.HTMLPrinter; + +import dwtx.jface.internal.text.html.HTML2TextReader; // packageimport +import dwtx.jface.internal.text.html.BrowserInformationControl; // packageimport +import dwtx.jface.internal.text.html.SubstitutionTextReader; // packageimport +import dwtx.jface.internal.text.html.HTMLTextPresenter; // packageimport +import dwtx.jface.internal.text.html.BrowserInput; // packageimport +import dwtx.jface.internal.text.html.SingleCharReader; // packageimport +import dwtx.jface.internal.text.html.BrowserInformationControlInput; // packageimport +import dwtx.jface.internal.text.html.HTMLMessages; // packageimport + + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.URL; + +import dwt.DWT; +import dwt.DWTError; +import dwt.graphics.FontData; +import dwt.graphics.RGB; +import dwt.widgets.Display; + + +/** + * Provides a set of convenience methods for creating HTML pages. + *

    + * Moved into this package from dwtx.jface.internal.text.revisions.

    + */ +public class HTMLPrinter { + + private static RGB BG_COLOR_RGB_; + private static RGB FG_COLOR_RGB_; + + private static RGB BG_COLOR_RGB(){ + COLOR_RGB_init(); + return BG_COLOR_RGB_; + } + private static RGB FG_COLOR_RGB(){ + COLOR_RGB_init(); + return FG_COLOR_RGB_; + } + + private static bool COLOR_RGB_init_complete = false; + private static void COLOR_RGB_init() { + if( COLOR_RGB_init_complete ){ + return; + } + COLOR_RGB_init_complete = true; + BG_COLOR_RGB_= new RGB(255, 255, 225); // RGB value of info bg color on WindowsXP + FG_COLOR_RGB_= new RGB(0, 0, 0); // RGB value of info fg color on WindowsXP + Display display= Display.getDefault(); + if (display !is null && !display.isDisposed()) { + try { + display.asyncExec( dgRunnable( (Display display_){ + BG_COLOR_RGB_= display_.getSystemColor(DWT.COLOR_INFO_BACKGROUND).getRGB(); + FG_COLOR_RGB_= display_.getSystemColor(DWT.COLOR_INFO_FOREGROUND).getRGB(); + }, display )); + } catch (DWTError err) { + // see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=45294 + if (err.code !is DWT.ERROR_DEVICE_DISPOSED) + throw err; + } + } + } + + private this() { + } + + private static String replace(String text, char c, String s) { + + int previous= 0; + int current= text.indexOf(c, previous); + + if (current is -1) + return text; + + StringBuffer buffer= new StringBuffer(); + while (current > -1) { + buffer.append(text.substring(previous, current)); + buffer.append(s); + previous= current + 1; + current= text.indexOf(c, previous); + } + buffer.append(text.substring(previous)); + + return buffer.toString(); + } + + public static String convertToHTMLContent(String content) { + content= replace(content, '&', "&"); //$NON-NLS-1$ + content= replace(content, '"', """); //$NON-NLS-1$ + content= replace(content, '<', "<"); //$NON-NLS-1$ + return replace(content, '>', ">"); //$NON-NLS-1$ + } + + public static String read(Reader rd) { + + StringBuffer buffer= new StringBuffer(); + char[] readBuffer= new char[2048]; + + try { + int n= rd.read(readBuffer); + while (n > 0) { + buffer.append(readBuffer[ 0 .. n ]); + n= rd.read(readBuffer); + } + return buffer.toString(); + } catch (IOException x) { + } + + return null; + } + + public static void insertPageProlog(StringBuffer buffer, int position, RGB fgRGB, RGB bgRGB, String styleSheet) { + if (fgRGB is null) + fgRGB= FG_COLOR_RGB; + if (bgRGB is null) + bgRGB= BG_COLOR_RGB; + + StringBuffer pageProlog= new StringBuffer(300); + + pageProlog.append(""); //$NON-NLS-1$ + + appendStyleSheetURL(pageProlog, styleSheet); + + appendColors(pageProlog, fgRGB, bgRGB); + + buffer.select(position,0); + buffer.replace(pageProlog.toString()); + } + + private static void appendColors(StringBuffer pageProlog, RGB fgRGB, RGB bgRGB) { + pageProlog.append(""); //$NON-NLS-1$ + } + + private static void appendColor(StringBuffer buffer, RGB rgb) { + buffer.append('#'); + appendAsHexString(buffer, rgb.red); + appendAsHexString(buffer, rgb.green); + appendAsHexString(buffer, rgb.blue); + } + + private static void appendAsHexString(StringBuffer buffer, int intValue) { + String hexValue= Integer.toHexString(intValue); + if (hexValue.length() is 1) + buffer.append('0'); + buffer.append(hexValue); + } + + public static void insertStyles(StringBuffer buffer, String[] styles) { + if (styles is null || styles.length is 0) + return; + + StringBuffer styleBuf= new StringBuffer(10 * styles.length); + for (int i= 0; styles !is null && i < styles.length; i++) { + styleBuf.append(" style=\""); //$NON-NLS-1$ + styleBuf.append(styles[i]); + styleBuf.append('"'); + } + + // Find insertion index + // a) within existing body tag with trailing space + int index= buffer.slice().indexOf(""); //$NON-NLS-1$ + if (index !is -1) { + buffer.select(index+5, 0); + buffer.replace( " " ); + buffer.select(index+6, 0); + buffer.replace(styleBuf); + return; + } + } + + private static void appendStyleSheetURL(StringBuffer buffer, String styleSheet) { + if (styleSheet is null) + return; + + buffer.append(""); //$NON-NLS-1$ + } + + private static void appendStyleSheetURL(StringBuffer buffer, URL styleSheetURL) { + if (styleSheetURL is null) + return; + + buffer.append(""); //$NON-NLS-1$ + + buffer.append(""); //$NON-NLS-1$ + + buffer.append(""); //$NON-NLS-1$ + } + + public static void insertPageProlog(StringBuffer buffer, int position) { + StringBuffer pageProlog= new StringBuffer(60); + pageProlog.append(""); //$NON-NLS-1$ + appendColors(pageProlog, FG_COLOR_RGB, BG_COLOR_RGB); + buffer.select(position, 0); + buffer.replace(pageProlog.toString()); + } + + public static void insertPageProlog(StringBuffer buffer, int position, URL styleSheetURL) { + StringBuffer pageProlog= new StringBuffer(300); + pageProlog.append(""); //$NON-NLS-1$ + appendStyleSheetURL(pageProlog, styleSheetURL); + appendColors(pageProlog, FG_COLOR_RGB, BG_COLOR_RGB); + buffer.select(position, 0); + buffer.replace(pageProlog.toString()); + } + + public static void insertPageProlog(StringBuffer buffer, int position, String styleSheet) { + insertPageProlog(buffer, position, null, null, styleSheet); + } + + public static void addPageProlog(StringBuffer buffer) { + insertPageProlog(buffer, buffer.length()); + } + + public static void addPageEpilog(StringBuffer buffer) { + buffer.append(""); //$NON-NLS-1$ + } + + public static void startBulletList(StringBuffer buffer) { + buffer.append("
      "); //$NON-NLS-1$ + } + + public static void endBulletList(StringBuffer buffer) { + buffer.append("
    "); //$NON-NLS-1$ + } + + public static void addBullet(StringBuffer buffer, String bullet) { + if (bullet !is null) { + buffer.append("
  • "); //$NON-NLS-1$ + buffer.append(bullet); + buffer.append("
  • "); //$NON-NLS-1$ + } + } + + public static void addSmallHeader(StringBuffer buffer, String header) { + if (header !is null) { + buffer.append("
    "); //$NON-NLS-1$ + buffer.append(header); + buffer.append("
    "); //$NON-NLS-1$ + } + } + + public static void addParagraph(StringBuffer buffer, String paragraph) { + if (paragraph !is null) { + buffer.append("

    "); //$NON-NLS-1$ + buffer.append(paragraph); + } + } + + public static void addParagraph(StringBuffer buffer, Reader paragraphReader) { + if (paragraphReader !is null) + addParagraph(buffer, read(paragraphReader)); + } + + /** + * Replaces the following style attributes of the font definition of the html + * element: + *

      + *
    • font-size
    • + *
    • font-weight
    • + *
    • font-style
    • + *
    • font-family
    • + *
    + * The font's name is used as font family, a sans-serif default font family is + * appended for the case that the given font name is not available. + *

    + * If the listed font attributes are not contained in the passed style list, nothing happens. + *

    + * + * @param styles CSS style definitions + * @param fontData the font information to use + * @return the modified style definitions + * @since 3.3 + */ + public static String convertTopLevelFont(String styles, FontData fontData) { + bool bold= (fontData.getStyle() & DWT.BOLD) !is 0; + bool italic= (fontData.getStyle() & DWT.ITALIC) !is 0; + + // See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=155993 + String size= Integer.toString(fontData.getHeight()) ~ ("carbon".equals(DWT.getPlatform()) ? "px" : "pt"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + String family= "'" ~ fontData.getName() ~ "',sans-serif"; //$NON-NLS-1$ //$NON-NLS-2$ + styles= styles.replaceFirst("(html\\s*\\{.*(?:\\s|;)font-size:\\s*)\\d+pt(\\;?.*\\})", "$1" ~ size ~ "$2"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + styles= styles.replaceFirst("(html\\s*\\{.*(?:\\s|;)font-weight:\\s*)\\w+(\\;?.*\\})", "$1" ~ (bold ? "bold" : "normal") ~ "$2"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + styles= styles.replaceFirst("(html\\s*\\{.*(?:\\s|;)font-style:\\s*)\\w+(\\;?.*\\})", "$1" ~ (italic ? "italic" : "normal") ~ "$2"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + styles= styles.replaceFirst("(html\\s*\\{.*(?:\\s|;)font-family:\\s*).+?(;.*\\})", "$1" ~ family ~ "$2"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + return styles; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/html/HTMLTextPresenter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/html/HTMLTextPresenter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,224 @@ +/******************************************************************************* + * 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 + * 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.text.html.HTMLTextPresenter; + +import dwtx.jface.internal.text.html.HTML2TextReader; // packageimport +import dwtx.jface.internal.text.html.HTMLPrinter; // packageimport +import dwtx.jface.internal.text.html.BrowserInformationControl; // packageimport +import dwtx.jface.internal.text.html.SubstitutionTextReader; // packageimport +import dwtx.jface.internal.text.html.BrowserInput; // packageimport +import dwtx.jface.internal.text.html.SingleCharReader; // packageimport +import dwtx.jface.internal.text.html.BrowserInformationControlInput; // packageimport +import dwtx.jface.internal.text.html.HTMLMessages; // packageimport + + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; +import dwtx.dwtxhelper.StringReader; + +import dwt.custom.StyleRange; +import dwt.graphics.Drawable; +import dwt.graphics.GC; +import dwt.widgets.Display; +import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; +import dwtx.jface.text.DefaultInformationControl; +import dwtx.jface.text.Region; +import dwtx.jface.text.TextPresentation; + + +/** + *

    + * Moved into this package from dwtx.jface.internal.text.revisions.

    + */ +public class HTMLTextPresenter : DefaultInformationControl_IInformationPresenter, DefaultInformationControl_IInformationPresenterExtension { + + private static String LINE_DELIM_; + private static String LINE_DELIM() { + if( LINE_DELIM_ is null ){ + LINE_DELIM_ = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + } + return LINE_DELIM_; + } + + private int fCounter; + private bool fEnforceUpperLineLimit; + + public this(bool enforceUpperLineLimit) { +// super(); + fEnforceUpperLineLimit= enforceUpperLineLimit; + } + + public this() { + this(true); + } + + protected Reader createReader(String hoverInfo, TextPresentation presentation) { + return new HTML2TextReader(new StringReader(hoverInfo), presentation); + } + + protected void adaptTextPresentation(TextPresentation presentation, int offset, int insertLength) { + + int yoursStart= offset; + int yoursEnd= offset + insertLength -1; + yoursEnd= Math.max(yoursStart, yoursEnd); + + Iterator e= presentation.getAllStyleRangeIterator(); + while (e.hasNext()) { + + StyleRange range= cast(StyleRange) e.next(); + + int myStart= range.start; + int myEnd= range.start + range.length -1; + myEnd= Math.max(myStart, myEnd); + + if (myEnd < yoursStart) + continue; + + if (myStart < yoursStart) + range.length += insertLength; + else + range.start += insertLength; + } + } + + private void append(StringBuffer buffer, String string, TextPresentation presentation) { + + int length= string.length(); + buffer.append(string); + + if (presentation !is null) + adaptTextPresentation(presentation, fCounter, length); + + fCounter += length; + } + + private String getIndent(String line) { + int length= line.length(); + + int i= 0; + while (i < length && Character.isWhitespace(line.getRelativeCodePoint(i,0))) + i += line.getRelativeCodePointOffset(i,1); + + return (i is length ? line : line.substring(0, i)) ~ " "; //$NON-NLS-1$ + } + + /** + * {@inheritDoc} + * + * @see dwtx.jface.text.DefaultInformationControl.IInformationPresenter#updatePresentation(dwt.widgets.Display, java.lang.String, dwtx.jface.text.TextPresentation, int, int) + * @deprecated + */ + public String updatePresentation(Display display, String hoverInfo, TextPresentation presentation, int maxWidth, int maxHeight) { + return updatePresentation(cast(Drawable)display, hoverInfo, presentation, maxWidth, maxHeight); + } + + /* + * @see IHoverInformationPresenterExtension#updatePresentation(Drawable drawable, String, TextPresentation, int, int) + * @since 3.2 + */ + public String updatePresentation(Drawable drawable, String hoverInfo, TextPresentation presentation, int maxWidth, int maxHeight) { + + if (hoverInfo is null) + return null; + + GC gc= new GC(drawable); + try { + + StringBuffer buffer= new StringBuffer(); + int maxNumberOfLines= cast(int) Math.round(maxHeight / gc.getFontMetrics().getHeight()); + + fCounter= 0; + LineBreakingReader reader= new LineBreakingReader(createReader(hoverInfo, presentation), gc, maxWidth); + + bool lastLineFormatted= false; + String lastLineIndent= null; + + String line=reader.readLine(); + bool lineFormatted= reader.isFormattedLine(); + bool firstLineProcessed= false; + + while (line !is null) { + + if (fEnforceUpperLineLimit && maxNumberOfLines <= 0) + break; + + if (firstLineProcessed) { + if (!lastLineFormatted) + append(buffer, LINE_DELIM, null); + else { + append(buffer, LINE_DELIM, presentation); + if (lastLineIndent !is null) + append(buffer, lastLineIndent, presentation); + } + } + + append(buffer, line, null); + firstLineProcessed= true; + + lastLineFormatted= lineFormatted; + if (!lineFormatted) + lastLineIndent= null; + else if (lastLineIndent is null) + lastLineIndent= getIndent(line); + + line= reader.readLine(); + lineFormatted= reader.isFormattedLine(); + + maxNumberOfLines--; + } + + if (line !is null) { + append(buffer, LINE_DELIM, lineFormatted ? presentation : null); + append(buffer, HTMLMessages.getString("HTMLTextPresenter.ellipse"), presentation); //$NON-NLS-1$ + } + + return trim(buffer, presentation); + + } catch (IOException e) { + + // ignore TODO do something else? + return null; + + } finally { + gc.dispose(); + } + } + + private String trim(StringBuffer buffer, TextPresentation presentation) { + + int length= buffer.length(); + + int end= length -1; + + while (end >= 0 && Character.isWhitespace(buffer.slice().getRelativeCodePoint( end, -1 ))) + end += buffer.slice().getRelativeCodePointOffset( end, -1 ); + + if (end <= -1) + return ""; //$NON-NLS-1$ + + if (end < buffer.slice().getAbsoluteCodePointOffset( length, -1 )) + buffer.truncate(buffer.slice().getAbsoluteCodePointOffset( end, 1)); + else + end= length; + + int start= 0; + while (start < end && Character.isWhitespace(buffer.slice().getRelativeCodePoint(start, 0))) + start += buffer.slice().getRelativeCodePointOffset( start, 1 ); + + buffer.select(0, start); + buffer.remove(); + presentation.setResultWindow(new Region(start, buffer.length())); + return buffer.toString(); + } +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/html/SingleCharReader.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/html/SingleCharReader.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,75 @@ +/******************************************************************************* + * 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 + * 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.text.html.SingleCharReader; + +import dwtx.jface.internal.text.html.HTML2TextReader; // packageimport +import dwtx.jface.internal.text.html.HTMLPrinter; // packageimport +import dwtx.jface.internal.text.html.BrowserInformationControl; // packageimport +import dwtx.jface.internal.text.html.SubstitutionTextReader; // packageimport +import dwtx.jface.internal.text.html.HTMLTextPresenter; // packageimport +import dwtx.jface.internal.text.html.BrowserInput; // packageimport +import dwtx.jface.internal.text.html.BrowserInformationControlInput; // packageimport +import dwtx.jface.internal.text.html.HTMLMessages; // packageimport + + +import dwt.dwthelper.utils; + +/** + *

    + * Moved into this package from dwtx.jface.internal.text.revisions.

    + */ +public abstract class SingleCharReader : Reader { + + /** + * @see Reader#read() + */ + public abstract int read() ; + + /** + * @see Reader#read(char[],int,int) + */ + public int read(char cbuf[], int off, int len) { + int end= off + len; + for (int i= off; i < end; i++) { + int ch= read(); + if (ch is -1) { + if (i is off) + return -1; + return i - off; + } + cbuf[i]= cast(char)ch; + } + return len; + } + + /** + * @see Reader#ready() + */ + public bool ready() { + return true; + } + + /** + * Returns the readable content as string. + * @return the readable content as string + * @exception IOException in case reading fails + */ + public String getString() { + StringBuffer buf= new StringBuffer(); + int ch; + while ((ch= read()) !is -1) { + buf.append(cast(char)ch); + } + return buf.toString(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/html/SubstitutionTextReader.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/html/SubstitutionTextReader.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,217 @@ +/******************************************************************************* + * 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 + * 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.text.html.SubstitutionTextReader; + +import dwtx.jface.internal.text.html.HTML2TextReader; // packageimport +import dwtx.jface.internal.text.html.HTMLPrinter; // packageimport +import dwtx.jface.internal.text.html.BrowserInformationControl; // packageimport +import dwtx.jface.internal.text.html.HTMLTextPresenter; // packageimport +import dwtx.jface.internal.text.html.BrowserInput; // packageimport +import dwtx.jface.internal.text.html.SingleCharReader; // packageimport +import dwtx.jface.internal.text.html.BrowserInformationControlInput; // packageimport +import dwtx.jface.internal.text.html.HTMLMessages; // packageimport + +import dwt.dwthelper.utils; +import tango.core.Exception; + +/** + * Reads the text contents from a reader and computes for each character + * a potential substitution. The substitution may eat more characters than + * only the one passed into the computation routine. + *

    + * Moved into this package from dwtx.jface.internal.text.revisions.

    + */ +public abstract class SubstitutionTextReader : SingleCharReader { + + private static String LINE_DELIM_; + protected static String LINE_DELIM() { + if( LINE_DELIM_ is null ){ + LINE_DELIM_ = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + } + return LINE_DELIM_; + } + + private Reader fReader; + protected bool fWasWhiteSpace; + private int fCharAfterWhiteSpace; + + /** + * Tells whether white space characters are skipped. + */ + private bool fSkipWhiteSpace= true; + + private bool fReadFromBuffer; + private StringBuffer fBuffer; + private int fIndex; + + + protected this(Reader reader) { + fReader= reader; + fBuffer= new StringBuffer(); + fIndex= 0; + fReadFromBuffer= false; + fCharAfterWhiteSpace= -1; + fWasWhiteSpace= true; + } + + /** + * Computes the substitution for the given character and if necessary + * subsequent characters. Implementation should use nextChar + * to read subsequent characters. + * + * @param c the character to be substituted + * @return the substitution for c + * @throws IOException in case computing the substitution fails + */ + protected abstract String computeSubstitution(int c) ; + + /** + * Returns the internal reader. + * + * @return the internal reader + */ + protected Reader getReader() { + return fReader; + } + + /** + * Returns the next character. + * @return the next character + * @throws IOException in case reading the character fails + */ + protected int nextChar() { + fReadFromBuffer= (fBuffer.length() > 0); + if (fReadFromBuffer) { + char ch= fBuffer.slice().charAt(fIndex++); + if (fIndex >= fBuffer.length()) { + fBuffer.truncate(0); + fIndex= 0; + } + return ch; + } + + int ch= fCharAfterWhiteSpace; + if (ch is -1) { + ch= fReader.read(); + } + if (fSkipWhiteSpace && Character.isWhitespace(cast(char)ch)) { + do { + ch= fReader.read(); + } while (Character.isWhitespace(cast(char)ch)); + if (ch !is -1) { + fCharAfterWhiteSpace= ch; + return ' '; + } + } else { + fCharAfterWhiteSpace= -1; + } + return ch; + } + + /// DWT + protected int nextDChar() { + char[4] buf = void; + int ch1 = nextChar(); + if( ch1 is -1 ) return -1; + buf[0] = cast(char)ch1; + if(( ch1 & 0x80 ) is 0x00 ){ + return ch1; + } + else if(( ch1 & 0xE0 ) is 0xC0 ){ + int ch2 = nextChar(); + if( ch2 is -1 ) throw new UnicodeException(__FILE__,__LINE__); + buf[1] = cast(char)ch2; + } + else if(( ch1 & 0xF0 ) is 0xE0 ){ + int ch2 = nextChar(); + if( ch1 is -1 ) throw new UnicodeException(__FILE__,__LINE__); + buf[1] = cast(char)ch2; + int ch3 = nextChar(); + if( ch3 is -1 ) throw new UnicodeException(__FILE__,__LINE__); + buf[2] = cast(char)ch3; + } + else if(( ch1 & 0xF8 ) is 0xF0 ){ + int ch2 = nextChar(); + if( ch1 is -1 ) throw new UnicodeException(__FILE__,__LINE__); + buf[1] = cast(char)ch2; + int ch3 = nextChar(); + if( ch3 is -1 ) throw new UnicodeException(__FILE__,__LINE__); + buf[2] = cast(char)ch3; + int ch4 = nextChar(); + if( ch4 is -1 ) throw new UnicodeException(__FILE__,__LINE__); + buf[3] = cast(char)ch4; + } + else { + throw new UnicodeException(__FILE__,__LINE__); + } + uint ate; + return tango.text.convert.Utf.decode( buf, ate ); + } + + /** + * @see Reader#read() + */ + public int read() { + int c; + do { + + c= nextChar(); + while (!fReadFromBuffer) { + String s= computeSubstitution(c); + if (s is null) + break; + if (s.length() > 0){ + fBuffer.select(0, 0); + fBuffer.replace(s); + } + c= nextChar(); + } + + } while (fSkipWhiteSpace && fWasWhiteSpace && (c is ' ')); + fWasWhiteSpace= (c is ' ' || c is '\r' || c is '\n'); + return c; + } + + /** + * @see Reader#ready() + */ + public bool ready() { + return fReader.ready(); + } + + /** + * @see Reader#close() + */ + public void close() { + fReader.close(); + } + + /** + * @see Reader#reset() + */ + public void reset() { + fReader.reset(); + fWasWhiteSpace= true; + fCharAfterWhiteSpace= -1; + fBuffer.truncate(0); + fIndex= 0; + } + + protected final void setSkipWhitespace(bool state) { + fSkipWhiteSpace= state; + } + + protected final bool isSkippingWhitespace() { + return fSkipWhiteSpace; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/link/contentassist/AdditionalInfoController2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/link/contentassist/AdditionalInfoController2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,273 @@ +/******************************************************************************* + * 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 + * 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.text.link.contentassist.AdditionalInfoController2; + +import dwtx.jface.internal.text.link.contentassist.IProposalListener; // packageimport +import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; // packageimport +import dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContentAssistMessages; // packageimport +import dwtx.jface.internal.text.link.contentassist.Helper2; // packageimport +import dwtx.jface.internal.text.link.contentassist.PopupCloser2; // packageimport +import dwtx.jface.internal.text.link.contentassist.IContentAssistListener2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; // packageimport + +import dwt.dwthelper.utils; +import tango.core.Thread; + +import dwt.events.SelectionEvent; +import dwt.events.SelectionListener; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Control; +import dwt.widgets.Table; +import dwt.widgets.TableItem; +import dwtx.core.runtime.Assert; +import dwtx.jface.text.AbstractInformationControlManager; +import dwtx.jface.text.IInformationControl; +import dwtx.jface.text.IInformationControlCreator; +import dwtx.jface.text.contentassist.ICompletionProposal; +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; + + + +/** + * Displays the additional information available for a completion proposal. + * + * @since 2.0 + */ +class AdditionalInfoController2 : AbstractInformationControlManager , Runnable { + + /** + * Internal table selection listener. + */ + private class TableSelectionListener : SelectionListener { + + /* + * @see SelectionListener#widgetSelected(SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + handleTableSelectionChanged(); + } + + /* + * @see SelectionListener#widgetDefaultSelected(SelectionEvent) + */ + public void widgetDefaultSelected(SelectionEvent e) { + } + } + + + /** The proposal table */ + private Table fProposalTable; + /** The thread controlling the delayed display of the additional info */ + private Thread fThread; + /** Indicates whether the display delay has been reset */ + private bool fIsReset= false; + /** Object to synchronize display thread and table selection changes */ + private const Object fMutex; + /** Thread access lock. */ + private const Object fThreadAccess; + /** Object to synchronize initial display of additional info */ + private Object fStartSignal; + /** The table selection listener */ + private SelectionListener fSelectionListener; + /** The delay after which additional information is displayed */ + private int fDelay; + + + /** + * Creates a new additional information controller. + * + * @param creator the information control creator to be used by this controller + * @param delay time in milliseconds after which additional info should be displayed + */ + this(IInformationControlCreator creator, int delay) { + fSelectionListener= new TableSelectionListener(); + fThreadAccess= new Object(); + fMutex= new Object(); + super(creator); + fDelay= delay; + setAnchor(ANCHOR_RIGHT); + setFallbackAnchors([ANCHOR_RIGHT, ANCHOR_LEFT, ANCHOR_BOTTOM ]); + } + + /* + * @see AbstractInformationControlManager#install(Control) + */ + public void install(Control control) { + + if (fProposalTable is control) { + // already installed + return; + } + + super.install(control); + + Assert.isTrue( null !is cast(Table)control ); + fProposalTable= cast(Table) control; + fProposalTable.addSelectionListener(fSelectionListener); + synchronized (fThreadAccess) { + if (fThread !is null) + fThread.interrupt(); + fThread= new Thread(this, ContentAssistMessages.getString("InfoPopup.info_delay_timer_name")); //$NON-NLS-1$ + + fStartSignal= new Object(); + synchronized (fStartSignal) { + fThread.start(); + try { + // wait until thread is ready + fStartSignal.wait(); + } catch (InterruptedException x) { + } + } + } + } + + /* + * @see AbstractInformationControlManager#disposeInformationControl() + */ + public void disposeInformationControl() { + + synchronized (fThreadAccess) { + if (fThread !is null) { + fThread.interrupt(); + fThread= null; + } + } + + if (fProposalTable !is null && !fProposalTable.isDisposed()) { + fProposalTable.removeSelectionListener(fSelectionListener); + fProposalTable= null; + } + + super.disposeInformationControl(); + } + + /* + * @see java.lang.Runnable#run() + */ + public void run() { + try { + while (true) { + + synchronized (fMutex) { + + if (fStartSignal !is null) { + synchronized (fStartSignal) { + fStartSignal.notifyAll(); + fStartSignal= null; + } + } + + // Wait for a selection event to occur. + fMutex.wait(); + + while (true) { + fIsReset= false; + // Delay before showing the popup. + fMutex.wait(fDelay); + if (!fIsReset) + break; + } + } + + if (fProposalTable !is null && !fProposalTable.isDisposed()) { + fProposalTable.getDisplay().asyncExec(new class() Runnable { + public void run() { + if (!fIsReset) + showInformation(); + } + }); + } + + } + } catch (InterruptedException e) { + } + + synchronized (fThreadAccess) { + // only null fThread if it is us! + if (Thread.currentThread() is fThread) + fThread= null; + } + } + + /** + *Handles a change of the line selected in the associated selector. + */ + public void handleTableSelectionChanged() { + + if (fProposalTable !is null && !fProposalTable.isDisposed() && fProposalTable.isVisible()) { + synchronized (fMutex) { + fIsReset= true; + fMutex.notifyAll(); + } + } + } + + /* + * @see AbstractInformationControlManager#computeInformation() + */ + protected void computeInformation() { + + if (fProposalTable is null || fProposalTable.isDisposed()) + return; + + TableItem[] selection= fProposalTable.getSelection(); + if (selection !is null && selection.length > 0) { + + TableItem item= selection[0]; + + // compute information + String information= null; + Object d= item.getData(); + + if ( cast(ICompletionProposal)d ) { + ICompletionProposal p= cast(ICompletionProposal) d; + information= p.getAdditionalProposalInfo(); + } + + if ( cast(ICompletionProposalExtension3)d ) + setCustomInformationControlCreator((cast(ICompletionProposalExtension3) d).getInformationControlCreator()); + else + setCustomInformationControlCreator(null); + + // compute subject area + setMargins(4, -1); + Rectangle area= fProposalTable.getBounds(); + area.x= 0; // subject area is the whole subject control + area.y= 0; + + // set information & subject area + setInformation(information, area); + } + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#computeSizeConstraints(Control, IInformationControl) + */ + protected Point computeSizeConstraints(Control subjectControl, IInformationControl informationControl) { + // at least as big as the proposal table + Point sizeConstraint= super.computeSizeConstraints(subjectControl, informationControl); + Point size= subjectControl.getSize(); + if (sizeConstraint.x < size.x) + sizeConstraint.x= size.x; + if (sizeConstraint.y < size.y) + sizeConstraint.y= size.y; + return sizeConstraint; + } +} + + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/link/contentassist/CompletionProposalPopup2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/link/contentassist/CompletionProposalPopup2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,968 @@ +/******************************************************************************* + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Sean Montgomery, sean_montgomery@comcast.net - https://bugs.eclipse.org/bugs/show_bug.cgi?id=116454 + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; + +import dwtx.jface.internal.text.link.contentassist.IProposalListener; // packageimport +import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContentAssistMessages; // packageimport +import dwtx.jface.internal.text.link.contentassist.Helper2; // packageimport +import dwtx.jface.internal.text.link.contentassist.PopupCloser2; // packageimport +import dwtx.jface.internal.text.link.contentassist.IContentAssistListener2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; // packageimport +import dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.dwtxhelper.Collection; + + +import dwt.DWT; +import dwt.custom.StyleRange; +import dwt.custom.StyledText; +import dwt.events.ControlEvent; +import dwt.events.ControlListener; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.events.KeyEvent; +import dwt.events.KeyListener; +import dwt.events.SelectionEvent; +import dwt.events.SelectionListener; +import dwt.events.VerifyEvent; +import dwt.graphics.Color; +import dwt.graphics.Point; +import dwt.layout.GridData; +import dwt.layout.GridLayout; +import dwt.widgets.Control; +import dwt.widgets.Shell; +import dwt.widgets.Table; +import dwt.widgets.TableItem; +import dwtx.jface.internal.text.TableOwnerDrawSupport; +import dwtx.jface.resource.JFaceResources; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentListener; +import dwtx.jface.text.IEditingSupport; +import dwtx.jface.text.IEditingSupportRegistry; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.IRewriteTarget; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.ITextViewerExtension; +import dwtx.jface.text.TextUtilities; +import dwtx.jface.text.contentassist.ICompletionProposal; +import dwtx.jface.text.contentassist.ICompletionProposalExtension; +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; +import dwtx.jface.text.contentassist.IContextInformation; +import dwtx.jface.viewers.StyledString; + + + +/** + * This class is used to present proposals to the user. If additional + * information exists for a proposal, then selecting that proposal + * will result in the information being displayed in a secondary + * window. + * + * @see dwtx.jface.text.contentassist.ICompletionProposal + * @see dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2 + */ +class CompletionProposalPopup2 : IContentAssistListener2 { + + /** The associated text viewer */ + private ITextViewer fViewer; + /** The associated content assistant */ + private ContentAssistant2 fContentAssistant; + /** The used additional info controller */ + private AdditionalInfoController2 fAdditionalInfoController; + /** The closing strategy for this completion proposal popup */ + private PopupCloser2 fPopupCloser; + /** The popup shell */ + private Shell fProposalShell; + /** The proposal table */ + private Table fProposalTable; + /** Indicates whether a completion proposal is being inserted */ + private bool fInserting= false; + /** The key listener to control navigation */ + private KeyListener fKeyListener; + /** List of document events used for filtering proposals */ + private List fDocumentEvents; + /** Listener filling the document event queue */ + private IDocumentListener fDocumentListener; + /** Reentrance count for filterProposals */ + private long fInvocationCounter= 0; + /** The filter list of proposals */ + private ICompletionProposal[] fFilteredProposals; + /** The computed list of proposals */ + private ICompletionProposal[] fComputedProposals; + /** The offset for which the proposals have been computed */ + private int fInvocationOffset; + /** The offset for which the computed proposals have been filtered */ + private int fFilterOffset; + /** The default line delimiter of the viewer's widget */ + private String fLineDelimiter; + /** The most recently selected proposal. */ + private ICompletionProposal fLastProposal; + /** + * Tells whether colored labels support is enabled. + * Only valid while the popup is active. + * + * @since 3.4 + */ + private bool fIsColoredLabelsSupportEnabled= false; + + private IEditingSupport fFocusEditingSupport; + private void fFocusEditingSupport_init() { + fFocusEditingSupport = new class() IEditingSupport { + + public bool isOriginator(DocumentEvent event, IRegion focus) { + return false; + } + + public bool ownsFocusShell() { + return Helper2.okToUse(fProposalShell) && fProposalShell.isFocusControl() + || Helper2.okToUse(fProposalTable) && fProposalTable.isFocusControl(); + } + + }; + } + private IEditingSupport fModificationEditingSupport; + private void fModificationEditingSupport_init() { + fModificationEditingSupport = new class() IEditingSupport { + + public bool isOriginator(DocumentEvent event, IRegion focus) { + if (fViewer !is null) { + Point selection= fViewer.getSelectedRange(); + return selection.x <= focus.getOffset() + focus.getLength() && selection.x + selection.y >= focus.getOffset(); + } + return false; + } + + public bool ownsFocusShell() { + return false; + } + + }; + } + + /** + * Creates a new completion proposal popup for the given elements. + * + * @param contentAssistant the content assistant feeding this popup + * @param viewer the viewer on top of which this popup appears + * @param infoController the info control collaborating with this popup + * @since 2.0 + */ + public this(ContentAssistant2 contentAssistant, ITextViewer viewer, AdditionalInfoController2 infoController) { + fPopupCloser= new PopupCloser2(); + fDocumentEvents= new ArrayList(); + + fModificationEditingSupport_init(); + fFocusEditingSupport_init(); + + fContentAssistant= contentAssistant; + fViewer= viewer; + fAdditionalInfoController= infoController; + } + + /** + * Computes and presents completion proposals. The flag indicates whether this call has + * be made out of an auto activation context. + * + * @param autoActivated true if auto activation context + * @return an error message or null in case of no error + */ + public String showProposals(bool autoActivated) { + + if (fKeyListener is null) { + fKeyListener= new class() KeyListener { + public void keyPressed(KeyEvent e) { + if (!Helper2.okToUse(fProposalShell)) + return; + + if (e.character is 0 && e.keyCode is DWT.CTRL) { + // http://dev.eclipse.org/bugs/show_bug.cgi?id=34754 + int index= fProposalTable.getSelectionIndex(); + if (index >= 0) + selectProposal(index, true); + } + } + + public void keyReleased(KeyEvent e) { + if (!Helper2.okToUse(fProposalShell)) + return; + + if (e.character is 0 && e.keyCode is DWT.CTRL) { + // http://dev.eclipse.org/bugs/show_bug.cgi?id=34754 + int index= fProposalTable.getSelectionIndex(); + if (index >= 0) + selectProposal(index, false); + } + } + }; + } + + final StyledText styledText= fViewer.getTextWidget(); + if (styledText !is null && !styledText.isDisposed()) + styledText.addKeyListener(fKeyListener); + +// BusyIndicator.showWhile(styledText.getDisplay(), new class() Runnable { +// public void run() { + + fInvocationOffset= fViewer.getSelectedRange().x; + // lazily compute proposals +// if (fComputedProposals is null) fComputedProposals= computeProposals(fContentAssistant.getCompletionPosition()); + fComputedProposals= computeProposals(fInvocationOffset); + + int count= (fComputedProposals is null ? 0 : fComputedProposals.length); + if (count is 0) { + + if (!autoActivated) + styledText.getDisplay().beep(); + + } else { + + if (count is 1 && !autoActivated && fContentAssistant.isAutoInserting()) + + insertProposal(fComputedProposals[0], cast(wchar) 0, 0, fInvocationOffset); + + else { + + if (fLineDelimiter is null) + fLineDelimiter= styledText.getLineDelimiter(); + + createProposalSelector(); + setProposals(fComputedProposals); + resizeProposalSelector(true); + displayProposals(); + } + } +// } +// }); + + return getErrorMessage(); + } + + /** + * Returns the completion proposal available at the given offset of the + * viewer's document. Delegates the work to the content assistant. + * + * @param offset the offset + * @return the completion proposals available at this offset + */ + private ICompletionProposal[] computeProposals(int offset) { + return fContentAssistant.computeCompletionProposals(fViewer, offset); + } + + /** + * Returns the error message. + * + * @return the error message + */ + private String getErrorMessage() { + return fContentAssistant.getErrorMessage(); + } + + /** + * Creates the proposal selector. + */ + private void createProposalSelector() { + if (Helper2.okToUse(fProposalShell)) + return; + + Control control= fViewer.getTextWidget(); + fProposalShell= new Shell(control.getShell(), DWT.ON_TOP); +// fProposalShell= new Shell(control.getShell(), DWT.ON_TOP | DWT.RESIZE ); + fProposalTable= new Table(fProposalShell, DWT.H_SCROLL | DWT.V_SCROLL); +// fProposalTable= new Table(fProposalShell, DWT.H_SCROLL | DWT.V_SCROLL); + + + fIsColoredLabelsSupportEnabled= fContentAssistant.isColoredLabelsSupportEnabled(); + if (fIsColoredLabelsSupportEnabled) + TableOwnerDrawSupport.install(fProposalTable); + + fProposalTable.setLocation(0, 0); + if (fAdditionalInfoController !is null) + fAdditionalInfoController.setSizeConstraints(50, 10, true, false); + + GridLayout layout= new GridLayout(); + layout.marginWidth= 0; + layout.marginHeight= 0; + fProposalShell.setLayout(layout); + + GridData data= new GridData(GridData.FILL_BOTH); + fProposalTable.setLayoutData(data); + + fProposalShell.pack(); + + // set location + Point currentLocation= fProposalShell.getLocation(); + Point newLocation= getLocation(); + if ((newLocation.x < currentLocation.x && newLocation.y is currentLocation.y) || newLocation.y < currentLocation.y) + fProposalShell.setLocation(newLocation); + + if (fAdditionalInfoController !is null) { + fProposalShell.addControlListener(new class() ControlListener { + + public void controlMoved(ControlEvent e) {} + + public void controlResized(ControlEvent e) { + // resets the cached resize constraints + fAdditionalInfoController.setSizeConstraints(50, 10, true, false); + } + }); + } + + fProposalShell.setBackground(control.getDisplay().getSystemColor(DWT.COLOR_BLACK)); + + Color c= control.getDisplay().getSystemColor(DWT.COLOR_INFO_BACKGROUND); + fProposalTable.setBackground(c); + + c= control.getDisplay().getSystemColor(DWT.COLOR_INFO_FOREGROUND); + fProposalTable.setForeground(c); + + fProposalTable.addSelectionListener(new class() SelectionListener { + + public void widgetSelected(SelectionEvent e) {} + + public void widgetDefaultSelected(SelectionEvent e) { + selectProposalWithMask(e.stateMask); + } + }); + + fPopupCloser.install(fContentAssistant, fProposalTable); + + fProposalShell.addDisposeListener(new class() DisposeListener { + public void widgetDisposed(DisposeEvent e) { + unregister(); // but don't dispose the shell, since we're being called from its disposal event! + } + }); + + fProposalTable.setHeaderVisible(false); + fContentAssistant.addToLayout(this, fProposalShell, ContentAssistant2.LayoutManager.LAYOUT_PROPOSAL_SELECTOR, fContentAssistant.getSelectionOffset()); + } + + /** + * Returns the proposal selected in the proposal selector. + * + * @return the selected proposal + * @since 2.0 + */ + private ICompletionProposal getSelectedProposal() { + int i= fProposalTable.getSelectionIndex(); + if (i < 0 || i >= fFilteredProposals.length) + return null; + return fFilteredProposals[i]; + } + + /** + * Takes the selected proposal and applies it. + * + * @param stateMask the state mask + * @since 2.1 + */ + private void selectProposalWithMask(int stateMask) { + ICompletionProposal p= getSelectedProposal(); + hide(); + if (p !is null) + insertProposal(p, cast(wchar) 0, stateMask, fViewer.getSelectedRange().x); + } + + /** + * Applies the given proposal at the given offset. The given character is the + * one that triggered the insertion of this proposal. + * + * @param p the completion proposal + * @param trigger the trigger character + * @param stateMask the state mask of the keyboard event triggering the insertion + * @param offset the offset + * @since 2.1 + */ + private void insertProposal(ICompletionProposal p, char trigger, int stateMask, int offset) { + + fInserting= true; + IRewriteTarget target= null; + IEditingSupportRegistry registry= null; + + try { + + IDocument document= fViewer.getDocument(); + + if ( cast(ITextViewerExtension)fViewer ) { + ITextViewerExtension extension= cast(ITextViewerExtension) fViewer; + target= extension.getRewriteTarget(); + } + + if (target !is null) + target.beginCompoundChange(); + + if ( cast(IEditingSupportRegistry)fViewer ) { + registry= cast(IEditingSupportRegistry) fViewer; + registry.register(fModificationEditingSupport); + } + + if ( cast(ICompletionProposalExtension2)p ) { + ICompletionProposalExtension2 e= cast(ICompletionProposalExtension2) p; + e.apply(fViewer, trigger, stateMask, offset); + } else if ( cast(ICompletionProposalExtension)p ) { + ICompletionProposalExtension e= cast(ICompletionProposalExtension) p; + e.apply(document, trigger, offset); + } else { + p.apply(document); + } + + Point selection= p.getSelection(document); + if (selection !is null) { + fViewer.setSelectedRange(selection.x, selection.y); + fViewer.revealRange(selection.x, selection.y); + } + + IContextInformation info= p.getContextInformation(); + if (info !is null) { + + int position; + if ( cast(ICompletionProposalExtension)p ) { + ICompletionProposalExtension e= cast(ICompletionProposalExtension) p; + position= e.getContextInformationPosition(); + } else { + if (selection is null) + selection= fViewer.getSelectedRange(); + position= selection.x + selection.y; + } + + fContentAssistant.showContextInformation(info, position); + } + + fContentAssistant.fireProposalChosen(p); + + } finally { + if (target !is null) + target.endCompoundChange(); + + if (registry !is null) + registry.unregister(fModificationEditingSupport); + + fInserting= false; + } + } + + /** + * Returns whether this popup has the focus. + * + * @return true if the popup has the focus + */ + public bool hasFocus() { + if (Helper2.okToUse(fProposalShell)) + return (fProposalShell.isFocusControl() || fProposalTable.isFocusControl()); + + return false; + } + + /** + * Hides this popup. + */ + public void hide() { + + unregister(); + + if ( cast(IEditingSupportRegistry)fViewer ) { + IEditingSupportRegistry registry= cast(IEditingSupportRegistry) fViewer; + registry.unregister(fFocusEditingSupport); + } + + if (Helper2.okToUse(fProposalShell)) { + fContentAssistant.removeContentAssistListener(this, ContentAssistant2.PROPOSAL_SELECTOR); + + fPopupCloser.uninstall(); + // see bug 47511: setVisible may run the event loop on GTK + // and trigger a rentrant call - have to make sure we don't + // dispose another shell that was already brought up in a + // reentrant call when calling setVisible() + Shell tempShell= fProposalShell; + fProposalShell= null; + tempShell.setVisible(false); + tempShell.dispose(); + } + } + + private void unregister() { + if (fDocumentListener !is null) { + IDocument document= fViewer.getDocument(); + if (document !is null) + document.removeDocumentListener(fDocumentListener); + fDocumentListener= null; + } + fDocumentEvents.clear(); + + StyledText styledText= fViewer.getTextWidget(); + if (fKeyListener !is null && styledText !is null && !styledText.isDisposed()) + styledText.removeKeyListener(fKeyListener); + + if (fLastProposal !is null) { + if ( cast(ICompletionProposalExtension2)fLastProposal ) { + ICompletionProposalExtension2 extension= cast(ICompletionProposalExtension2) fLastProposal; + extension.unselected(fViewer); + } + + fLastProposal= null; + } + + fFilteredProposals= null; + + fContentAssistant.possibleCompletionsClosed_package(); + } + + /** + *Returns whether this popup is active. It is active if the propsal selector is visible. + * + * @return true if this popup is active + */ + public bool isActive() { + return fProposalShell !is null && !fProposalShell.isDisposed(); + } + + /** + * Initializes the proposal selector with these given proposals. + * + * @param proposals the proposals + */ + private void setProposals(ICompletionProposal[] proposals) { + if (Helper2.okToUse(fProposalTable)) { + + ICompletionProposal oldProposal= getSelectedProposal(); + if ( cast(ICompletionProposalExtension2)oldProposal ) + (cast(ICompletionProposalExtension2) oldProposal).unselected(fViewer); + + fFilteredProposals= proposals; + + fProposalTable.setRedraw(false); + fProposalTable.removeAll(); + + Point selection= fViewer.getSelectedRange(); + int endOffset; + endOffset= selection.x + selection.y; + IDocument document= fViewer.getDocument(); + bool validate= false; + if (selection.y !is 0 && document !is null) validate= true; + int selectionIndex= 0; + + TableItem item; + ICompletionProposal p; + for (int i= 0; i < proposals.length; i++) { + p= proposals[i]; + item= new TableItem(fProposalTable, DWT.NULL); + if (p.getImage() !is null) + item.setImage(p.getImage()); + + String displayString; + StyleRange[] styleRanges= null; + if (fIsColoredLabelsSupportEnabled && cast(ICompletionProposalExtension6)p ) { + StyledString styledString= (cast(ICompletionProposalExtension6)p).getStyledDisplayString(); + displayString= styledString.getString(); + styleRanges= styledString.getStyleRanges(); + } else + displayString= p.getDisplayString(); + + item.setText(displayString); + if (fIsColoredLabelsSupportEnabled) + TableOwnerDrawSupport.storeStyleRanges(item, 0, styleRanges); + + item.setData(cast(Object)p); + + if (validate && validateProposal(document, p, endOffset, null)) { + selectionIndex= i; + validate= false; + } + } + + resizeProposalSelector(false); + + selectProposal(selectionIndex, false); + fProposalTable.setRedraw(true); + } + } + + private void resizeProposalSelector(bool adjustWidth) { + // in order to fill in the table items so size computation works correctly + // will cause flicker, though + fProposalTable.setRedraw(true); + + int width= adjustWidth ? DWT.DEFAULT : (cast(GridData)fProposalTable.getLayoutData()).widthHint; + Point size= fProposalTable.computeSize(width, DWT.DEFAULT, true); + + GridData data= new GridData(GridData.FILL_BOTH); + data.widthHint= adjustWidth ? Math.min(size.x, 300) : width; + data.heightHint= Math.min(getTableHeightHint(fProposalTable, fProposalTable.getItemCount()), getTableHeightHint(fProposalTable, 10)); + fProposalTable.setLayoutData(data); + + fProposalShell.layout(true); + fProposalShell.pack(); + + if (adjustWidth) { + fProposalShell.setLocation(getLocation()); + } + } + + /** + * Computes the table hight hint for table. + * + * @param table the table to compute the height for + * @param rows the number of rows to compute the height for + * @return the height hint for table + */ + private int getTableHeightHint(Table table, int rows) { + if (table.getFont().opEquals(JFaceResources.getDefaultFont())) + table.setFont(JFaceResources.getDialogFont()); + int result= table.getItemHeight() * rows; + if (table.getLinesVisible()) + result+= table.getGridLineWidth() * (rows - 1); + + // TODO adjust to correct size. +4 works on windows, but not others +// return result + 4; + return result; + } + + private bool validateProposal(IDocument document, ICompletionProposal p, int offset, DocumentEvent event) { + // detect selected + if ( cast(ICompletionProposalExtension2)p ) { + ICompletionProposalExtension2 e= cast(ICompletionProposalExtension2) p; + if (e.validate(document, offset, event)) + return true; + } else if ( cast(ICompletionProposalExtension)p ) { + ICompletionProposalExtension e= cast(ICompletionProposalExtension) p; + if (e.isValidFor(document, offset)) + return true; + } + return false; + } + + /** + * Returns the graphical location at which this popup should be made visible. + * + * @return the location of this popup + */ + private Point getLocation() { + StyledText text= fViewer.getTextWidget(); + Point selection= text.getSelection(); + Point p= text.getLocationAtOffset(selection.x); + p.x -= fProposalShell.getBorderWidth(); + if (p.x < 0) p.x= 0; + if (p.y < 0) p.y= 0; + p= new Point(p.x, p.y + text.getLineHeight(selection.x)); + p= text.toDisplay(p); + return p; + } + + /** + *Displays this popup and install the additional info controller, so that additional info + * is displayed when a proposal is selected and additional info is available. + */ + private void displayProposals() { + if (fContentAssistant.addContentAssistListener(this, ContentAssistant2.PROPOSAL_SELECTOR)) { + + if (fDocumentListener is null) + fDocumentListener= new class() IDocumentListener { + public void documentAboutToBeChanged(DocumentEvent event) { + if (!fInserting) + fDocumentEvents.add(event); + } + + public void documentChanged(DocumentEvent event) { + if (!fInserting) + filterProposals(); + } + }; + IDocument document= fViewer.getDocument(); + if (document !is null) + document.addDocumentListener(fDocumentListener); + + + if ( cast(IEditingSupportRegistry)fViewer ) { + IEditingSupportRegistry registry= cast(IEditingSupportRegistry) fViewer; + registry.register(fFocusEditingSupport); + } + + fProposalShell.setVisible(true); + // see bug 47511: setVisible may run the event loop on GTK + // and trigger a rentrant call - have to check whether we are still + // visible + if (!Helper2.okToUse(fProposalShell)) + return; + + + if (fAdditionalInfoController !is null) { + fAdditionalInfoController.install(fProposalTable); + fAdditionalInfoController.handleTableSelectionChanged(); + } + } + } + + /* + * @see IContentAssistListener#verifyKey(VerifyEvent) + */ + public bool verifyKey(VerifyEvent e) { + if (!Helper2.okToUse(fProposalShell)) + return true; + + char key= e.character; + if (key is 0) { + int newSelection= fProposalTable.getSelectionIndex(); + int visibleRows= (fProposalTable.getSize().y / fProposalTable.getItemHeight()) - 1; + bool smartToggle= false; + switch (e.keyCode) { + + case DWT.ARROW_LEFT : + case DWT.ARROW_RIGHT : + filterProposals(); + return true; + + case DWT.ARROW_UP : + newSelection -= 1; + if (newSelection < 0) + newSelection= fProposalTable.getItemCount() - 1; + break; + + case DWT.ARROW_DOWN : + newSelection += 1; + if (newSelection > fProposalTable.getItemCount() - 1) + newSelection= 0; + break; + + case DWT.PAGE_DOWN : + newSelection += visibleRows; + if (newSelection >= fProposalTable.getItemCount()) + newSelection= fProposalTable.getItemCount() - 1; + break; + + case DWT.PAGE_UP : + newSelection -= visibleRows; + if (newSelection < 0) + newSelection= 0; + break; + + case DWT.HOME : + newSelection= 0; + break; + + case DWT.END : + newSelection= fProposalTable.getItemCount() - 1; + break; + + default : + if (e.keyCode !is DWT.MOD1 && e.keyCode !is DWT.MOD2 && e.keyCode !is DWT.MOD3 && e.keyCode !is DWT.MOD4) + hide(); + return true; + } + + selectProposal(newSelection, smartToggle); + + e.doit= false; + return false; + + } + + // key !is 0 + switch (key) { + case 0x1B: // Esc + e.doit= false; + hide(); + break; + + case '\n': // Ctrl-Enter on w2k + case '\r': // Enter + if ((e.stateMask & DWT.CTRL) is 0) { + e.doit= false; + selectProposalWithMask(e.stateMask); + } + break; + + // in linked mode: hide popup + // plus: don't invalidate the event in order to give LinkedUI a chance to handle it + case '\t': +// hide(); + break; + + default: + ICompletionProposal p= getSelectedProposal(); + if ( cast(ICompletionProposalExtension)p ) { + ICompletionProposalExtension t= cast(ICompletionProposalExtension) p; + char[] triggers= t.getTriggerCharacters(); + if (contains(triggers, key)) { + hide(); + if (key is ';') { + e.doit= true; + insertProposal(p, cast(wchar) 0, e.stateMask, fViewer.getSelectedRange().x); + } else { + e.doit= false; + insertProposal(p, key, e.stateMask, fViewer.getSelectedRange().x); + } + } + } + } + + return true; + } + + /** + * Selects the entry with the given index in the proposal selector and feeds + * the selection to the additional info controller. + * + * @param index the index in the list + * @param smartToggle true if the smart toogle key has been pressed + * @since 2.1 + */ + private void selectProposal(int index, bool smartToggle) { + + ICompletionProposal oldProposal= getSelectedProposal(); + if ( cast(ICompletionProposalExtension2)oldProposal ) + (cast(ICompletionProposalExtension2) oldProposal).unselected(fViewer); + + ICompletionProposal proposal= fFilteredProposals[index]; + if ( cast(ICompletionProposalExtension2)proposal ) + (cast(ICompletionProposalExtension2) proposal).selected(fViewer, smartToggle); + + fLastProposal= proposal; + + fProposalTable.setSelection(index); + fProposalTable.showSelection(); + if (fAdditionalInfoController !is null) + fAdditionalInfoController.handleTableSelectionChanged(); + } + + /** + * Returns whether the given character is contained in the given array of + * characters. + * + * @param characters the list of characters + * @param c the character to look for in the list + * @return true if character belongs to the list + * @since 2.0 + */ + private bool contains(char[] characters, char c) { + + if (characters is null) + return false; + + for (int i= 0; i < characters.length; i++) { + if (c is characters[i]) + return true; + } + + return false; + } + + /* + * @see IEventConsumer#processEvent(VerifyEvent) + */ + public void processEvent(VerifyEvent e) { + } + + /** + * Filters the displayed proposal based on the given cursor position and the + * offset of the original invocation of the content assistant. + */ + private void filterProposals() { + ++ fInvocationCounter; + Control control= fViewer.getTextWidget(); + control.getDisplay().asyncExec(dgRunnable( (long fInvocationCounter_) { + long fCounter= fInvocationCounter_; + + if (fCounter !is fInvocationCounter) return; + + int offset= fViewer.getSelectedRange().x; + ICompletionProposal[] proposals= null; + try { + if (offset > -1) { + DocumentEvent event= TextUtilities.mergeProcessedDocumentEvents(fDocumentEvents); + proposals= computeFilteredProposals(offset, event); + } + } catch (BadLocationException x) { + } finally { + fDocumentEvents.clear(); + } + fFilterOffset= offset; + + if (proposals !is null && proposals.length > 0) + setProposals(proposals); + else + hide(); + }, fInvocationCounter)); + } + + /** + * Computes the subset of already computed propsals that are still valid for + * the given offset. + * + * @param offset the offset + * @param event the merged document event + * @return the set of filtered proposals + * @since 2.0 + */ + private ICompletionProposal[] computeFilteredProposals(int offset, DocumentEvent event) { + + if (offset is fInvocationOffset && event is null) + return fComputedProposals; + + if (offset < fInvocationOffset) { + return null; + } + + ICompletionProposal[] proposals= fComputedProposals; + if (offset > fFilterOffset) + proposals= fFilteredProposals; + + if (proposals is null) + return null; + + IDocument document= fViewer.getDocument(); + int length= proposals.length; + List filtered= new ArrayList(length); + for (int i= 0; i < length; i++) { + + if (cast(ICompletionProposalExtension2)proposals[i] ) { + + ICompletionProposalExtension2 p= cast(ICompletionProposalExtension2) proposals[i]; + if (p.validate(document, offset, event)) + filtered.add(cast(Object)p); + + } else if (cast(ICompletionProposalExtension)proposals[i] ) { + + ICompletionProposalExtension p= cast(ICompletionProposalExtension) proposals[i]; + if (p.isValidFor(document, offset)) + filtered.add(cast(Object)p); + + } else { + // restore original behavior + fInvocationOffset= offset; + fComputedProposals= computeProposals(fInvocationOffset); + return fComputedProposals; + } + } + + return arraycast!(ICompletionProposal)(filtered.toArray()); + } + + /** + * Requests the proposal shell to take focus. + * + * @since 3.0 + */ + public void setFocus() { + if (Helper2.okToUse(fProposalShell)) + fProposalShell.setFocus(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/link/contentassist/ContentAssistMessages.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/link/contentassist/ContentAssistMessages.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,83 @@ +/******************************************************************************* + * 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 + * 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.text.link.contentassist.ContentAssistMessages; + + +import dwtx.jface.internal.text.link.contentassist.IProposalListener; // packageimport +import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; // packageimport +import dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2; // packageimport +import dwtx.jface.internal.text.link.contentassist.Helper2; // packageimport +import dwtx.jface.internal.text.link.contentassist.PopupCloser2; // packageimport +import dwtx.jface.internal.text.link.contentassist.IContentAssistListener2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; // packageimport +import dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2; // packageimport + +import dwt.dwthelper.utils; + +import dwt.dwthelper.ResourceBundle; +import dwtx.dwtxhelper.MessageFormat; + + +/** + * Helper class to get NLSed messages. + * + * @since 3.0 + */ +class ContentAssistMessages { + +// private static const String RESOURCE_BUNDLE= ContentAssistMessages.classinfo.getName(); + + private static ResourceBundle fgResourceBundle;//= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + static this() { + fgResourceBundle = ResourceBundle.getBundle( + getImportData!("dwtx.jface.internal.text.link.contentassist.ContentAssistMessages.properties")); + } + + private this() { + } + + /** + * Gets a string from the resource bundle. + * + * @param key the string used to get the bundle value, must not be null + * @return the string from the resource bundle + */ + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" ~ key ~ "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + } + + /** + * Gets a string from the resource bundle and formats it with the given arguments. + * + * @param key the string used to get the bundle value, must not be null + * @param args the arguments used to format the string + * @return the formatted string + */ + public static String getFormattedString(String key, Object[] args... ) { + String format= null; + try { + format= fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" ~ key ~ "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + return MessageFormat.format(format, args); + } + + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/link/contentassist/ContentAssistant2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/link/contentassist/ContentAssistant2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,1603 @@ +/******************************************************************************* + * 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 + * 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.text.link.contentassist.ContentAssistant2; + +import dwtx.jface.internal.text.link.contentassist.IProposalListener; // packageimport +import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; // packageimport +import dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContentAssistMessages; // packageimport +import dwtx.jface.internal.text.link.contentassist.Helper2; // packageimport +import dwtx.jface.internal.text.link.contentassist.PopupCloser2; // packageimport +import dwtx.jface.internal.text.link.contentassist.IContentAssistListener2; // packageimport +import dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; +import tango.core.Thread; + +import dwt.DWT; +import dwt.DWTError; +import dwt.custom.StyledText; +import dwt.custom.VerifyKeyListener; +import dwt.events.ControlEvent; +import dwt.events.ControlListener; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.events.FocusEvent; +import dwt.events.FocusListener; +import dwt.events.MouseEvent; +import dwt.events.MouseListener; +import dwt.events.VerifyEvent; +import dwt.graphics.Color; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Listener; +import dwt.widgets.Shell; +import dwt.widgets.Widget; +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.DefaultInformationControl; +import dwtx.jface.text.IEventConsumer; +import dwtx.jface.text.IInformationControl; +import dwtx.jface.text.IInformationControlCreator; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.ITextViewerExtension; +import dwtx.jface.text.IViewportListener; +import dwtx.jface.text.IWidgetTokenKeeper; +import dwtx.jface.text.IWidgetTokenKeeperExtension; +import dwtx.jface.text.IWidgetTokenOwner; +import dwtx.jface.text.IWidgetTokenOwnerExtension; +import dwtx.jface.text.TextUtilities; +import dwtx.jface.text.contentassist.CompletionProposal; +import dwtx.jface.text.contentassist.ICompletionProposal; +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; +import dwtx.jface.text.contentassist.IContentAssistProcessor; +import dwtx.jface.text.contentassist.IContentAssistant; +import dwtx.jface.text.contentassist.IContentAssistantExtension; +import dwtx.jface.text.contentassist.IContextInformation; +import dwtx.jface.text.contentassist.IContextInformationPresenter; +import dwtx.jface.text.contentassist.IContextInformationValidator; + + +/** + * A custom implementation of the IContentAssistant interface. + * This implementation is used by the linked mode UI. This is internal and subject + * to change without notice. + */ +public class ContentAssistant2 : IContentAssistant, IContentAssistantExtension, IWidgetTokenKeeper, IWidgetTokenKeeperExtension { + + /** + * A generic closer class used to monitor various + * interface events in order to determine whether + * content-assist should be terminated and all + * associated windows closed. + */ + class Closer : ControlListener, MouseListener, FocusListener, DisposeListener, IViewportListener { + + /** The shell on which we add listeners. */ + private Shell fShell; + private long fViewportListenerStartTime; + + /** + * Installs this closer on it's viewer's text widget. + */ + protected void install() { + Control w= fViewer.getTextWidget(); + if (Helper2.okToUse(w)) { + + Shell shell= w.getShell(); + fShell= shell; + shell.addControlListener(this); + + w.addMouseListener(this); + w.addFocusListener(this); + + /* + * 1GGYYWK: ITPJUI:ALL - Dismissing editor with code assist up causes lots of Internal Errors + */ + w.addDisposeListener(this); + } + + fViewer.addViewportListener(this); + fViewportListenerStartTime= System.currentTimeMillis() + 500; + } + + /** + * Uninstalls this closer from the viewer's text widget. + */ + protected void uninstall() { + Shell shell= fShell; + fShell= null; + if (Helper2.okToUse(shell)) + shell.removeControlListener(this); + + Control w= fViewer.getTextWidget(); + if (Helper2.okToUse(w)) { + + w.removeMouseListener(this); + w.removeFocusListener(this); + + /* + * 1GGYYWK: ITPJUI:ALL - Dismissing editor with code assist up causes lots of Internal Errors + */ + w.removeDisposeListener(this); + } + + fViewer.removeViewportListener(this); + } + + /* + * @see ControlListener#controlResized(ControlEvent) + */ + public void controlResized(ControlEvent e) { + hide(); + } + + /* + * @see ControlListener#controlMoved(ControlEvent) + */ + public void controlMoved(ControlEvent e) { + hide(); + } + + /* + * @see MouseListener#mouseDown(MouseEvent) + */ + public void mouseDown(MouseEvent e) { + hide(); + } + + /* + * @see MouseListener#mouseUp(MouseEvent) + */ + public void mouseUp(MouseEvent e) { + } + + /* + * @see MouseListener#mouseDoubleClick(MouseEvent) + */ + public void mouseDoubleClick(MouseEvent e) { + hide(); + } + + /* + * @see FocusListener#focusGained(FocusEvent) + */ + public void focusGained(FocusEvent e) { + } + + /* + * @see FocusListener#focusLost(FocusEvent) + */ + public void focusLost(FocusEvent e) { + if (fViewer !is null) { + Control control= fViewer.getTextWidget(); + if (control !is null) { + Display d= control.getDisplay(); + if (d !is null) { + d.asyncExec(new class() Runnable { + public void run() { + if (!hasFocus()) + hide(); + } + }); + } + } + } + } + + /* + * @seeDisposeListener#widgetDisposed(DisposeEvent) + */ + public void widgetDisposed(DisposeEvent e) { + /* + * 1GGYYWK: ITPJUI:ALL - Dismissing editor with code assist up causes lots of Internal Errors + */ + hide(); + } + + /* + * @see IViewportListener#viewportChanged(int) + */ + public void viewportChanged(int topIndex) { + if (System.currentTimeMillis() > fViewportListenerStartTime) + hide(); + } + } + + /** + * An implementation of IContentAssistListener, this class is + * used to monitor key events in support of automatic activation + * of the content assistant. If enabled, the implementation utilizes a + * thread to watch for input characters matching the activation + * characters specified by the content assist processor, and if + * detected, will wait the indicated delay interval before + * activating the content assistant. + */ + class AutoAssistListener : VerifyKeyListener, Runnable { + + private Thread fThread; + private bool fIsReset= false; + private Object fMutex= new Object(); + private int fShowStyle; + + private const static int SHOW_PROPOSALS= 1; + private const static int SHOW_CONTEXT_INFO= 2; + + protected this() { + } + + protected void start(int showStyle) { + fShowStyle= showStyle; + fThread= new Thread(&run); + fThread.name = ContentAssistMessages.getString("ContentAssistant.assist_delay_timer_name"); //$NON-NLS-1$ + fThread.start(); + } + + public void run() { + try { + while (true) { + synchronized (fMutex) { + if (fAutoActivationDelay !is 0) + fMutex.wait(fAutoActivationDelay); + if (fIsReset) { + fIsReset= false; + continue; + } + } + showAssist(fShowStyle); + break; + } + } catch (InterruptedException e) { + } + fThread= null; + } + + protected void reset(int showStyle) { + synchronized (fMutex) { + fShowStyle= showStyle; + fIsReset= true; + fMutex.notifyAll(); + } + } + + protected void stop() { + Thread threadToStop= fThread; + if (threadToStop !is null) + threadToStop.interrupt(); + } + + private bool contains(char[] characters, char character) { + if (characters !is null) { + for (int i= 0; i < characters.length; i++) { + if (character is characters[i]) + return true; + } + } + return false; + } + + public void verifyKey(VerifyEvent e) { + // Only act on typed characters and ignore modifier-only events + if (e.character is 0 && (e.keyCode & DWT.KEYCODE_BIT) is 0) + return; + + if (e.character !is 0 && (e.stateMask is DWT.ALT)) + return; + + int showStyle; + int pos= fViewer.getSelectedRange().x; + char[] activation= getCompletionProposalAutoActivationCharacters(fViewer, pos); + + if (contains(activation, e.character) && !fProposalPopup.isActive()) + showStyle= SHOW_PROPOSALS; + else { + activation= getContextInformationAutoActivationCharacters(fViewer, pos); + if (contains(activation, e.character) && !fContextInfoPopup.isActive()) + showStyle= SHOW_CONTEXT_INFO; + else { + if (fThread !is null && fThread.isAlive()) + stop(); + return; + } + } + + if (fThread !is null && fThread.isAlive()) + reset(showStyle); + else + start(showStyle); + } + + protected void showAssist(int showStyle) { + Control control= fViewer.getTextWidget(); + Display d= control.getDisplay(); + if (d !is null) { + try { + d.syncExec(new class() Runnable { + public void run() { + if (showStyle is SHOW_PROPOSALS) + fProposalPopup.showProposals(true); + else if (showStyle is SHOW_CONTEXT_INFO) + fContextInfoPopup.showContextProposals(true); + } + }); + } catch (DWTError e) { + } + } + } + } + + /** + * The layout manager layouts the various + * windows associated with the content assistant based on the + * settings of the content assistant. + */ + class LayoutManager : Listener { + + // Presentation types. + /** proposal selector */ + public const static int LAYOUT_PROPOSAL_SELECTOR= 0; + /** context selector */ + public const static int LAYOUT_CONTEXT_SELECTOR= 1; + /** context info */ + public const static int LAYOUT_CONTEXT_INFO_POPUP= 2; + + int fContextType= LAYOUT_CONTEXT_SELECTOR; + Shell[] fShells= new Shell[3]; + Object[] fPopups= new Object[3]; + + protected void add(Object popup, Shell shell, int type, int offset) { + Assert.isNotNull(popup); + Assert.isTrue(shell !is null && !shell.isDisposed()); + checkType(type); + + if (fShells[type] !is shell) { + if (fShells[type] !is null) + fShells[type].removeListener(DWT.Dispose, this); + shell.addListener(DWT.Dispose, this); + fShells[type]= shell; + } + + fPopups[type]= popup; + if (type is LAYOUT_CONTEXT_SELECTOR || type is LAYOUT_CONTEXT_INFO_POPUP) + fContextType= type; + + layout(type, offset); + adjustListeners(type); + } + + protected void checkType(int type) { + Assert.isTrue(type is LAYOUT_PROPOSAL_SELECTOR || + type is LAYOUT_CONTEXT_SELECTOR || type is LAYOUT_CONTEXT_INFO_POPUP); + } + + public void handleEvent(Event event) { + Widget source= event.widget; + source.removeListener(DWT.Dispose, this); + + int type= getShellType(source); + checkType(type); + fShells[type]= null; + + switch (type) { + case LAYOUT_PROPOSAL_SELECTOR: + if (fContextType is LAYOUT_CONTEXT_SELECTOR && + Helper2.okToUse(fShells[LAYOUT_CONTEXT_SELECTOR])) { + // Restore event notification to the tip popup. + addContentAssistListener(cast(IContentAssistListener2) fPopups[LAYOUT_CONTEXT_SELECTOR], CONTEXT_SELECTOR); + } + break; + + case LAYOUT_CONTEXT_SELECTOR: + if (Helper2.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) { + if (fProposalPopupOrientation is PROPOSAL_STACKED) + layout(LAYOUT_PROPOSAL_SELECTOR, getSelectionOffset()); + // Restore event notification to the proposal popup. + addContentAssistListener(cast(IContentAssistListener2) fPopups[LAYOUT_PROPOSAL_SELECTOR], PROPOSAL_SELECTOR); + } + fContextType= LAYOUT_CONTEXT_INFO_POPUP; + break; + + case LAYOUT_CONTEXT_INFO_POPUP: + if (Helper2.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) { + if (fContextInfoPopupOrientation is CONTEXT_INFO_BELOW) + layout(LAYOUT_PROPOSAL_SELECTOR, getSelectionOffset()); + } + fContextType= LAYOUT_CONTEXT_SELECTOR; + break; + } + } + + protected int getShellType(Widget shell) { + for (int i=0; i displayBounds.width) + location.x= displayBounds.width - shellBounds.width; + + if (location.x < displayBounds.x) + location.x= displayBounds.x; + } + + protected void shiftVerticalLocation(Point location, Rectangle shellBounds, Rectangle displayBounds) { + if (location.y + shellBounds.height > displayBounds.height) + location.y= displayBounds.height - shellBounds.height; + + if (location.y < displayBounds.y) + location.y= displayBounds.y; + } + + protected Point getAboveLocation(Shell shell, int offset) { + StyledText text= fViewer.getTextWidget(); + Point location= text.getLocationAtOffset(offset); + location= text.toDisplay(location); + + Rectangle shellBounds= shell.getBounds(); + Rectangle displayBounds= shell.getDisplay().getClientArea(); + + location.y=location.y - shellBounds.height; + + shiftHorizontalLocation(location, shellBounds, displayBounds); + shiftVerticalLocation(location, shellBounds, displayBounds); + + return location; + } + + protected Point getBelowLocation(Shell shell, int offset) { + StyledText text= fViewer.getTextWidget(); + Point location= text.getLocationAtOffset(offset); + if (location.x < 0) location.x= 0; + if (location.y < 0) location.y= 0; + location= text.toDisplay(location); + + Rectangle shellBounds= shell.getBounds(); + Rectangle displayBounds= shell.getDisplay().getClientArea(); + + location.y= location.y + text.getLineHeight(offset); + shiftHorizontalLocation(location, shellBounds, displayBounds); + shiftVerticalLocation(location, shellBounds, displayBounds); + + return location; + } + + protected Point getStackedLocation(Shell shell, Shell parent) { + Point p= parent.getLocation(); + Point size= parent.getSize(); + p.x += size.x / 4; + p.y += size.y; + + p= parent.toDisplay(p); + + Rectangle shellBounds= shell.getBounds(); + Rectangle displayBounds= shell.getDisplay().getClientArea(); + shiftHorizontalLocation(p, shellBounds, displayBounds); + shiftVerticalLocation(p, shellBounds, displayBounds); + + return p; + } + + protected void adjustListeners(int type) { + switch (type) { + case LAYOUT_PROPOSAL_SELECTOR: + if (fContextType is LAYOUT_CONTEXT_SELECTOR && + Helper2.okToUse(fShells[LAYOUT_CONTEXT_SELECTOR])) + // Disable event notification to the tip selector. + removeContentAssistListener(cast(IContentAssistListener2) fPopups[LAYOUT_CONTEXT_SELECTOR], CONTEXT_SELECTOR); + break; + case LAYOUT_CONTEXT_SELECTOR: + if (Helper2.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) + // Disable event notification to the proposal selector. + removeContentAssistListener(cast(IContentAssistListener2) fPopups[LAYOUT_PROPOSAL_SELECTOR], PROPOSAL_SELECTOR); + break; + case LAYOUT_CONTEXT_INFO_POPUP: + break; + } + } + } + + /** + * Internal key listener and event consumer. + */ + class InternalListener : VerifyKeyListener, IEventConsumer { + + /** + * Verifies key events by notifying the registered listeners. + * Each listener is allowed to indicate that the event has been + * handled and should not be further processed. + * + * @param e the verify event + * @see VerifyKeyListener#verifyKey(dwt.events.VerifyEvent) + */ + public void verifyKey(VerifyEvent e) { + IContentAssistListener2[] listeners= arraycast!(IContentAssistListener2)( fListeners.clone()); + for (int i= 0; i < listeners.length; i++) { + if (listeners[i] !is null) { + if (!listeners[i].verifyKey(e) || !e.doit) + return; + } + } + } + + /* + * @see IEventConsumer#processEvent + */ + public void processEvent(VerifyEvent event) { + + installKeyListener(); + + IContentAssistListener2[] listeners= arraycast!(IContentAssistListener2)(fListeners.clone()); + for (int i= 0; i < listeners.length; i++) { + if (listeners[i] !is null) { + listeners[i].processEvent(event); + if (!event.doit) + return; + } + } + } + } + + + // Content-Assist Listener types + final static int CONTEXT_SELECTOR= 0; + final static int PROPOSAL_SELECTOR= 1; + final static int CONTEXT_INFO_POPUP= 2; + + /** + * The popup priority: > info pop-ups, < standard content assist. + * Default value: 10. + * + * @since 3.0 + */ + public static const int WIDGET_PRIORITY= 10; + + + private static const int DEFAULT_AUTO_ACTIVATION_DELAY= 500; + + private IInformationControlCreator fInformationControlCreator; + private int fAutoActivationDelay= DEFAULT_AUTO_ACTIVATION_DELAY; + private bool fIsAutoActivated= false; + private bool fIsAutoInserting= false; + private int fProposalPopupOrientation= PROPOSAL_OVERLAY; + private int fContextInfoPopupOrientation= CONTEXT_INFO_ABOVE; + private Map fProcessors; + private String fPartitioning; + + private Color fContextInfoPopupBackground; + private Color fContextInfoPopupForeground; + private Color fContextSelectorBackground; + private Color fContextSelectorForeground; + + private ITextViewer fViewer; + private String fLastErrorMessage; + + private Closer fCloser; + private LayoutManager fLayoutManager; + private AutoAssistListener fAutoAssistListener; + private InternalListener fInternalListener; + private CompletionProposalPopup2 fProposalPopup; + private ContextInformationPopup2 fContextInfoPopup; + + private bool fKeyListenerHooked= false; + private IContentAssistListener2[] fListeners= new IContentAssistListener2[4]; + private int fCompletionPosition; + private String[] fProposalStrings; + private ICompletionProposal[] fProposals; + private const List fProposalListeners= new ArrayList(); + + /** + * Tells whether colored label support is enabled. + * @since 3.4 + */ + private bool fIsColoredLabelsSupportEnabled= false; + + + /** + * Creates a new content assistant. The content assistant is not automatically activated, + * overlays the completion proposals with context information list if necessary, and + * shows the context information above the location at which it was activated. If auto + * activation will be enabled, without further configuration steps, this content assistant + * is activated after a 500 ms delay. It uses the default partitioning. + */ + public this() { + setContextInformationPopupOrientation(CONTEXT_INFO_ABOVE); + setInformationControlCreator(getInformationControlCreator()); + +// JavaTextTools textTools= JavaPlugin.getDefault().getJavaTextTools(); +// IColorManager manager= textTools.getColorManager(); +// +// IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); +// +// Color c= getColor(store, PreferenceConstants.CODEASSIST_PROPOSALS_FOREGROUND, manager); +// setProposalSelectorForeground(c); +// +// c= getColor(store, PreferenceConstants.CODEASSIST_PROPOSALS_BACKGROUND, manager); +// setProposalSelectorBackground(c); + } + + /** + * Creates an IInformationControlCreator to be used to display context information. + * + * @return an IInformationControlCreator to be used to display context information + */ + private IInformationControlCreator getInformationControlCreator() { + return new class() IInformationControlCreator { + public IInformationControl createInformationControl(Shell parent) { + return new DefaultInformationControl(parent, false); + } + }; + } + + /** + * Sets the document partitioning this content assistant is using. + * + * @param partitioning the document partitioning for this content assistant + */ + public void setDocumentPartitioning(String partitioning) { + Assert.isNotNull(partitioning); + fPartitioning= partitioning; + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistantExtension#getDocumentPartitioning() + * @since 3.0 + */ + public String getDocumentPartitioning() { + return fPartitioning; + } + + /** + * Registers a given content assist processor for a particular content type. + * If there is already a processor registered for this type, the new processor + * is registered instead of the old one. + * + * @param processor the content assist processor to register, or null to remove an existing one + * @param contentType the content type under which to register + */ + public void setContentAssistProcessor(IContentAssistProcessor processor, String contentType) { + + Assert.isNotNull(contentType); + + if (fProcessors is null) + fProcessors= new HashMap(); + + if (processor is null) + fProcessors.remove(contentType); + else + fProcessors.put(contentType, processor); + } + + /* + * @see IContentAssistant#getContentAssistProcessor + */ + public IContentAssistProcessor getContentAssistProcessor(String contentType) { + if (fProcessors is null) + return null; + + return cast(IContentAssistProcessor) fProcessors.get(contentType); + } + + /** + * Enables the content assistant's auto activation mode. + * + * @param enabled indicates whether auto activation is enabled or not + */ + public void enableAutoActivation(bool enabled) { + fIsAutoActivated= enabled; + manageAutoActivation(fIsAutoActivated); + } + + /** + * Enables the content assistant's auto insertion mode. If enabled, + * the content assistant inserts a proposal automatically if it is + * the only proposal. In the case of ambiguities, the user must + * make the choice. + * + * @param enabled indicates whether auto insertion is enabled or not + * @since 2.0 + */ + public void enableAutoInsert(bool enabled) { + fIsAutoInserting= enabled; + } + + /** + * Returns whether this content assistant is in the auto insertion + * mode or not. + * + * @return true if in auto insertion mode + * @since 2.0 + */ + bool isAutoInserting() { + return fIsAutoInserting; + } + + /** + * Installs and uninstall the listeners needed for auto-activation. + * @param start true if listeners must be installed, + * false if they must be removed + * @since 2.0 + */ + private void manageAutoActivation(bool start) { + if (start) { + + if (fViewer !is null && fAutoAssistListener is null) { + fAutoAssistListener= new AutoAssistListener(); + if ( cast(ITextViewerExtension)fViewer ) { + ITextViewerExtension extension= cast(ITextViewerExtension) fViewer; + extension.appendVerifyKeyListener(fAutoAssistListener); + } else { + StyledText textWidget= fViewer.getTextWidget(); + if (Helper2.okToUse(textWidget)) + textWidget.addVerifyKeyListener(fAutoAssistListener); + } + } + + } else if (fAutoAssistListener !is null) { + + if ( cast(ITextViewerExtension)fViewer ) { + ITextViewerExtension extension= cast(ITextViewerExtension) fViewer; + extension.removeVerifyKeyListener(fAutoAssistListener); + } else { + StyledText textWidget= fViewer.getTextWidget(); + if (Helper2.okToUse(textWidget)) + textWidget.removeVerifyKeyListener(fAutoAssistListener); + } + + fAutoAssistListener= null; + } + } + + /** + * Sets the delay after which the content assistant is automatically invoked + * if the cursor is behind an auto activation character. + * + * @param delay the auto activation delay + */ + public void setAutoActivationDelay(int delay) { + fAutoActivationDelay= delay; + } + + /** + * Sets the proposal pop-ups' orientation. + * The following values may be used: + *
      + *
    • PROPOSAL_OVERLAY

      + * proposal popup windows should overlay each other + *

    • + *
    • PROPOSAL_REMOVE

      + * any currently shown proposal popup should be closed + *

    • + *
    • PROPOSAL_STACKED

      + * proposal popup windows should be vertical stacked, with no overlap, + * beneath the line containing the current cursor location + *

    • + *
    + * + * @param orientation the popup's orientation + */ + public void setProposalPopupOrientation(int orientation) { + fProposalPopupOrientation= orientation; + } + + /** + * Sets the context information popup's orientation. + * The following values may be used: + *
      + *
    • CONTEXT_ABOVE

      + * context information popup should always appear above the line containing + * the current cursor location + *

    • + *
    • CONTEXT_BELOW

      + * context information popup should always appear below the line containing + * the current cursor location + *

    • + *
    + * + * @param orientation the popup's orientation + */ + public void setContextInformationPopupOrientation(int orientation) { + fContextInfoPopupOrientation= orientation; + } + + /** + * Sets the context information popup's background color. + * + * @param background the background color + */ + public void setContextInformationPopupBackground(Color background) { + fContextInfoPopupBackground= background; + } + + /** + * Returns the background of the context information popup. + * + * @return the background of the context information popup + * @since 2.0 + */ + Color getContextInformationPopupBackground() { + return fContextInfoPopupBackground; + } + + /** + * Sets the context information popup's foreground color. + * + * @param foreground the foreground color + * @since 2.0 + */ + public void setContextInformationPopupForeground(Color foreground) { + fContextInfoPopupForeground= foreground; + } + + /** + * Returns the foreground of the context information popup. + * + * @return the foreground of the context information popup + * @since 2.0 + */ + Color getContextInformationPopupForeground() { + return fContextInfoPopupForeground; + } + + /** + * Sets the context selector's background color. + * + * @param background the background color + * @since 2.0 + */ + public void setContextSelectorBackground(Color background) { + fContextSelectorBackground= background; + } + + /** + * Returns the background of the context selector. + * + * @return the background of the context selector + * @since 2.0 + */ + Color getContextSelectorBackground() { + return fContextSelectorBackground; + } + + /** + * Sets the context selector's foreground color. + * + * @param foreground the foreground color + * @since 2.0 + */ + public void setContextSelectorForeground(Color foreground) { + fContextSelectorForeground= foreground; + } + + /** + * Returns the foreground of the context selector. + * + * @return the foreground of the context selector + * @since 2.0 + */ + Color getContextSelectorForeground() { + return fContextSelectorForeground; + } + + /** + * Sets the information control creator for the additional information control. + * + * @param creator the information control creator for the additional information control + * @since 2.0 + */ + public void setInformationControlCreator(IInformationControlCreator creator) { + fInformationControlCreator= creator; + } + + /* + * @see IContentAssist#install + */ + public void install(ITextViewer textViewer) { + Assert.isNotNull(textViewer); + + fViewer= textViewer; + + fLayoutManager= new LayoutManager(); + fInternalListener= new InternalListener(); + + AdditionalInfoController2 controller= null; + if (fInformationControlCreator !is null) { + int delay= fAutoActivationDelay; + if (delay is 0) + delay= DEFAULT_AUTO_ACTIVATION_DELAY; + delay= Math.round(delay * 1.5f); + controller= new AdditionalInfoController2(fInformationControlCreator, delay); + } + fContextInfoPopup= new ContextInformationPopup2(this, fViewer); + fProposalPopup= new CompletionProposalPopup2(this, fViewer, controller); + + manageAutoActivation(fIsAutoActivated); + } + + /* + * @see IContentAssist#uninstall + */ + public void uninstall() { + + if (fProposalPopup !is null) + fProposalPopup.hide(); + + if (fContextInfoPopup !is null) + fContextInfoPopup.hide(); + + manageAutoActivation(false); + + if (fCloser !is null) { + fCloser.uninstall(); + fCloser= null; + } + + fViewer= null; + } + + /** + * Adds the given shell of the specified type to the layout. + * Valid types are defined by LayoutManager. + * + * @param popup a content assist popup + * @param shell the shell of the content-assist popup + * @param type the type of popup + * @param visibleOffset the offset at which to layout the popup relative to the offset of the viewer's visible region + * @since 2.0 + */ + void addToLayout(Object popup, Shell shell, int type, int visibleOffset) { + fLayoutManager.add(popup, shell, type, visibleOffset); + } + + /** + * Layouts the registered popup of the given type relative to the + * given offset. The offset is relative to the offset of the viewer's visible region. + * Valid types are defined by LayoutManager. + * + * @param type the type of popup to layout + * @param visibleOffset the offset at which to layout relative to the offset of the viewer's visible region + * @since 2.0 + */ + void layout(int type, int visibleOffset) { + fLayoutManager.layout(type, visibleOffset); + } + + /** + * Notifies the controller that a popup has lost focus. + * + * @param e the focus event + */ + void popupFocusLost(FocusEvent e) { + fCloser.focusLost(e); + } + + /** + * Returns the offset of the selection relative to the offset of the visible region. + * + * @return the offset of the selection relative to the offset of the visible region + * @since 2.0 + */ + int getSelectionOffset() { + StyledText text= fViewer.getTextWidget(); + return text.getSelectionRange().x; + } + + /** + * Returns whether the widget token could be acquired. + * The following are valid listener types: + *
      + *
    • AUTO_ASSIST + *
    • CONTEXT_SELECTOR + *
    • PROPOSAL_SELECTOR + *
    • CONTEXT_INFO_POPUP + *
        + * @param type the listener type for which to acquire + * @return true if the widget token could be acquired + * @since 2.0 + */ + private bool acquireWidgetToken(int type) { + switch (type) { + case CONTEXT_SELECTOR: + case PROPOSAL_SELECTOR: + if ( cast(IWidgetTokenOwner)fViewer ) { + IWidgetTokenOwner owner= cast(IWidgetTokenOwner) fViewer; + return owner.requestWidgetToken(this); + } else if ( cast(IWidgetTokenOwnerExtension)fViewer ) { + IWidgetTokenOwnerExtension extension= cast(IWidgetTokenOwnerExtension) fViewer; + return extension.requestWidgetToken(this, WIDGET_PRIORITY); + } + } + return true; + } + + /** + * Registers a content assist listener. + * The following are valid listener types: + *
          + *
        • AUTO_ASSIST + *
        • CONTEXT_SELECTOR + *
        • PROPOSAL_SELECTOR + *
        • CONTEXT_INFO_POPUP + *
            + * Returns whether the listener could be added successfully. A listener + * can not be added if the widget token could not be acquired. + * + * @param listener the listener to register + * @param type the type of listener + * @return true if the listener could be added + */ + bool addContentAssistListener(IContentAssistListener2 listener, int type) { + + if (acquireWidgetToken(type)) { + + fListeners[type]= listener; + + if (getNumberOfListeners() is 1) { + fCloser= new Closer(); + fCloser.install(); + fViewer.setEventConsumer(fInternalListener); + installKeyListener(); + } + return true; + } + + return false; + } + + /** + * Installs a key listener on the text viewer's widget. + */ + private void installKeyListener() { + if (!fKeyListenerHooked) { + StyledText text= fViewer.getTextWidget(); + if (Helper2.okToUse(text)) { + + if ( cast(ITextViewerExtension)fViewer ) { + ITextViewerExtension e= cast(ITextViewerExtension) fViewer; + e.prependVerifyKeyListener(fInternalListener); + } else { + text.addVerifyKeyListener(fInternalListener); + } + + fKeyListenerHooked= true; + } + } + } + + /** + * Releases the previously acquired widget token if the token + * is no longer necessary. + * The following are valid listener types: + *
              + *
            • AUTO_ASSIST + *
            • CONTEXT_SELECTOR + *
            • PROPOSAL_SELECTOR + *
            • CONTEXT_INFO_POPUP + *
                + * + * @param type the listener type + * @since 2.0 + */ + private void releaseWidgetToken(int type) { + if (fListeners[CONTEXT_SELECTOR] is null && fListeners[PROPOSAL_SELECTOR] is null) { + if ( cast(IWidgetTokenOwner)fViewer ) { + IWidgetTokenOwner owner= cast(IWidgetTokenOwner) fViewer; + owner.releaseWidgetToken(this); + } + } + } + + /** + * Unregisters a content assist listener. + * + * @param listener the listener to unregister + * @param type the type of listener + * + * @see #addContentAssistListener + */ + void removeContentAssistListener(IContentAssistListener2 listener, int type) { + fListeners[type]= null; + + if (getNumberOfListeners() is 0) { + + if (fCloser !is null) { + fCloser.uninstall(); + fCloser= null; + } + + uninstallKeyListener(); + fViewer.setEventConsumer(null); + } + + releaseWidgetToken(type); + } + + /** + * Uninstall the key listener from the text viewer's widget. + */ + private void uninstallKeyListener() { + if (fKeyListenerHooked) { + StyledText text= fViewer.getTextWidget(); + if (Helper2.okToUse(text)) { + + if ( cast(ITextViewerExtension)fViewer ) { + ITextViewerExtension e= cast(ITextViewerExtension) fViewer; + e.removeVerifyKeyListener(fInternalListener); + } else { + text.removeVerifyKeyListener(fInternalListener); + } + + fKeyListenerHooked= false; + } + } + } + + /** + * Returns the number of listeners. + * + * @return the number of listeners + * @since 2.0 + */ + private int getNumberOfListeners() { + int count= 0; + for (int i= 0; i <= CONTEXT_INFO_POPUP; i++) { + if (fListeners[i] !is null) + ++ count; + } + return count; + } + + /* + * @see IContentAssist#showPossibleCompletions + */ + public String showPossibleCompletions() { + return fProposalPopup.showProposals(false); + } + + /** + * Hides the proposal popup. + */ + public void hidePossibleCompletions() { + if (fProposalPopup !is null) + fProposalPopup.hide(); + } + + /** + * Hides any open pop-ups. + */ + protected void hide() { + if (fProposalPopup !is null) + fProposalPopup.hide(); + if (fContextInfoPopup !is null) + fContextInfoPopup.hide(); + } + package void hide_package() { + hide(); + } + + /** + * Callback to signal this content assistant that the presentation of the possible completions has been stopped. + * @since 2.1 + */ + protected void possibleCompletionsClosed() { + } + package void possibleCompletionsClosed_package(){ + possibleCompletionsClosed(); + } + /* + * @see IContentAssist#showContextInformation + */ + public String showContextInformation() { + return fContextInfoPopup.showContextProposals(false); + } + + + /** + * Callback to signal this content assistant that the presentation of the context information has been stopped. + * @since 2.1 + */ + protected void contextInformationClosed() { + } + package void contextInformationClosed_package() { + contextInformationClosed(); + } + + /** + * Requests that the specified context information to be shown. + * + * @param contextInformation the context information to be shown + * @param position the position to which the context information refers to + * @since 2.0 + */ + void showContextInformation(IContextInformation contextInformation, int position) { + fContextInfoPopup.showContextInformation(contextInformation, position); + } + + /** + * Returns the current content assist error message. + * + * @return an error message or null if no error has occurred + */ + String getErrorMessage() { + return fLastErrorMessage; + } + + /** + * Returns the content assist processor for the content + * type of the specified document position. + * + * @param viewer the text viewer + * @param offset a offset within the document + * @return a content-assist processor or null if none exists + */ + private IContentAssistProcessor getProcessor(ITextViewer viewer, int offset) { + try { + String type= TextUtilities.getContentType(viewer.getDocument(), getDocumentPartitioning(), offset, true); + return getContentAssistProcessor(type); + } catch (BadLocationException x) { + } + return null; + } + + /** + * Returns an array of completion proposals computed based on + * the specified document position. The position is used to + * determine the appropriate content assist processor to invoke. + * + * @param viewer the viewer for which to compute the proposals + * @param position a document position + * @return an array of completion proposals + * + * @see IContentAssistProcessor#computeCompletionProposals + */ + ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int position) { + if (fProposals !is null) { + return fProposals; + } else if (fProposalStrings !is null) { + ICompletionProposal[] result= new ICompletionProposal[fProposalStrings.length]; + for (int i= 0; i < fProposalStrings.length; i++) { + result[i]= new CompletionProposal(fProposalStrings[i], position, fProposalStrings[i].length(), fProposalStrings[i].length()); + } + return result; + } else return null; + } + + /** + * Returns an array of context information objects computed based + * on the specified document position. The position is used to determine + * the appropriate content assist processor to invoke. + * + * @param viewer the viewer for which to compute the context information + * @param position a document position + * @return an array of context information objects + * + * @see IContentAssistProcessor#computeContextInformation + */ + IContextInformation[] computeContextInformation(ITextViewer viewer, int position) { + fLastErrorMessage= null; + + IContextInformation[] result= null; + + IContentAssistProcessor p= getProcessor(viewer, position); + if (p !is null) { + result= p.computeContextInformation(viewer, position); + fLastErrorMessage= p.getErrorMessage(); + } + + return result; + } + + /** + * Returns the context information validator that should be used to + * determine when the currently displayed context information should + * be dismissed. The position is used to determine the appropriate + * content assist processor to invoke. + * + * @param textViewer the text viewer + * @param offset a document offset + * @return an validator + * + * @see IContentAssistProcessor#getContextInformationValidator + */ + IContextInformationValidator getContextInformationValidator(ITextViewer textViewer, int offset) { + IContentAssistProcessor p= getProcessor(textViewer, offset); + return p !is null ? p.getContextInformationValidator() : null; + } + + /** + * Returns the context information presenter that should be used to + * display context information. The position is used to determine the appropriate + * content assist processor to invoke. + * + * @param textViewer the text viewer + * @param offset a document offset + * @return a presenter + * @since 2.0 + */ + IContextInformationPresenter getContextInformationPresenter(ITextViewer textViewer, int offset) { + IContextInformationValidator validator= getContextInformationValidator(textViewer, offset); + if ( cast(IContextInformationPresenter)validator ) + return cast(IContextInformationPresenter) validator; + return null; + } + + /** + * Returns the characters which when typed by the user should automatically + * initiate proposing completions. The position is used to determine the + * appropriate content assist processor to invoke. + * + * @param textViewer the text viewer + * @param offset a document offset + * @return the auto activation characters + * + * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters + */ + private char[] getCompletionProposalAutoActivationCharacters(ITextViewer textViewer, int offset) { + IContentAssistProcessor p= getProcessor(textViewer, offset); + return p !is null ? p.getCompletionProposalAutoActivationCharacters() : null; + } + + /** + * Returns the characters which when typed by the user should automatically + * initiate the presentation of context information. The position is used + * to determine the appropriate content assist processor to invoke. + * + * @param textViewer the text viewer + * @param offset a document offset + * @return the auto activation characters + * + * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters + */ + private char[] getContextInformationAutoActivationCharacters(ITextViewer textViewer, int offset) { + IContentAssistProcessor p= getProcessor(textViewer, offset); + return p !is null ? p.getContextInformationAutoActivationCharacters() : null; + } + + /* + * @see dwtx.jface.text.IWidgetTokenKeeper#requestWidgetToken(IWidgetTokenOwner) + * @since 2.0 + */ + public bool requestWidgetToken(IWidgetTokenOwner owner) { + hidePossibleCompletions(); + return true; + } + + /** + * @param completionPosition + */ + public void setCompletionPosition(int completionPosition) { + fCompletionPosition= completionPosition; + } + + /** + * @return the completion position + */ + public int getCompletionPosition() { + return fCompletionPosition; + } + + /** + * @param proposals + */ + public void setCompletions(String[] proposals) { + fProposalStrings= proposals; + } + + /** + * @param proposals + */ + public void setCompletions(ICompletionProposal[] proposals) { + fProposals= proposals; + } + + /* + * @see dwtx.jface.text.IWidgetTokenKeeperExtension#requestWidgetToken(dwtx.jface.text.IWidgetTokenOwner, int) + * @since 3.0 + */ + public bool requestWidgetToken(IWidgetTokenOwner owner, int priority) { + if (priority > WIDGET_PRIORITY) { + hidePossibleCompletions(); + return true; + } + return false; + } + + /* + * @see dwtx.jface.text.IWidgetTokenKeeperExtension#setFocus(dwtx.jface.text.IWidgetTokenOwner) + * @since 3.0 + */ + public bool setFocus(IWidgetTokenOwner owner) { + if (fProposalPopup !is null) { + fProposalPopup.setFocus(); + return fProposalPopup.hasFocus(); + } + return false; + } + + /** + * Returns whether any popups controlled by the receiver have the input focus. + * + * @return true if any of the managed popups have the focus, false otherwise + */ + public bool hasFocus() { + return (fProposalPopup !is null && fProposalPopup.hasFocus()) + || (fContextInfoPopup !is null && fContextInfoPopup.hasFocus()); + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistantExtension#completePrefix() + */ + public String completePrefix() { + return null; + } + + /** + * @param proposal + */ + public void fireProposalChosen(ICompletionProposal proposal) { + List list= new ArrayList(fProposalListeners); + for (Iterator it= list.iterator(); it.hasNext();) { + IProposalListener listener= cast(IProposalListener) it.next(); + listener.proposalChosen(proposal); + } + + } + + /** + * @param listener + */ + public void removeProposalListener(IProposalListener listener) { + fProposalListeners.remove(listener); + } + + /** + * @param listener + */ + public void addProposalListener(IProposalListener listener) { + fProposalListeners.add(listener); + } + + /** + * Tells whether the support for colored labels is enabled. + * + * @return true if the support for colored labels is enabled, false otherwise + * @since 3.4 + */ + bool isColoredLabelsSupportEnabled() { + return fIsColoredLabelsSupportEnabled; + } + + /** + * Enables the support for colored labels in the proposal popup. + *

                Completion proposals can implement {@link ICompletionProposalExtension6} + * to provide colored proposal labels.

                + * + * @param isEnabled if true the support for colored labels is enabled in the proposal popup + * @since 3.4 + */ + public void enableColoredLabels(bool isEnabled) { + fIsColoredLabelsSupportEnabled= isEnabled; + } +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/link/contentassist/ContextInformationPopup2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/link/contentassist/ContextInformationPopup2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,647 @@ +/******************************************************************************* + * 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 + * 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.text.link.contentassist.ContextInformationPopup2; + +import dwtx.jface.internal.text.link.contentassist.IProposalListener; // packageimport +import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; // packageimport +import dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContentAssistMessages; // packageimport +import dwtx.jface.internal.text.link.contentassist.Helper2; // packageimport +import dwtx.jface.internal.text.link.contentassist.PopupCloser2; // packageimport +import dwtx.jface.internal.text.link.contentassist.IContentAssistListener2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; // packageimport +import dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2; // packageimport + +import dwt.dwthelper.utils; + + +import dwtx.dwtxhelper.Collection; + +import dwt.DWT; +import dwt.custom.BusyIndicator; +import dwt.custom.StyledText; +import dwt.events.KeyEvent; +import dwt.events.SelectionEvent; +import dwt.events.SelectionListener; +import dwt.events.VerifyEvent; +import dwt.graphics.Color; +import dwt.graphics.Point; +import dwt.layout.GridData; +import dwt.layout.GridLayout; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Shell; +import dwt.widgets.Table; +import dwt.widgets.TableItem; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.TextPresentation; +import dwtx.jface.text.contentassist.IContextInformation; +import dwtx.jface.text.contentassist.IContextInformationExtension; +import dwtx.jface.text.contentassist.IContextInformationPresenter; +import dwtx.jface.text.contentassist.IContextInformationValidator; + + +/** + * This class is used to present context information to the user. + * If multiple contexts are valid at the current cursor location, + * a list is presented from which the user may choose one context. + * Once the user makes their choice, or if there was only a single + * possible context, the context information is shown in a tooltip like popup.

                + * If the tooltip is visible and the user wants to see context information of + * a context embedded into the one for which context information is displayed, + * context information for the embedded context is shown. As soon as the + * cursor leaves the embedded context area, the context information for + * the embedding context is shown again. + * + * @see IContextInformation + * @see IContextInformationValidator + */ +class ContextInformationPopup2 : IContentAssistListener2 { + + + + /** + * Represents the state necessary for embedding contexts. + * @since 2.0 + */ + static class ContextFrame { + public int fBeginOffset; + public int fOffset; + public int fVisibleOffset; + public IContextInformation fInformation; + public IContextInformationValidator fValidator; + public IContextInformationPresenter fPresenter; + } + + private ITextViewer fViewer; + private ContentAssistant2 fContentAssistant; + + private PopupCloser2 fPopupCloser; + private Shell fContextSelectorShell; + private Table fContextSelectorTable; + private IContextInformation[] fContextSelectorInput; + private String fLineDelimiter= null; + + private Shell fContextInfoPopup; + private StyledText fContextInfoText; + private TextPresentation fTextPresentation; + + private Stack fContextFrameStack; + + + /** + * Creates a new context information popup. + * + * @param contentAssistant the content assist for computing the context information + * @param viewer the viewer on top of which the context information is shown + */ + public this(ContentAssistant2 contentAssistant, ITextViewer viewer) { + fPopupCloser= new PopupCloser2(); + fContextFrameStack= new Stack(); + fContentAssistant= contentAssistant; + fViewer= viewer; + } + + /** + * Shows all possible contexts for the given cursor position of the viewer. + * + * @param autoActivated true if auto activated + * @return a potential error message or null in case of no error + */ + public String showContextProposals(bool autoActivated) { + final StyledText styledText= fViewer.getTextWidget(); + BusyIndicator.showWhile(styledText.getDisplay(), dgRunnable( (bool autoActivated_, StyledText styledText_ ) { + int position= fViewer.getSelectedRange().x; + + IContextInformation[] contexts= computeContextInformation(position); + int count = (contexts is null ? 0 : contexts.length); + if (count is 1) { + + // Show context information directly + internalShowContextInfo(contexts[0], position); + + } else if (count > 0) { + // Precise context must be selected + + if (fLineDelimiter is null) + fLineDelimiter= styledText_.getLineDelimiter(); + + createContextSelector(); + setContexts(contexts); + displayContextSelector(); + hideContextInfoPopup(); + + } else if (!autoActivated_) { + styledText_.getDisplay().beep(); + } + }, autoActivated, styledText )); + + return getErrorMessage(); + } + + /** + * Displays the given context information for the given offset. + * + * @param info the context information + * @param position the offset + * @since 2.0 + */ + public void showContextInformation(IContextInformation info, int position) { + Control control= fViewer.getTextWidget(); + BusyIndicator.showWhile(control.getDisplay(), dgRunnable( (IContextInformation info_, int position_) { + internalShowContextInfo(info_, position_); + hideContextSelector(); + }, info, position)); + } + + /** + * Displays the given context information for the given offset. + * + * @param information the context information + * @param offset the offset + * @since 2.0 + */ + + private void internalShowContextInfo(IContextInformation information, int offset) { + + IContextInformationValidator validator= fContentAssistant.getContextInformationValidator(fViewer, offset); + + if (validator !is null) { + ContextFrame current= new ContextFrame(); + current.fInformation= information; + current.fBeginOffset= ( cast(IContextInformationExtension)information ) ? (cast(IContextInformationExtension) information).getContextInformationPosition() : offset; + if (current.fBeginOffset is -1) current.fBeginOffset= offset; + current.fOffset= offset; + current.fVisibleOffset= fViewer.getTextWidget().getSelectionRange().x - (offset - current.fBeginOffset); + current.fValidator= validator; + current.fPresenter= fContentAssistant.getContextInformationPresenter(fViewer, offset); + + fContextFrameStack.push(current); + + internalShowContextFrame(current, fContextFrameStack.size() is 1); + } + } + + /** + * Shows the given context frame. + * + * @param frame the frane to display + * @param initial true if this is the first frame to be displayed + * @since 2.0 + */ + private void internalShowContextFrame(ContextFrame frame, bool initial) { + + frame.fValidator.install(frame.fInformation, fViewer, frame.fOffset); + + if (frame.fPresenter !is null) { + if (fTextPresentation is null) + fTextPresentation= new TextPresentation(); + frame.fPresenter.install(frame.fInformation, fViewer, frame.fBeginOffset); + frame.fPresenter.updatePresentation(frame.fOffset, fTextPresentation); + } + + createContextInfoPopup(); + + fContextInfoText.setText(frame.fInformation.getInformationDisplayString()); + if (fTextPresentation !is null) + TextPresentation.applyTextPresentation(fTextPresentation, fContextInfoText); + resize(); + + if (initial) { + if (fContentAssistant.addContentAssistListener(this, ContentAssistant2.CONTEXT_INFO_POPUP)) { + fContentAssistant.addToLayout(this, fContextInfoPopup, ContentAssistant2.LayoutManager.LAYOUT_CONTEXT_INFO_POPUP, frame.fVisibleOffset); + fContextInfoPopup.setVisible(true); + } + } else { + fContentAssistant.layout(ContentAssistant2.LayoutManager.LAYOUT_CONTEXT_INFO_POPUP, frame.fVisibleOffset); + } + } + + /** + * Computes all possible context information for the given offset. + * + * @param position the offset + * @return all possible context information for the given offset + * @since 2.0 + */ + private IContextInformation[] computeContextInformation(int position) { + return fContentAssistant.computeContextInformation(fViewer, position); + } + + /** + *Returns the error message generated while computing context information. + * + * @return the error message + */ + private String getErrorMessage() { + return fContentAssistant.getErrorMessage(); + } + + /** + * Creates the context information popup. This is the tooltip like overlay window. + */ + private void createContextInfoPopup() { + if (Helper2.okToUse(fContextInfoPopup)) + return; + + Control control= fViewer.getTextWidget(); + Display display= control.getDisplay(); + + fContextInfoPopup= new Shell(control.getShell(), DWT.NO_TRIM | DWT.ON_TOP); + fContextInfoPopup.setBackground(display.getSystemColor(DWT.COLOR_BLACK)); + + fContextInfoText= new StyledText(fContextInfoPopup, DWT.MULTI | DWT.READ_ONLY); + + Color c= fContentAssistant.getContextInformationPopupBackground(); + if (c is null) + c= display.getSystemColor(DWT.COLOR_INFO_BACKGROUND); + fContextInfoText.setBackground(c); + + c= fContentAssistant.getContextInformationPopupForeground(); + if (c is null) + c= display.getSystemColor(DWT.COLOR_INFO_FOREGROUND); + fContextInfoText.setForeground(c); + } + + /** + * Resizes the context information popup. + * @since 2.0 + */ + private void resize() { + Point size= fContextInfoText.computeSize(DWT.DEFAULT, DWT.DEFAULT, true); + size.x += 3; + fContextInfoText.setSize(size); + fContextInfoText.setLocation(1,1); + size.x += 2; + size.y += 2; + fContextInfoPopup.setSize(size); + } + + /** + *Hides the context information popup. + */ + private void hideContextInfoPopup() { + + if (Helper2.okToUse(fContextInfoPopup)) { + + int size= fContextFrameStack.size(); + if (size > 0) { + fContextFrameStack.pop(); + -- size; + } + + if (size > 0) { + ContextFrame current= cast(ContextFrame) fContextFrameStack.peek(); + internalShowContextFrame(current, false); + } else { + + fContentAssistant.removeContentAssistListener(this, ContentAssistant2.CONTEXT_INFO_POPUP); + + fContextInfoPopup.setVisible(false); + fContextInfoPopup.dispose(); + fContextInfoPopup= null; + + if (fTextPresentation !is null) { + fTextPresentation.clear(); + fTextPresentation= null; + } + } + } + + if (fContextInfoPopup is null) + fContentAssistant.contextInformationClosed_package(); + } + + /** + * Creates the context selector in case the user has the choice between multiple valid contexts + * at a given offset. + */ + private void createContextSelector() { + if (Helper2.okToUse(fContextSelectorShell)) + return; + + Control control= fViewer.getTextWidget(); + fContextSelectorShell= new Shell(control.getShell(), DWT.NO_TRIM | DWT.ON_TOP); + GridLayout layout= new GridLayout(); + layout.marginWidth= 0; + layout.marginHeight= 0; + fContextSelectorShell.setLayout(layout); + fContextSelectorShell.setBackground(control.getDisplay().getSystemColor(DWT.COLOR_BLACK)); + + + fContextSelectorTable= new Table(fContextSelectorShell, DWT.H_SCROLL | DWT.V_SCROLL); + fContextSelectorTable.setLocation(1, 1); + GridData gd= new GridData(GridData.FILL_BOTH); + gd.heightHint= fContextSelectorTable.getItemHeight() * 10; + gd.widthHint= 300; + fContextSelectorTable.setLayoutData(gd); + + fContextSelectorShell.pack(true); + + Color c= fContentAssistant.getContextSelectorBackground(); + if (c is null) + c= control.getDisplay().getSystemColor(DWT.COLOR_INFO_BACKGROUND); + fContextSelectorTable.setBackground(c); + + c= fContentAssistant.getContextSelectorForeground(); + if (c is null) + c= control.getDisplay().getSystemColor(DWT.COLOR_INFO_FOREGROUND); + fContextSelectorTable.setForeground(c); + + fContextSelectorTable.addSelectionListener(new class() SelectionListener { + public void widgetSelected(SelectionEvent e) { + } + + public void widgetDefaultSelected(SelectionEvent e) { + insertSelectedContext(); + hideContextSelector(); + } + }); + + fPopupCloser.install(fContentAssistant, fContextSelectorTable); + + fContextSelectorTable.setHeaderVisible(false); + fContentAssistant.addToLayout(this, fContextSelectorShell, ContentAssistant2.LayoutManager.LAYOUT_CONTEXT_SELECTOR, fContentAssistant.getSelectionOffset()); + } + + /** + * Causes the context information of the context selected in the context selector + * to be displayed in the context information popup. + */ + private void insertSelectedContext() { + int i= fContextSelectorTable.getSelectionIndex(); + + if (i < 0 || i >= fContextSelectorInput.length) + return; + + int position= fViewer.getSelectedRange().x; + internalShowContextInfo(fContextSelectorInput[i], position); + } + + /** + * Sets the contexts in the context selector to the given set. + * + * @param contexts the possible contexts + */ + private void setContexts(IContextInformation[] contexts) { + if (Helper2.okToUse(fContextSelectorTable)) { + + fContextSelectorInput= contexts; + + fContextSelectorTable.setRedraw(false); + fContextSelectorTable.removeAll(); + + TableItem item; + IContextInformation t; + for (int i= 0; i < contexts.length; i++) { + t= contexts[i]; + item= new TableItem(fContextSelectorTable, DWT.NULL); + if (t.getImage() !is null) + item.setImage(t.getImage()); + item.setText(t.getContextDisplayString()); + } + + fContextSelectorTable.select(0); + fContextSelectorTable.setRedraw(true); + } + } + + /** + * Displays the context selector. + */ + private void displayContextSelector() { + if (fContentAssistant.addContentAssistListener(this, ContentAssistant2.CONTEXT_SELECTOR)) + fContextSelectorShell.setVisible(true); + } + + /** + * Hodes the context selector. + */ + private void hideContextSelector() { + if (Helper2.okToUse(fContextSelectorShell)) { + fContentAssistant.removeContentAssistListener(this, ContentAssistant2.CONTEXT_SELECTOR); + + fPopupCloser.uninstall(); + fContextSelectorShell.setVisible(false); + fContextSelectorShell.dispose(); + fContextSelectorShell= null; + } + + if (!Helper2.okToUse(fContextInfoPopup)) + fContentAssistant.contextInformationClosed_package(); + } + + /** + *Returns whether the context selector has the focus. + * + * @return true if teh context selector has the focus + */ + public bool hasFocus() { + if (Helper2.okToUse(fContextSelectorShell)) + return (fContextSelectorShell.isFocusControl() || fContextSelectorTable.isFocusControl()); + + return false; + } + + /** + * Hides context selector and context information popup. + */ + public void hide() { + hideContextSelector(); + hideContextInfoPopup(); + } + + /** + * Returns whether this context information popup is active. I.e., either + * a context selector or context information is displayed. + * + * @return true if the context selector is active + */ + public bool isActive() { + return (Helper2.okToUse(fContextInfoPopup) || Helper2.okToUse(fContextSelectorShell)); + } + + /* + * @see IContentAssistListener#verifyKey(VerifyEvent) + */ + public bool verifyKey(VerifyEvent e) { + if (Helper2.okToUse(fContextSelectorShell)) + return contextSelectorKeyPressed(e); + if (Helper2.okToUse(fContextInfoPopup)) + return contextInfoPopupKeyPressed(e); + return true; + } + + /** + * Processes a key stroke in the context selector. + * + * @param e the verify event describing the key stroke + * @return true if processing can be stopped + */ + private bool contextSelectorKeyPressed(VerifyEvent e) { + + char key= e.character; + if (key is 0) { + + int change; + int visibleRows= (fContextSelectorTable.getSize().y / fContextSelectorTable.getItemHeight()) - 1; + int selection= fContextSelectorTable.getSelectionIndex(); + + switch (e.keyCode) { + + case DWT.ARROW_UP: + change= (fContextSelectorTable.getSelectionIndex() > 0 ? -1 : 0); + break; + + case DWT.ARROW_DOWN: + change= (fContextSelectorTable.getSelectionIndex() < fContextSelectorTable.getItemCount() - 1 ? 1 : 0); + break; + + case DWT.PAGE_DOWN : + change= visibleRows; + if (selection + change >= fContextSelectorTable.getItemCount()) + change= fContextSelectorTable.getItemCount() - selection; + break; + + case DWT.PAGE_UP : + change= -visibleRows; + if (selection + change < 0) + change= -selection; + break; + + case DWT.HOME : + change= -selection; + break; + + case DWT.END : + change= fContextSelectorTable.getItemCount() - selection; + break; + + default: + if (e.keyCode !is DWT.MOD1 && e.keyCode !is DWT.MOD2 && e.keyCode !is DWT.MOD3 && e.keyCode !is DWT.MOD4) + hideContextSelector(); + return true; + } + + fContextSelectorTable.setSelection(selection + change); + fContextSelectorTable.showSelection(); + e.doit= false; + return false; + + } else if ('\t' is key) { + // switch focus to selector shell + e.doit= false; + fContextSelectorShell.setFocus(); + return false; + } else if (key is DWT.ESC) { + e.doit= false; + hideContextSelector(); + } + + return true; + } + + /** + * Processes a key stroke while the info popup is up. + * + * @param e the verify event describing the key stroke + * @return true if processing can be stopped + */ + private bool contextInfoPopupKeyPressed(KeyEvent e) { + + char key= e.character; + if (key is 0) { + + switch (e.keyCode) { + case DWT.ARROW_LEFT: + case DWT.ARROW_RIGHT: + validateContextInformation(); + break; + default: + if (e.keyCode !is DWT.MOD1 && e.keyCode !is DWT.MOD2 && e.keyCode !is DWT.MOD3 && e.keyCode !is DWT.MOD4) + hideContextInfoPopup(); + break; + } + + } else if (key is DWT.ESC) { + e.doit= false; + hideContextInfoPopup(); + } else { + validateContextInformation(); + } + return true; + } + + /* + * @see IEventConsumer#processEvent(VerifyEvent) + */ + public void processEvent(VerifyEvent event) { + if (Helper2.okToUse(fContextSelectorShell)) + contextSelectorProcessEvent(event); + if (Helper2.okToUse(fContextInfoPopup)) + contextInfoPopupProcessEvent(event); + } + + /** + * Processes a key stroke in the context selector. + * + * @param e the verify event describing the key stroke + */ + private void contextSelectorProcessEvent(VerifyEvent e) { + + if (e.start is e.end && e.text !is null && e.text.equals(fLineDelimiter)) { + e.doit= false; + insertSelectedContext(); + } + + hideContextSelector(); + } + + /** + * Processes a key stroke while the info popup is up. + * + * @param e the verify event describing the key stroke + */ + private void contextInfoPopupProcessEvent(VerifyEvent e) { + if (e.start !is e.end && (e.text is null || e.text.length() is 0)) + validateContextInformation(); + } + + /** + * Validates the context information for the viewer's actual cursor position. + */ + private void validateContextInformation() { + /* + * Post the code in the event queue in order to ensure that the + * action described by this verify key event has already beed executed. + * Otherwise, we'd validate the context information based on the + * pre-key-stroke state. + */ + fContextInfoPopup.getDisplay().asyncExec(dgRunnable( (ContextFrame fFrame_) { + + ContextFrame fFrame= fFrame_; + + if (Helper2.okToUse(fContextInfoPopup) && fFrame is fContextFrameStack.peek()) { + int offset= fViewer.getSelectedRange().x; + if (fFrame.fValidator is null || !fFrame.fValidator.isContextInformationValid(offset)) { + hideContextInfoPopup(); + } else if (fFrame.fPresenter !is null && fFrame.fPresenter.updatePresentation(offset, fTextPresentation)) { + TextPresentation.applyTextPresentation(fTextPresentation, fContextInfoText); + resize(); + } + } + }, cast(ContextFrame) fContextFrameStack.peek())); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/link/contentassist/Helper2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/link/contentassist/Helper2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.internal.text.link.contentassist.Helper2; + +import dwtx.jface.internal.text.link.contentassist.IProposalListener; // packageimport +import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; // packageimport +import dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContentAssistMessages; // packageimport +import dwtx.jface.internal.text.link.contentassist.PopupCloser2; // packageimport +import dwtx.jface.internal.text.link.contentassist.IContentAssistListener2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; // packageimport +import dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2; // packageimport + + +import dwt.dwthelper.utils; + + + +import dwt.widgets.Widget; + + +/** + * Helper class for testing widget state. + */ +class Helper2 { + + /** + * Returns whether the widget is null or disposed. + * + * @param widget the widget to check + * @return true if the widget is neither null nor disposed + */ + public static bool okToUse(Widget widget) { + return (widget !is null && !widget.isDisposed()); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/link/contentassist/IContentAssistListener2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/link/contentassist/IContentAssistListener2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.internal.text.link.contentassist.IContentAssistListener2; + +import dwtx.jface.internal.text.link.contentassist.IProposalListener; // packageimport +import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; // packageimport +import dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContentAssistMessages; // packageimport +import dwtx.jface.internal.text.link.contentassist.Helper2; // packageimport +import dwtx.jface.internal.text.link.contentassist.PopupCloser2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; // packageimport +import dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2; // packageimport + + +import dwt.dwthelper.utils; + + + + + +import dwt.events.VerifyEvent; +import dwtx.jface.text.IEventConsumer; + + + +/** + * An interface whereby listeners can not only receive key events, + * but can also consume them to prevent subsequent listeners from + * processing the event. + */ +interface IContentAssistListener2 : IEventConsumer { + + /** + * Verifies the key event. + * + * @param event the key event + * @return true if processing should be continued by additional listeners + * @see dwt.custom.VerifyKeyListener#verifyKey(VerifyEvent) + */ + public bool verifyKey(VerifyEvent event); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/link/contentassist/IProposalListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/link/contentassist/IProposalListener.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.internal.text.link.contentassist.IProposalListener; + +import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; // packageimport +import dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContentAssistMessages; // packageimport +import dwtx.jface.internal.text.link.contentassist.Helper2; // packageimport +import dwtx.jface.internal.text.link.contentassist.PopupCloser2; // packageimport +import dwtx.jface.internal.text.link.contentassist.IContentAssistListener2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; // packageimport +import dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.contentassist.ICompletionProposal; + + +/** + * + */ +public interface IProposalListener { + + /** + * @param proposal + */ + void proposalChosen(ICompletionProposal proposal); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/link/contentassist/LineBreakingReader.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/link/contentassist/LineBreakingReader.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,142 @@ +/******************************************************************************* + * 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 + * 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.text.link.contentassist.LineBreakingReader; + +import dwtx.jface.internal.text.link.contentassist.IProposalListener; // packageimport +import dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContentAssistMessages; // packageimport +import dwtx.jface.internal.text.link.contentassist.Helper2; // packageimport +import dwtx.jface.internal.text.link.contentassist.PopupCloser2; // packageimport +import dwtx.jface.internal.text.link.contentassist.IContentAssistListener2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; // packageimport +import dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2; // packageimport + + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.BufferedReader; +import dwtx.dwtxhelper.mangoicu.UBreakIterator; + +import dwt.graphics.GC; + +/* + * Not a real reader. Could change if requested + */ +public class LineBreakingReader { + + private BufferedReader fReader; + private GC fGC; + private int fMaxWidth; + + private String fLine; + private int fOffset; + + private UBreakIterator fLineBreakIterator; + private bool fBreakWords; + + /** + * Creates a reader that breaks an input text to fit in a given width. + * + * @param reader Reader of the input text + * @param gc The graphic context that defines the currently used font sizes + * @param maxLineWidth The max width (pixels) where the text has to fit in + */ + public this(Reader reader, GC gc, int maxLineWidth) { + fReader= new BufferedReader(reader); + fGC= gc; + fMaxWidth= maxLineWidth; + fOffset= 0; + fLine= null; + fLineBreakIterator= UBreakIterator.openLineIterator( ULocale.Default); + fBreakWords= true; + } + + public bool isFormattedLine() { + return fLine !is null; + } + + /** + * Reads the next line. The lengths of the line will not exceed the given maximum + * width. + * + * @return the next line + * @throws IOException + */ + public String readLine() { + if (fLine is null) { + String line= fReader.readLine(); + if (line is null) + return null; + + int lineLen= fGC.textExtent(line).x; + if (lineLen < fMaxWidth) { + return line; + } + fLine= line; + fLineBreakIterator.setText(line); + fOffset= 0; + } + int breakOffset= findNextBreakOffset(fOffset); + String res; + if (breakOffset !is UBreakIterator.DONE) { + res= fLine.substring(fOffset, breakOffset); + fOffset= findWordBegin(breakOffset); + if (fOffset is fLine.length()) { + fLine= null; + } + } else { + res= fLine.substring(fOffset); + fLine= null; + } + return res; + } + + private int findNextBreakOffset(int currOffset) { + int currWidth= 0; + int nextOffset= fLineBreakIterator.following(currOffset); + while (nextOffset !is UBreakIterator.DONE) { + String word= fLine.substring(currOffset, nextOffset); + int wordWidth= fGC.textExtent(word).x; + int nextWidth= wordWidth + currWidth; + if (nextWidth > fMaxWidth) { + if (currWidth > 0) + return currOffset; + + if (!fBreakWords) + return nextOffset; + + // need to fit into fMaxWidth + int length= word.length(); + while (length >= 0) { + length--; + word= word.substring(0, length); + wordWidth= fGC.textExtent(word).x; + if (wordWidth + currWidth < fMaxWidth) + return currOffset + length; + } + return nextOffset; + } + currWidth= nextWidth; + currOffset= nextOffset; + nextOffset= fLineBreakIterator.next(); + } + return nextOffset; + } + + private int findWordBegin(int idx) { + while (idx < fLine.length() && Character.isWhitespace(fLine.charAt(idx))) { + idx++; + } + return idx; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/link/contentassist/PopupCloser2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/link/contentassist/PopupCloser2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.internal.text.link.contentassist.PopupCloser2; + +import dwtx.jface.internal.text.link.contentassist.IProposalListener; // packageimport +import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; // packageimport +import dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContentAssistMessages; // packageimport +import dwtx.jface.internal.text.link.contentassist.Helper2; // packageimport +import dwtx.jface.internal.text.link.contentassist.IContentAssistListener2; // packageimport +import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; // packageimport +import dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2; // packageimport + + +import dwt.dwthelper.utils; + + +import dwt.events.FocusEvent; +import dwt.events.FocusListener; +import dwt.events.SelectionEvent; +import dwt.events.SelectionListener; +import dwt.events.ShellAdapter; +import dwt.events.ShellEvent; +import dwt.widgets.Display; +import dwt.widgets.ScrollBar; +import dwt.widgets.Shell; +import dwt.widgets.Table; + + +/** + * A generic closer class used to monitor various + * interface events in order to determine whether + * a content assistant should be terminated and all + * associated windows be closed. + */ +class PopupCloser2 : ShellAdapter , FocusListener, SelectionListener { + + /** The content assistant to be monitored */ + private ContentAssistant2 fContentAssistant; + /** The table of a selector popup opened by the content assistant */ + private Table fTable; + /** The scrollbar of the table for the selector popup */ + private ScrollBar fScrollbar; + /** Indicates whether the scrollbar thumb has been grabbed. */ + private bool fScrollbarClicked= false; + /** The shell on which some listeners are registered. */ + private Shell fShell; + + + /** + * Installs this closer on the given table opened by the given content assistant. + * + * @param contentAssistant the content assistant + * @param table the table to be tracked + */ + public void install(ContentAssistant2 contentAssistant, Table table) { + fContentAssistant= contentAssistant; + fTable= table; + if (Helper2.okToUse(fTable)) { + Shell shell= fTable.getShell(); + if (Helper2.okToUse(shell)) { + fShell= shell; + fShell.addShellListener(this); + } + fTable.addFocusListener(this); + fScrollbar= fTable.getVerticalBar(); + if (fScrollbar !is null) + fScrollbar.addSelectionListener(this); + } + } + + /** + * Uninstalls this closer if previously installed. + */ + public void uninstall() { + fContentAssistant= null; + if (Helper2.okToUse(fShell)) + fShell.removeShellListener(this); + fShell= null; + if (Helper2.okToUse(fScrollbar)) + fScrollbar.removeSelectionListener(this); + if (Helper2.okToUse(fTable)) + fTable.removeFocusListener(this); + } + + /* + * @see dwt.events.SelectionListener#widgetSelected(dwt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + fScrollbarClicked= true; + } + + /* + * @see dwt.events.SelectionListener#widgetDefaultSelected(dwt.events.SelectionEvent) + */ + public void widgetDefaultSelected(SelectionEvent e) { + fScrollbarClicked= true; + } + + /* + * @see dwt.events.FocusListener#focusGained(dwt.events.FocusEvent) + */ + public void focusGained(FocusEvent e) { + } + + /* + * @see dwt.events.FocusListener#focusLost(dwt.events.FocusEvent) + */ + public void focusLost(FocusEvent e) { + fScrollbarClicked= false; + Display d= fTable.getDisplay(); + d.asyncExec(dgRunnable((FocusEvent e_) { + if (Helper2.okToUse(fTable) && !fTable.isFocusControl() && !fScrollbarClicked && fContentAssistant !is null) + fContentAssistant.popupFocusLost(e_); + }, e )); + } + + /* + * @see dwt.events.ShellAdapter#shellDeactivated(dwt.events.ShellEvent) + * @since 3.1 + */ + public void shellDeactivated(ShellEvent e) { + if (fContentAssistant !is null) + fContentAssistant.hide_package(); + } + + + /* + * @see dwt.events.ShellAdapter#shellClosed(dwt.events.ShellEvent) + * @since 3.1 + */ + public void shellClosed(ShellEvent e) { + if (fContentAssistant !is null) + fContentAssistant.hide_package(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/revisions/ChangeRegion.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/revisions/ChangeRegion.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,175 @@ +/******************************************************************************* + * 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 + * 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.text.revisions.ChangeRegion; + +import dwtx.jface.internal.text.revisions.HunkComputer; // packageimport +import dwtx.jface.internal.text.revisions.LineIndexOutOfBoundsException; // packageimport +import dwtx.jface.internal.text.revisions.Hunk; // packageimport +import dwtx.jface.internal.text.revisions.Colors; // packageimport +import dwtx.jface.internal.text.revisions.Range; // packageimport +import dwtx.jface.internal.text.revisions.RevisionPainter; // packageimport +import dwtx.jface.internal.text.revisions.RevisionSelectionProvider; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; +import tango.text.convert.Format; + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.revisions.Revision; +import dwtx.jface.text.source.ILineRange; +import dwtx.jface.text.source.LineRange; + +/** + * A change region describes a contiguous range of lines that was changed in the same revision of a + * document. Once it is adjusted to diff information, the originally contiguous range may be split + * into several ranges or even be empty. + * + * @since 3.2 + */ +public final class ChangeRegion { + private const Revision fRevision; + private const ILineRange fLines; + private const List fAdjusted; + + /** + * Creates a new change region for the given revision and line range. + * + * @param revision the revision of the new region + * @param lines the line range of the new region + * @throws IndexOutOfBoundsException if the line range is not well-formed + */ + public this(Revision revision, ILineRange lines) { + fAdjusted= new LinkedList(); + Assert.isLegal(revision !is null); + Assert.isLegal(lines !is null); + fLines= Range.copy(lines); + fRevision=revision; + clearDiff(); + } + + /** + * Returns the revision that this region belongs to. + * + * @return the revision that this region belongs to + */ + public Revision getRevision() { + return fRevision; + } + + /** + * Returns the original (before applying diff information) line range of this change region. + * + * @return the original (before applying diff information) line range of this change region + */ + public ILineRange getOriginalRange() { + return fLines; + } + + /** + * Returns the list of {@link ILineRange}s of this change region for which the revision + * information is still valid. + * + * @return the list of adjusted line ranges + */ + public List getAdjustedRanges() { + return fAdjusted; + } + + /** + * Returns the line coverage of the adjusted ranges, an empty range if the coverage is empty. + * + * @return the line coverage of the adjusted ranges + */ + public ILineRange getAdjustedCoverage() { + if (fAdjusted.isEmpty()) + return new LineRange(fLines.getStartLine(), 0); + + Range first= cast(Range) fAdjusted.get(0); + Range last= cast(Range) fAdjusted.get(fAdjusted.size() - 1); + + return Range.createAbsolute(first.start(), last.end()); + } + + /** + * Clears any adjusted ranges, restoring the original range. + */ + public void clearDiff() { + fAdjusted.clear(); + fAdjusted.add(Range.copy(fLines)); + } + + /** + * Adjusts this change region to a diff hunk. This will change the adjusted ranges. + * + * @param hunk the diff hunk to adjust to + */ + public void adjustTo(Hunk hunk) { + for (ListIterator it= fAdjusted.listIterator(); it.hasNext();) { + Range range= cast(Range) it.next(); + + // do we need a split? + int unchanged= getUnchanged(hunk, range.start()); + if (unchanged > 0) { + if (unchanged >= range.length()) + continue; + range= range.split(unchanged); + it.add(range); + it.previous(); it.next(); // needed so we can remove below + } + + int line= range.start(); + Assert.isTrue(hunk.line <= line); + + // by how much do we shrink? + int overlap= getOverlap(hunk, line); + if (overlap >= range.length()) { + it.remove(); + continue; + } + + // by how much do we move? + range.moveBy(hunk.delta + overlap); + range.resizeBy(-overlap); + } + + } + + private int getUnchanged(Hunk hunk, int line) { + return Math.max(0, hunk.line - line); + } + + /* + * Returns the number of lines after line that the hunk reports as changed. + */ + private int getOverlap(Hunk hunk, int line) { + + int deltaLine= hunk.line + hunk.changed; + if (hunk.delta >= 0) { + if (deltaLine <= line) + return 0; + return deltaLine - line; + } + + // hunk.delta < 0 + int hunkEnd= deltaLine - hunk.delta; + int cutCount= hunkEnd - line; + return Math.max(0, cutCount); + } + + /* + * @see java.lang.Object#toString() + */ + public override String toString() { + return Format("ChangeRegion [{},[{}+{})]", fRevision.toString(), fLines.getStartLine(), fLines.getNumberOfLines() ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/revisions/Colors.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/revisions/Colors.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,280 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.internal.text.revisions.Colors; + +import dwtx.jface.internal.text.revisions.HunkComputer; // packageimport +import dwtx.jface.internal.text.revisions.LineIndexOutOfBoundsException; // packageimport +import dwtx.jface.internal.text.revisions.Hunk; // packageimport +import dwtx.jface.internal.text.revisions.ChangeRegion; // packageimport +import dwtx.jface.internal.text.revisions.Range; // packageimport +import dwtx.jface.internal.text.revisions.RevisionPainter; // packageimport +import dwtx.jface.internal.text.revisions.RevisionSelectionProvider; // packageimport + + +import dwt.dwthelper.utils; + + +import dwt.DWT; +import dwt.graphics.RGB; +import dwtx.core.runtime.Assert; + +/** + * Utility for color operations. + * + * @since 3.3 + */ +public final class Colors { + /* + * Implementation note: Color computation assumes sRGB, which is probably not true, and does not + * always give good results. CIE based algorithms would be better, see + * http://www.w3.org/TR/PNG-ColorAppendix.html and http://en.wikipedia.org/wiki/Lab_color_space + */ + + /** + * Returns the human-perceived brightness of a color as float in [0.0, 1.0]. The used RGB + * weights come from http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC9. + * + * @param rgb the color + * @return the gray-scale value + */ + public static float brightness(RGB rgb) { + return Math.min(1f, (0.2126f * rgb.red + 0.7152f * rgb.green + 0.0722f * rgb.blue + 0.5f) / 255f); + } + + /** + * Normalizes a color in its perceived brightness. Yellows are darkened, while blues and reds + * are lightened. Depending on the hue, the brightness range within the RGB gamut may be + * different, outside values are clipped. Note that this is an approximation; the returned RGB + * is not guaranteed to have the requested {@link #brightness(RGB) brightness}. + * + * @param color the color to normalize + * @param brightness the requested brightness, in [0, 1] + * @return a normalized version of color + * @see #brightness(RGB) + */ + public static RGB adjustBrightness(RGB color, float brightness_) { + float[] hsi= toHSI(color); + float psychoFactor= brightness_ - brightness(color); + float weight= 0.5f; // found by trial and error + hsi[2]= Math.max(0, Math.min(1.0f, hsi[2] + psychoFactor * weight)); + color= fromHSI(hsi); + return color; + } + + /** + * Converts an {@link RGB} to an HSI + * triplet. + * + * @param color the color to convert + * @return the HSI float array of length 3 + */ + private static float[] toHSI(RGB color) { + float r = color.red / 255f; + float g = color.green / 255f; + float b = color.blue / 255f; + float max = Math.max(Math.max(r, g), b); + float min = Math.min(Math.min(r, g), b); + float delta = max - min; + float maxPlusMin= max + min; + float intensity = maxPlusMin / 2; + float saturation= intensity < 0.5 ? delta / maxPlusMin : delta / (2 - maxPlusMin); + + float hue = 0; + if (delta !is 0) { + if (r is max) { + hue = (g - b) / delta; + } else { + if (g is max) { + hue = 2 + (b - r) / delta; + } else { + hue = 4 + (r - g) / delta; + } + } + hue *= 60; + if (hue < 0) hue += 360; + } + return [hue, saturation, intensity]; + } + + /** + * Converts a HSI triplet to an RGB. + * + * @param hsi the HSI values + * @return the RGB corresponding to the HSI spec + */ + private static RGB fromHSI(float[] hsi) { + float r, g, b; + float hue= hsi[0]; + float saturation= hsi[1]; + float intensity= hsi[2]; + if (saturation is 0) { + r = g = b = intensity; + } else { + float temp2= intensity < 0.5f ? intensity * (1.0f + saturation) : (intensity + saturation) - (intensity * saturation); + float temp1= 2f * intensity - temp2; + if (hue is 360) hue = 0; + hue /= 360; + + r= hue2RGB(temp1, temp2, hue + 1f/3f); + g= hue2RGB(temp1, temp2, hue); + b= hue2RGB(temp1, temp2, hue - 1f/3f); + } + + int red = cast(int)(r * 255 + 0.5); + int green = cast(int)(g * 255 + 0.5); + int blue = cast(int)(b * 255 + 0.5); + return new RGB(red, green, blue); + } + + private static float hue2RGB(float t1, float t2, float hue) { + if (hue < 0) + hue += 1; + else if (hue > 1) + hue -= 1; + if (6f * hue < 1) + return t1 +(t2 - t1) * 6f * hue; + if (2f * hue < 1) + return t2; + if (3f * hue < 2) + return t1 + (t2 - t1) * (2f/3f - hue) * 6f; + return t1; + } + + /** + * Returns an RGB that lies between the given foreground and background + * colors using the given mixing factor. A factor of 1.0 will produce a + * color equal to fg, while a factor of 0.0 will produce one + * equal to bg. + * @param bg the background color + * @param fg the foreground color + * @param factor the mixing factor, must be in [0, 1] + * + * @return the interpolated color + */ + public static RGB blend(RGB bg, RGB fg, float factor) { + Assert.isLegal(bg !is null); + Assert.isLegal(fg !is null); + Assert.isLegal(factor >= 0f && factor <= 1f); + + float complement= 1f - factor; + return new RGB( + cast(int) (complement * bg.red + factor * fg.red), + cast(int) (complement * bg.green + factor * fg.green), + cast(int) (complement * bg.blue + factor * fg.blue) + ); + } + + /** + * Returns an array of colors in a smooth palette from start to end. + *

                + * The returned array has size steps, and the color at index 0 is start, the color + * at index steps - 1 is end. + * + * @param start the start color of the palette + * @param end the end color of the palette + * @param steps the requested size, must be > 0 + * @return an array of steps colors in the palette from start to end + */ + public static RGB[] palette(RGB start, RGB end, int steps) { + Assert.isLegal(start !is null); + Assert.isLegal(end !is null); + Assert.isLegal(steps > 0); + + if (steps is 1) + return [ start ]; + + float step= 1.0f / (steps - 1); + RGB[] gradient= new RGB[steps]; + for (int i= 0; i < steps; i++) + gradient[i]= blend(start, end, step * i); + + return gradient; + } + + /** + * Returns an array of colors with hues evenly distributed on the hue wheel defined by the HSB color space. The returned array + * has size steps. The distance d between two successive colors is + * in [120°, 180°]. + *

                + * The color at a given index has the hue returned by + * {@linkplain #computeHue(int) computeHue(index)}; i.e. the computed hues are not equidistant, + * but adaptively distributed on the color wheel. + *

                + *

                + * The first six colors returned correspond to the following {@link DWT} color constants: + * {@link DWT#COLOR_RED red}, {@link DWT#COLOR_GREEN green}, {@link DWT#COLOR_BLUE blue}, + * {@link DWT#COLOR_YELLOW yellow}, {@link DWT#COLOR_CYAN cyan}, + * {@link DWT#COLOR_MAGENTA magenta}. + *

                + * + * @param steps the requested size, must be >= 2 + * @return an array of steps colors evenly distributed on the color wheel + */ + public static RGB[] rainbow(int steps) { + Assert.isLegal(steps >= 2); + + RGB[] rainbow= new RGB[steps]; + for (int i= 0; i < steps; i++) + rainbow[i]= new RGB(computeHue(i), 1f, 1f); + + return rainbow; + } + + /** + * Returns an indexed hue in [0°, 360°), distributing the hues evenly on the hue wheel + * defined by the HSB (or HSV) color + * space. The distance d between two successive colors is in [120°, 180°]. + *

                + * The first six colors returned correspond to the following {@link DWT} color constants: + * {@link DWT#COLOR_RED red}, {@link DWT#COLOR_GREEN green}, {@link DWT#COLOR_BLUE blue}, + * {@link DWT#COLOR_YELLOW yellow}, {@link DWT#COLOR_CYAN cyan}, + * {@link DWT#COLOR_MAGENTA magenta}. + *

                + * + * @param index the index of the color, must be >= 0 + * @return a color hue in [0°, 360°) + * @see RGB#RGB(float, float, float) + */ + public static float computeHue(int index) { + Assert.isLegal(index >= 0); + /* + * Base 3 gives a nice partitioning for RGB colors with red, green, blue being the colors + * 0,1,2, and yellow, cyan, magenta colors 3,4,5. + */ + final int base= 3; + final float range= 360f; + + // partition the baseRange by using the least significant bit to select one half of the + // partitioning + int baseIndex= index / base; + float baseRange= range / base; + float baseOffset= 0f; + while (baseIndex > 0) { + baseRange /= 2; + int lsb= baseIndex % 2; + baseOffset += lsb * baseRange; + baseIndex >>= 1; + } + + final int baseMod= index % base; + final float hue= baseOffset + baseMod * range / base; + Assert.isTrue(hue >= 0 && hue < 360); + return hue; + } + + private this() { + // not instantiatable + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/revisions/Hunk.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/revisions/Hunk.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,94 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.internal.text.revisions.Hunk; + +import dwtx.jface.internal.text.revisions.HunkComputer; // packageimport +import dwtx.jface.internal.text.revisions.LineIndexOutOfBoundsException; // packageimport +import dwtx.jface.internal.text.revisions.Colors; // packageimport +import dwtx.jface.internal.text.revisions.ChangeRegion; // packageimport +import dwtx.jface.internal.text.revisions.Range; // packageimport +import dwtx.jface.internal.text.revisions.RevisionPainter; // packageimport +import dwtx.jface.internal.text.revisions.RevisionSelectionProvider; // packageimport + +import dwt.dwthelper.utils; +import tango.text.convert.Format; + +import dwtx.core.runtime.Assert; + +/** + * A hunk describes a contiguous range of changed, added or deleted lines. Hunks are separated by + * one or more unchanged lines. + * + * @since 3.3 + */ +public final class Hunk { + /** + * The line at which the hunk starts in the current document. Must be in + * [0, numberOfLines] – note the inclusive end; there may be a hunk with + * line is numberOfLines to describe deleted lines at then end of the document. + */ + public const int line; + /** + * The difference in lines compared to the corresponding line range in the original. Positive + * for added lines, negative for deleted lines. + */ + public const int delta; + /** The number of changed lines in this hunk, must be >= 0. */ + public const int changed; + + /** + * Creates a new hunk. + * + * @param line the line at which the hunk starts, must be >= 0 + * @param delta the difference in lines compared to the original + * @param changed the number of changed lines in this hunk, must be >= 0 + */ + public this(int line, int delta, int changed) { + Assert.isLegal(line >= 0); + Assert.isLegal(changed >= 0); + this.line= line; + this.delta= delta; + this.changed= changed; + } + + /* + * @see java.lang.Object#toString() + */ + public override String toString() { + return Format("Hunk [{}>{}{}{}]", line, changed, delta < 0 ? "-" : "+", Math.abs(delta) ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + } + + /* + * @see java.lang.Object#hashCode() + */ + public override hash_t toHash() { + final int prime= 31; + int result= 1; + result= prime * result + changed; + result= prime * result + delta; + result= prime * result + line; + return result; + } + + /* + * @see java.lang.Object#equals(java.lang.Object) + */ + public override int opEquals(Object obj) { + if (obj is this) + return true; + if ( Hunk other= cast(Hunk)obj ) { + return other.line is this.line && other.delta is this.delta && other.changed is this.changed; + } + return false; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/revisions/HunkComputer.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/revisions/HunkComputer.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,90 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.internal.text.revisions.HunkComputer; + +import dwtx.jface.internal.text.revisions.LineIndexOutOfBoundsException; // packageimport +import dwtx.jface.internal.text.revisions.Hunk; // packageimport +import dwtx.jface.internal.text.revisions.Colors; // packageimport +import dwtx.jface.internal.text.revisions.ChangeRegion; // packageimport +import dwtx.jface.internal.text.revisions.Range; // packageimport +import dwtx.jface.internal.text.revisions.RevisionPainter; // packageimport +import dwtx.jface.internal.text.revisions.RevisionSelectionProvider; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + +import dwtx.jface.text.source.ILineDiffInfo; +import dwtx.jface.text.source.ILineDiffer; + + +/** + * Computes the diff hunks from an {@link ILineDiffer}. + * + * @since 3.3 + */ +public final class HunkComputer { + /** + * Converts the line-based information of {@link ILineDiffer} into {@link Hunk}s, grouping + * contiguous blocks of lines that are changed (added, deleted). + * + * @param differ the line differ to query + * @param lines the number of lines to query + * @return the corresponding {@link Hunk} information + */ + public static Hunk[] computeHunks(ILineDiffer differ, int lines) { + List hunks= new ArrayList(lines); + + int added= 0; + int changed= 0; + ILineDiffInfo info= null; + for (int line= 0; line < lines; line++) { + info= differ.getLineInfo(line); + if (info is null) + continue; + + int changeType= info.getChangeType(); + switch (changeType) { + case ILineDiffInfo.ADDED: + added++; + continue; + case ILineDiffInfo.CHANGED: + changed++; + continue; + case ILineDiffInfo.UNCHANGED: + added -= info.getRemovedLinesAbove(); + if (added !is 0 || changed !is 0) { + hunks.add(new Hunk(line - changed - Math.max(0, added), added, changed)); + added= 0; + changed= 0; + } + } + } + + // last hunk + if (info !is null) { + added -= info.getRemovedLinesBelow(); + if (added !is 0 || changed !is 0) { + hunks.add(new Hunk(lines - changed, added, changed)); + added= 0; + changed= 0; + } + } + + return arraycast!(Hunk)( hunks.toArray()); + } + private this() { + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/revisions/LineIndexOutOfBoundsException.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/revisions/LineIndexOutOfBoundsException.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2005, 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 + *******************************************************************************/ +module dwtx.jface.internal.text.revisions.LineIndexOutOfBoundsException; + +import dwtx.jface.internal.text.revisions.HunkComputer; // packageimport +import dwtx.jface.internal.text.revisions.Hunk; // packageimport +import dwtx.jface.internal.text.revisions.Colors; // packageimport +import dwtx.jface.internal.text.revisions.ChangeRegion; // packageimport +import dwtx.jface.internal.text.revisions.Range; // packageimport +import dwtx.jface.internal.text.revisions.RevisionPainter; // packageimport +import dwtx.jface.internal.text.revisions.RevisionSelectionProvider; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Thrown to indicate that an attempt to create or modify a {@link Range} failed because it would + * have resulted in an illegal range. A range is illegal if its length is <= 0 or if its start + * line is < 0. + * + * @since 3.2 + */ +public final class LineIndexOutOfBoundsException : IndexOutOfBoundsException { + private static const long serialVersionUID= 1L; + + /** + * Constructs an LineIndexOutOfBoundsException with no detail message. + */ + public this() { + super(); + } + + /** + * Constructs an LineIndexOutOfBoundsException with the specified detail message. + * + * @param s the detail message. + */ + public this(String s) { + super(s); + } + + /** + * Constructs a new LineIndexOutOfBoundsException + * object with an argument indicating the illegal index. + * + * @param index the illegal index. + */ + public this(int index) { + super("Line index out of range: " ~ Integer.toString(index)); //$NON-NLS-1$ + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/revisions/Range.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/revisions/Range.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,280 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.internal.text.revisions.Range; + +import dwtx.jface.internal.text.revisions.HunkComputer; // packageimport +import dwtx.jface.internal.text.revisions.LineIndexOutOfBoundsException; // packageimport +import dwtx.jface.internal.text.revisions.Hunk; // packageimport +import dwtx.jface.internal.text.revisions.Colors; // packageimport +import dwtx.jface.internal.text.revisions.ChangeRegion; // packageimport +import dwtx.jface.internal.text.revisions.RevisionPainter; // packageimport +import dwtx.jface.internal.text.revisions.RevisionSelectionProvider; // packageimport + +import dwt.dwthelper.utils; +import tango.text.convert.Format; + +import dwtx.jface.text.source.ILineRange; + +/** + * A variable {@link dwtx.jface.text.source.ILineRange} with the following invariant: + *
                  + *
                • {@link #start() start} >= 0 + *
                • {@link #length() length} > 0, i.e. a range cannot be empty + *
                + *

                + * Attempts to create or modify a Range such that this invariant would be violated + * result in a {@link LineIndexOutOfBoundsException} being + * thrown. + *

                + * + * @since 3.2 + */ +public final class Range : ILineRange, Cloneable { + /** + * Creates a new range with the same start and length as the passed line range. + * + * @param range the range to copy + * @return a Range with the same start and length as range + * @throws LineIndexOutOfBoundsException if the passed {@link ILineRange} does not adhere to the + * contract of {@link Range} + */ + public static Range copy(ILineRange range) { + return createRelative(range.getStartLine(), range.getNumberOfLines()); + } + + /** + * Creates a new range equal to the passed line range. + * + * @param range the range to copy + * @return a Range equal to range + */ + public static Range copy(Range range) { + return createRelative(range.start(), range.length()); + } + + /** + * Creates a new range with the given start offset and length. + * + * @param start the first line of the new range, must be >= 0 + * @param length the number of lines included in the new range, must be > 0 + * @return a Range with the given start and length + * @throws LineIndexOutOfBoundsException if the parameters violate the invariant of + * {@link Range} + */ + public static Range createRelative(int start, int length) { + return new Range(start, length); + } + + /** + * Creates a new range with the given start and end offsets. + * + * @param start the first line of the new range, must be >= 0 + * @param end the first line not in the range any more (exclusive), must be > start + * @return a Range with the given start and end offsets + * @throws LineIndexOutOfBoundsException if the parameters violate the invariant of + * {@link Range} + */ + public static Range createAbsolute(int start, int end) { + return new Range(start, end - start); + } + + private int fStart; + private int fLength; + + /* + * Private constructor. + */ + private this(int start, int length) { + moveTo(start); + setLength(length); + } + + /* + * @see dwtx.jface.text.source.ILineRange#getStartLine() + */ + public int getStartLine() { + return start(); + } + + /* + * @see dwtx.jface.text.source.ILineRange#getNumberOfLines() + */ + public int getNumberOfLines() { + return length(); + } + + /** + * Returns the first line contained in this range. Short equivalent of {@link #getStartLine()}. + * + * @return the first line contained in this range + */ + public int start() { + return fStart; + } + + /** + * Returns the number of lines contained in this range. Short equivalent of {@link #getNumberOfLines()}. + * + * @return the number of lines contained in this range + */ + public int length() { + return fLength; + } + + /** + * Returns the first line after this range. Equivalent to {@linkplain #start() start} + {@linkplain #length() length}. + * + * @return the first line after this range + */ + public int end() { + return start() + length(); + } + + /** + * Moves the receiver to start, keeping {@link #length()} constant. + * + * @param start the new start, must be >= 0 + * @throws LineIndexOutOfBoundsException if start < 0 + */ + public void moveTo(int start) { + if (!(start >= 0)) + throw new LineIndexOutOfBoundsException(Format("Cannot set a negative start: {}", start)); //$NON-NLS-1$ + fStart= start; + } + + /** + * Moves this range such that the {@link #end()} is at end, keeping + * {@link #length()} constant. + * + * @param end the new end + * @throws LineIndexOutOfBoundsException if end <= {@link #start()} + */ + public void moveEndTo(int end) { + moveTo(end - length()); + } + + /** + * Moves the range by delta lines, keeping {@link #length()} constant. The + * resulting start line must be >= 0. + * + * @param delta the number of lines to shift the range + * @throws LineIndexOutOfBoundsException if -delta > {@link #start()} + */ + public void moveBy(int delta) { + moveTo(start() + delta); + } + + /** + * Moves the start offset to start, keeping {@link #end()} constant. + * + * @param start the new start, must be >= 0 and < {@link #end()} + * @throws LineIndexOutOfBoundsException if start < 0 or >= {@link #end()} + */ + public void setStart(int start) { + int end= end(); + if (!(start >= 0 && start < end)) + throw new LineIndexOutOfBoundsException(Format("Cannot set a negative start: {}", start)); //$NON-NLS-1$ + moveTo(start); + setEnd(end); + } + + /** + * Sets the end of this range, keeping {@link #start()} constant. + * + * @param end the new end, must be > {@link #start()} + * @throws LineIndexOutOfBoundsException if end <= {@link #start()} + */ + public void setEnd(int end) { + setLength(end - start()); + } + + /** + * Sets the length of this range, keeping {@link #start()} constant. + * + * @param length the new length, must be > 0 + * @throws LineIndexOutOfBoundsException if length <= 0 + */ + public void setLength(int length) { + if (!(length > 0)) + throw new LineIndexOutOfBoundsException(Format("Cannot set length <= 0: {}", length)); //$NON-NLS-1$ + fLength= length; + } + + /** + * Sets the length of this range, keeping {@link #end()} constant. + * + * @param length the new length, must be > 0 and <= {@link #end()} + * @throws LineIndexOutOfBoundsException if length <= 0 + */ + public void setLengthAndMove(int length) { + setStart(end() - length); + } + + /** + * Resizes the range by delta lines, keeping {@link #start()} constant. + * + * @param delta the number of lines to resize the range + * @throws LineIndexOutOfBoundsException if -delta >= {@link #length()} + */ + public void resizeBy(int delta) { + setLength(length() + delta); + } + + /** + * Resizes the range by delta lines by moving the start offset, {@link #end()} remains unchanged. + * + * @param delta the number of lines to resize the range + * @throws LineIndexOutOfBoundsException if -delta >= {@link #length()} + */ + public void resizeAndMoveBy(int delta) { + setStart(start() + delta); + } + + /** + * Splits a range off the end of the receiver. The receiver is shortened to only include + * remaining lines after the split. + * + * @param remaining the number of lines to remain in the receiver, must be in [1, {@link #length() length}) + * @return the split off range + * @throws LineIndexOutOfBoundsException if remaining>= {@link #length()} or remaining<t;= 0 + */ + public Range split(int remaining) { + if (!(remaining < length())) // assert before modification + throw new LineIndexOutOfBoundsException(Format("Remaining must be less than length: {}", length())); //$NON-NLS-1$ + + int splitLength= length() - remaining; + setLength(remaining); + return new Range(end(), splitLength); + } + + /** + * Returns true if the passed range has the same offset and length as the receiver. + * + * @param range another line range to compare the receiver to + * @return true if range has the same offset and length as the receiver + */ + public bool equalRange(ILineRange range) { + if (range is this) + return true; + if (range is null) + return false; + return range.getStartLine() is start() && range.getNumberOfLines() is length(); + } + + /* + * @see java.lang.Object#clone() + */ + public Object clone() { + return Range.copy(this); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/revisions/RevisionPainter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/revisions/RevisionPainter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,1607 @@ +/******************************************************************************* + * 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 + * 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.text.revisions.RevisionPainter; + +import dwtx.jface.internal.text.revisions.HunkComputer; // packageimport +import dwtx.jface.internal.text.revisions.LineIndexOutOfBoundsException; // packageimport +import dwtx.jface.internal.text.revisions.Hunk; // packageimport +import dwtx.jface.internal.text.revisions.Colors; // packageimport +import dwtx.jface.internal.text.revisions.ChangeRegion; // packageimport +import dwtx.jface.internal.text.revisions.Range; // packageimport +import dwtx.jface.internal.text.revisions.RevisionSelectionProvider; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; +import tango.text.convert.Format; + +import dwt.DWT; +import dwt.custom.StyledText; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.events.MouseEvent; +import dwt.events.MouseMoveListener; +import dwt.events.MouseTrackListener; +import dwt.graphics.Color; +import dwt.graphics.FontMetrics; +import dwt.graphics.GC; +import dwt.graphics.Point; +import dwt.graphics.RGB; +import dwt.graphics.Rectangle; +import dwt.widgets.Canvas; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Listener; +import dwt.widgets.Shell; +import dwtx.core.runtime.Assert; +import dwtx.core.runtime.ListenerList; +import dwtx.core.runtime.Platform; +import dwtx.jface.internal.text.html.BrowserInformationControl; +import dwtx.jface.internal.text.html.HTMLPrinter; +import dwtx.jface.resource.JFaceResources; +import dwtx.jface.text.AbstractReusableInformationControlCreator; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.DefaultInformationControl; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IInformationControl; +import dwtx.jface.text.IInformationControlCreator; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.ITextViewerExtension5; +import dwtx.jface.text.JFaceTextUtil; +import dwtx.jface.text.Position; +import dwtx.jface.text.Region; +import dwtx.jface.text.information.IInformationProviderExtension2; +import dwtx.jface.text.revisions.IRevisionListener; +import dwtx.jface.text.revisions.IRevisionRulerColumnExtension; +import dwtx.jface.text.revisions.Revision; +import dwtx.jface.text.revisions.RevisionEvent; +import dwtx.jface.text.revisions.RevisionInformation; +import dwtx.jface.text.revisions.RevisionRange; +import dwtx.jface.text.revisions.IRevisionRulerColumnExtension; +import dwtx.jface.text.source.Annotation; +import dwtx.jface.text.source.CompositeRuler; +import dwtx.jface.text.source.IAnnotationHover; +import dwtx.jface.text.source.IAnnotationHoverExtension; +import dwtx.jface.text.source.IAnnotationHoverExtension2; +import dwtx.jface.text.source.IAnnotationModel; +import dwtx.jface.text.source.IAnnotationModelExtension; +import dwtx.jface.text.source.IAnnotationModelListener; +import dwtx.jface.text.source.IChangeRulerColumn; +import dwtx.jface.text.source.ILineDiffer; +import dwtx.jface.text.source.ILineRange; +import dwtx.jface.text.source.ISharedTextColors; +import dwtx.jface.text.source.ISourceViewer; +import dwtx.jface.text.source.IVerticalRulerColumn; +import dwtx.jface.text.source.LineRange; + + +/** + * A strategy for painting the live annotate colors onto the vertical ruler column. It also manages + * the revision hover. + * + * @since 3.2 + */ +public final class RevisionPainter { + /** Tells whether this class is in debug mode. */ + private static bool DEBUG_init = false; + private static bool DEBUG_; + private static bool DEBUG(){ + if( !DEBUG_init ){ + DEBUG_init = true; + DEBUG_ = "true".equalsIgnoreCase(Platform.getDebugOption("dwtx.jface.text.source/debug/RevisionRulerColumn")); //$NON-NLS-1$//$NON-NLS-2$ + } + return DEBUG_; + } + + // RGBs provided by UI Designer + private static RGB BY_DATE_START_COLOR_; + private static RGB BY_DATE_START_COLOR(){ + if( BY_DATE_START_COLOR_ is null ){ + synchronized(RevisionPainter.classinfo){ + if( BY_DATE_START_COLOR_ is null ){ + BY_DATE_START_COLOR_ = new RGB(199, 134, 57); + } + } + } + return BY_DATE_START_COLOR_; + } + private static RGB BY_DATE_END_COLOR_; + private static RGB BY_DATE_END_COLOR(){ + if( BY_DATE_END_COLOR_ is null ){ + synchronized(RevisionPainter.classinfo){ + if( BY_DATE_END_COLOR_ is null ){ + BY_DATE_END_COLOR_ = new RGB(241, 225, 206); + } + } + } + return BY_DATE_END_COLOR_; + } + + + /** + * The annotations created to show a revision in the overview ruler. + */ + private static final class RevisionAnnotation : Annotation { + public this(String text) { + super("dwtx.ui.workbench.texteditor.revisionAnnotation", false, text); //$NON-NLS-1$ + } + } + + /** + * The color tool manages revision colors and computes shaded colors based on the relative age + * and author of a revision. + */ + private final class ColorTool { + /** + * The average perceived intensity of a base color. 0 means black, 1 means white. A base + * revision color perceived as light such as yellow will be darkened, while colors perceived + * as dark such as blue will be lightened up. + */ + private static const float AVERAGE_INTENSITY= 0.5f; + /** + * The maximum shading in [0, 1] - this is the shade that the most recent revision will + * receive. + */ + private static const float MAX_SHADING= 0.7f; + /** + * The minimum shading in [0, 1] - this is the shade that the oldest revision will receive. + */ + private static const float MIN_SHADING= 0.2f; + /** + * The shade for the focus boxes. + */ + private static const float FOCUS_COLOR_SHADING= 1f; + + + /** + * A list of {@link Long}, storing the age of each revision in a sorted list. + */ + private List fRevisions; + /** + * The stored shaded colors. + */ + private const Map fColors; + /** + * The stored focus colors. + */ + private const Map fFocusColors; + + this(){ + fColors= new HashMap(); + fFocusColors= new HashMap(); + } + /** + * Sets the revision information, which is needed to compute the relative age of a revision. + * + * @param info the new revision info, null for none. + */ + public void setInfo(RevisionInformation info) { + fRevisions= null; + fColors.clear(); + fFocusColors.clear(); + + if (info is null) + return; + List revisions= new ArrayList(); + for (Iterator it= info.getRevisions().iterator(); it.hasNext();) { + Revision revision= cast(Revision) it.next(); + revisions.add(new Long(computeAge(revision))); + } + Collections.sort(revisions); + fRevisions= revisions; + } + + private RGB adaptColor(Revision revision, bool focus) { + RGB rgb; + float scale; + if (fRenderingMode is IRevisionRulerColumnExtension_AGE) { + int index= computeAgeIndex(revision); + if (index is -1 || fRevisions.size() is 0) { + rgb= getBackground().getRGB(); + } else { + // gradient from intense red for most recent to faint yellow for oldest + RGB[] gradient= Colors.palette(BY_DATE_START_COLOR, BY_DATE_END_COLOR, fRevisions.size()); + rgb= gradient[gradient.length - index - 1]; + } + scale= 0.99f; + } else if (fRenderingMode is IRevisionRulerColumnExtension_AUTHOR) { + rgb= revision.getColor(); + rgb= Colors.adjustBrightness(rgb, AVERAGE_INTENSITY); + scale= 0.6f; + } else if (fRenderingMode is IRevisionRulerColumnExtension_AUTHOR_SHADED_BY_AGE) { + rgb= revision.getColor(); + rgb= Colors.adjustBrightness(rgb, AVERAGE_INTENSITY); + int index= computeAgeIndex(revision); + int size= fRevisions.size(); + // relative age: newest is 0, oldest is 1 + // if there is only one revision, use an intermediate value to avoid extreme coloring + if (index is -1 || size < 2) + scale= 0.5f; + else + scale= cast(float) index / (size - 1); + } else { + Assert.isTrue(false); + return null; // dummy + } + rgb= getShadedColor(rgb, scale, focus); + return rgb; + } + + private int computeAgeIndex(Revision revision) { + long age= computeAge(revision); + int index= fRevisions.indexOf(new Long(age)); + return index; + } + + private RGB getShadedColor(RGB color, float scale, bool focus) { + Assert.isLegal(scale >= 0.0); + Assert.isLegal(scale <= 1.0); + RGB background= getBackground().getRGB(); + + // normalize to lie within [MIN_SHADING, MAX_SHADING] + // use more intense colors if the ruler is narrow (i.e. not showing line numbers) + bool makeIntense= getWidth() <= 15; + float intensityShift= makeIntense ? 0.3f : 0f; + float max= MAX_SHADING + intensityShift; + float min= MIN_SHADING + intensityShift; + scale= (max - min) * scale + min; + + // focus coloring + if (focus) { + scale += FOCUS_COLOR_SHADING; + if (scale > 1) { + background= new RGB(255 - background.red, 255 - background.green, 255 - background.blue); + scale= 2 - scale; + } + } + + return Colors.blend(background, color, scale); + } + + private long computeAge(Revision revision) { + return revision.getDate().getTime(); + } + + /** + * Returns the color for a revision based on relative age and author. + * + * @param revision the revision + * @param focus true to return the focus color + * @return the color for a revision + */ + public RGB getColor(Revision revision, bool focus) { + Map map= focus ? fFocusColors : fColors; + RGB color= cast(RGB) map.get(revision); + if (color !is null) + return color; + + color= adaptColor(revision, focus); + map.put(revision, color); + return color; + } + } + + /** + * Handles all the mouse interaction in this line number ruler column. + */ + private class MouseHandler : MouseMoveListener, MouseTrackListener, Listener { + + private RevisionRange fMouseDownRegion; + + private void handleMouseUp(Event e) { + if (e.button is 1) { + RevisionRange upRegion= fFocusRange; + RevisionRange downRegion= fMouseDownRegion; + fMouseDownRegion= null; + + if (upRegion is downRegion) { + Revision revision= upRegion is null ? null : upRegion.getRevision(); + if (revision is fSelectedRevision) + revision= null; // deselect already selected revision + handleRevisionSelected(revision); + } + } + } + + private void handleMouseDown(Event e) { + if (e.button is 3) + updateFocusRevision(null); // kill any focus as the ctx menu is going to show + if (e.button is 1) { + fMouseDownRegion= fFocusRange; + postRedraw(); + } + } + + /* + * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event) + */ + public void handleEvent(Event event) { + switch (event.type) { + case DWT.MouseWheel: + handleMouseWheel(event); + break; + case DWT.MouseDown: + handleMouseDown(event); + break; + case DWT.MouseUp: + handleMouseUp(event); + break; + default: + Assert.isLegal(false); + } + } + + /* + * @see dwt.events.MouseTrackListener#mouseEnter(dwt.events.MouseEvent) + */ + public void mouseEnter(MouseEvent e) { + updateFocusLine(toDocumentLineNumber(e.y)); + } + + /* + * @see dwt.events.MouseTrackListener#mouseExit(dwt.events.MouseEvent) + */ + public void mouseExit(MouseEvent e) { + updateFocusLine(-1); + } + + /* + * @see dwt.events.MouseTrackListener#mouseHover(dwt.events.MouseEvent) + */ + public void mouseHover(MouseEvent e) { + } + + /* + * @see dwt.events.MouseMoveListener#mouseMove(dwt.events.MouseEvent) + */ + public void mouseMove(MouseEvent e) { + updateFocusLine(toDocumentLineNumber(e.y)); + } + } + + /** + * Internal listener class that will update the ruler when the underlying model changes. + */ + private class AnnotationListener : IAnnotationModelListener { + /* + * @see dwtx.jface.text.source.IAnnotationModelListener#modelChanged(dwtx.jface.text.source.IAnnotationModel) + */ + public void modelChanged(IAnnotationModel model) { + clearRangeCache(); + postRedraw(); + } + + } + + /** + * The information control creator. + */ + private static final class HoverInformationControlCreator : AbstractReusableInformationControlCreator { + private bool fIsFocusable; + + public this(bool isFocusable) { + fIsFocusable= isFocusable; + } + + /* + * @see dwtx.jface.internal.text.revisions.AbstractReusableInformationControlCreator#doCreateInformationControl(dwt.widgets.Shell) + */ + protected IInformationControl doCreateInformationControl(Shell parent) { + if (BrowserInformationControl.isAvailable(parent)) { + return new class(parent, JFaceResources.DIALOG_FONT, fIsFocusable) BrowserInformationControl { + public this(Shell parent, String symbolicFontName, bool resizable){ + super(parent, symbolicFontName,resizable); + } + /* + * @see dwtx.jface.internal.text.html.BrowserInformationControl#setInformation(java.lang.String) + * @since 3.3 + */ + public void setInformation(String content) { + content= addCSSToHTMLFragment(content); + super.setInformation(content); + } + + /** + * Adds a HTML header and CSS info if html is only an HTML fragment (has no + * <html> section). + * + * @param html the html / text produced by a revision + * @return modified html + */ + private String addCSSToHTMLFragment(String html) { + int max= Math.min(100, html.length()); + if (html.substring(0, max).indexOf("") !is -1) //$NON-NLS-1$ + // there is already a header + return html; + + StringBuffer info= new StringBuffer(512 + html.length()); + HTMLPrinter.insertPageProlog(info, 0, fgStyleSheet); + info.append(html); + HTMLPrinter.addPageEpilog(info); + return info.toString(); + } + + }; + } + return new DefaultInformationControl(parent, fIsFocusable); + } + + /* + * @see dwtx.jface.text.AbstractReusableInformationControlCreator#canReplace(dwtx.jface.text.IInformationControlCreator) + */ + public bool canReplace(IInformationControlCreator creator) { + return creator.classinfo is this.classinfo + && (cast(HoverInformationControlCreator) creator).fIsFocusable is fIsFocusable; + } + } + + private static final String fgStyleSheet= "/* Font definitions */\n" ~ //$NON-NLS-1$ + "body, h1, h2, h3, h4, h5, h6, p, table, td, caption, th, ul, ol, dl, li, dd, dt {font-family: sans-serif; font-size: 9pt }\n" ~ //$NON-NLS-1$ + "pre { font-family: monospace; font-size: 9pt }\n" ~ //$NON-NLS-1$ + "\n" ~ //$NON-NLS-1$ + "/* Margins */\n" ~ //$NON-NLS-1$ + "body { overflow: auto; margin-top: 0; margin-bottom: 4; margin-left: 3; margin-right: 0 }\n" ~ //$NON-NLS-1$ + "h1 { margin-top: 5; margin-bottom: 1 } \n" ~ //$NON-NLS-1$ + "h2 { margin-top: 25; margin-bottom: 3 }\n" ~ //$NON-NLS-1$ + "h3 { margin-top: 20; margin-bottom: 3 }\n" ~ //$NON-NLS-1$ + "h4 { margin-top: 20; margin-bottom: 3 }\n" ~ //$NON-NLS-1$ + "h5 { margin-top: 0; margin-bottom: 0 }\n" ~ //$NON-NLS-1$ + "p { margin-top: 10px; margin-bottom: 10px }\n" ~ //$NON-NLS-1$ + "pre { margin-left: 6 }\n" ~ //$NON-NLS-1$ + "ul { margin-top: 0; margin-bottom: 10 }\n" ~ //$NON-NLS-1$ + "li { margin-top: 0; margin-bottom: 0 } \n" ~ //$NON-NLS-1$ + "li p { margin-top: 0; margin-bottom: 0 } \n" ~ //$NON-NLS-1$ + "ol { margin-top: 0; margin-bottom: 10 }\n" ~ //$NON-NLS-1$ + "dl { margin-top: 0; margin-bottom: 10 }\n" ~ //$NON-NLS-1$ + "dt { margin-top: 0; margin-bottom: 0; font-weight: bold }\n" ~ //$NON-NLS-1$ + "dd { margin-top: 0; margin-bottom: 0 }\n" ~ //$NON-NLS-1$ + "\n" ~ //$NON-NLS-1$ + "/* Styles and colors */\n" ~ //$NON-NLS-1$ + "a:link { color: #0000FF }\n" ~ //$NON-NLS-1$ + "a:hover { color: #000080 }\n" ~ //$NON-NLS-1$ + "a:visited { text-decoration: underline }\n" ~ //$NON-NLS-1$ + "h4 { font-style: italic }\n" ~ //$NON-NLS-1$ + "strong { font-weight: bold }\n" ~ //$NON-NLS-1$ + "em { font-style: italic }\n" ~ //$NON-NLS-1$ + "var { font-style: italic }\n" ~ //$NON-NLS-1$ + "th { font-weight: bold }\n" ~ //$NON-NLS-1$ + ""; //$NON-NLS-1$ + + /** + * The revision hover displays information about the currently selected revision. + */ + private final class RevisionHover : IAnnotationHover, IAnnotationHoverExtension, IAnnotationHoverExtension2, IInformationProviderExtension2 { + + /* + * @see dwtx.jface.text.source.IAnnotationHover#getHoverInfo(dwtx.jface.text.source.ISourceViewer, + * int) + */ + public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) { + Object info= getHoverInfo(sourceViewer, getHoverLineRange(sourceViewer, lineNumber), 0); + return info is null ? null : info.toString(); + } + + /* + * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverControlCreator() + */ + public IInformationControlCreator getHoverControlCreator() { + RevisionInformation revisionInfo= fRevisionInfo; + if (revisionInfo !is null) { + IInformationControlCreator creator= revisionInfo.getHoverControlCreator(); + if (creator !is null) + return creator; + } + return new HoverInformationControlCreator(false); + } + + /* + * @see dwtx.jface.text.source.IAnnotationHoverExtension#canHandleMouseCursor() + */ + public bool canHandleMouseCursor() { + return false; + } + + /* + * @see dwtx.jface.text.source.IAnnotationHoverExtension2#canHandleMouseWheel() + */ + public bool canHandleMouseWheel() { + return true; + } + + /* + * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverInfo(dwtx.jface.text.source.ISourceViewer, + * dwtx.jface.text.source.ILineRange, int) + */ + public Object getHoverInfo(ISourceViewer sourceViewer, ILineRange lineRange, int visibleNumberOfLines) { + RevisionRange range= getRange(lineRange.getStartLine()); + Object info= range is null ? null : range.getRevision().getHoverInfo(); + return info; + } + + /* + * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverLineRange(dwtx.jface.text.source.ISourceViewer, + * int) + */ + public ILineRange getHoverLineRange(ISourceViewer viewer, int lineNumber) { + RevisionRange range= getRange(lineNumber); + return range is null ? null : new LineRange(lineNumber, 1); + } + + /* + * @see dwtx.jface.text.information.IInformationProviderExtension2#getInformationPresenterControlCreator() + */ + public IInformationControlCreator getInformationPresenterControlCreator() { + RevisionInformation revisionInfo= fRevisionInfo; + if (revisionInfo !is null) { + IInformationControlCreator creator= revisionInfo.getInformationPresenterControlCreator(); + if (creator !is null) + return creator; + } + return new HoverInformationControlCreator(true); + } + } + + /* Listeners and helpers. */ + + /** The shared color provider. */ + private const ISharedTextColors fSharedColors; + /** The color tool. */ + private const ColorTool fColorTool; + /** The mouse handler. */ + private const MouseHandler fMouseHandler; + /** The hover. */ + private const RevisionHover fHover; + /** The annotation listener. */ + private const AnnotationListener fAnnotationListener; + /** The selection provider. */ + private const RevisionSelectionProvider fRevisionSelectionProvider; + /** + * The list of revision listeners. + * @since 3.3. + */ + private const ListenerList fRevisionListeners; + + /* The context - column and viewer we are connected to. */ + + /** The vertical ruler column that delegates painting to this painter. */ + private const IVerticalRulerColumn fColumn; + /** The parent ruler. */ + private CompositeRuler fParentRuler; + /** The column's control, typically a {@link Canvas}, possibly null. */ + private Control fControl; + /** The text viewer that the column is attached to. */ + private ITextViewer fViewer; + /** The viewer's text widget. */ + private StyledText fWidget; + + /* The models we operate on. */ + + /** The revision model object. */ + private RevisionInformation fRevisionInfo; + /** The line differ. */ + private ILineDiffer fLineDiffer= null; + /** The annotation model. */ + private IAnnotationModel fAnnotationModel= null; + /** The background color, possibly null. */ + private Color fBackground; + + /* Cache. */ + + /** The cached list of ranges adapted to quick diff. */ + private List fRevisionRanges= null; + /** The annotations created for the overview ruler temporary display. */ + private List fAnnotations; + + /* State */ + + /** The current focus line, -1 for none. */ + private int fFocusLine= -1; + /** The current focus region, null if none. */ + private RevisionRange fFocusRange= null; + /** The current focus revision, null if none. */ + private Revision fFocusRevision= null; + /** + * The currently selected revision, null if none. The difference between + * {@link #fFocusRevision} and {@link #fSelectedRevision} may not be obvious: the focus revision + * is the one focused by the mouse (by hovering over a block of the revision), while the + * selected revision is sticky, i.e. is not removed when the mouse leaves the ruler. + * + * @since 3.3 + */ + private Revision fSelectedRevision= null; + /** true if the mouse wheel handler is installed, false otherwise. */ + private bool fWheelHandlerInstalled= false; + /** + * The revision rendering mode. + */ + private IRevisionRulerColumnExtension_RenderingMode fRenderingMode; + /** + * The required with in characters. + * @since 3.3 + */ + private int fRequiredWidth= -1; + /** + * The width of the revision field in chars to compute {@link #fAuthorInset} from. + * @since 3.3 + */ + private int fRevisionIdChars= 0; + /** + * true to show revision ids, false otherwise. + * @since 3.3 + */ + private bool fShowRevision= false; + /** + * true to show the author, false otherwise. + * @since 3.3 + */ + private bool fShowAuthor= false; + /** + * The author inset in pixels for when author *and* revision id are shown. + * @since 3.3 + */ + private int fAuthorInset; + /** + * The remembered ruler width (as changing the ruler width triggers recomputation of the colors. + * @since 3.3 + */ + private int fLastWidth= -1; + + /** + * Creates a new revision painter for a vertical ruler column. + * + * @param column the column that will delegate{@link #paint(GC, ILineRange) painting} to the + * newly created painter. + * @param sharedColors a shared colors object to store shaded colors in + */ + public this(IVerticalRulerColumn column, ISharedTextColors sharedColors) { + + fColorTool= new ColorTool(); + fMouseHandler= new MouseHandler(); + fHover= new RevisionHover(); + fAnnotationListener= new AnnotationListener(); + fRevisionSelectionProvider= new RevisionSelectionProvider(this); + fRevisionListeners= new ListenerList(ListenerList.IDENTITY); + fAnnotations= new ArrayList(); + fRenderingMode= IRevisionRulerColumnExtension_AUTHOR_SHADED_BY_AGE; + + Assert.isLegal(column !is null); + Assert.isLegal(sharedColors !is null); + fColumn= column; + fSharedColors= sharedColors; + } + + /** + * Sets the revision information to be drawn and triggers a redraw. + * + * @param info the revision information to show, null to draw none + */ + public void setRevisionInformation(RevisionInformation info) { + if (fRevisionInfo !is info) { + fRequiredWidth= -1; + fRevisionIdChars= 0; + fRevisionInfo= info; + clearRangeCache(); + updateFocusRange(null); + handleRevisionSelected(cast(Revision) null); + fColorTool.setInfo(info); + postRedraw(); + informListeners(); + } + } + + /** + * Changes the rendering mode and triggers redrawing if needed. + * + * @param renderingMode the rendering mode + * @since 3.3 + */ + public void setRenderingMode(IRevisionRulerColumnExtension_RenderingMode renderingMode) { + Assert.isLegal(renderingMode !is null); + if (fRenderingMode !is renderingMode) { + fRenderingMode= renderingMode; + fColorTool.setInfo(fRevisionInfo); + postRedraw(); + } + } + + /** + * Sets the background color. + * + * @param background the background color, null for the platform's list + * background + */ + public void setBackground(Color background) { + fBackground= background; + } + + /** + * Sets the parent ruler - the delegating column must call this method as soon as it creates its + * control. + * + * @param parentRuler the parent ruler + */ + public void setParentRuler(CompositeRuler parentRuler) { + fParentRuler= parentRuler; + } + + /** + * Delegates the painting of the quick diff colors to this painter. The painter will draw the + * color boxes onto the passed {@link GC} for all model (document) lines in + * visibleModelLines. + * + * @param gc the {@link GC} to draw onto + * @param visibleLines the lines (in document offsets) that are currently (perhaps only + * partially) visible + */ + public void paint(GC gc, ILineRange visibleLines) { + connectIfNeeded(); + if (!isConnected()) + return; + + // compute the horizontal indent of the author for the case that we show revision + // and author + if (fShowAuthor && fShowRevision) { + char[] string= new char[fRevisionIdChars + 1]; + Arrays.fill(string, '9'); + if (string.length > 1) { + string[0]= '.'; + string[1]= ' '; + } + fAuthorInset= gc.stringExtent(new_String(string)).x; + } + + // recompute colors (show intense colors if ruler is narrow) + int width= getWidth(); + if (width !is fLastWidth) { + fColorTool.setInfo(fRevisionInfo); + fLastWidth= width; + } + + // draw change regions + List/* */ranges= getRanges(visibleLines); + for (Iterator it= ranges.iterator(); it.hasNext();) { + RevisionRange region= cast(RevisionRange) it.next(); + paintRange(region, gc); + } + } + + /** + * Ensures that the column is fully instantiated, i.e. has a control, and that the viewer is + * visible. + */ + private void connectIfNeeded() { + if (isConnected() || fParentRuler is null) + return; + + fViewer= fParentRuler.getTextViewer(); + if (fViewer is null) + return; + + fWidget= fViewer.getTextWidget(); + if (fWidget is null) + return; + + fControl= fColumn.getControl(); + if (fControl is null) + return; + + fControl.addMouseTrackListener(fMouseHandler); + fControl.addMouseMoveListener(fMouseHandler); + fControl.addListener(DWT.MouseUp, fMouseHandler); + fControl.addListener(DWT.MouseDown, fMouseHandler); + fControl.addDisposeListener(new class() DisposeListener { + /* + * @see dwt.events.DisposeListener#widgetDisposed(dwt.events.DisposeEvent) + */ + public void widgetDisposed(DisposeEvent e) { + handleDispose(); + } + }); + + fRevisionSelectionProvider.install(fViewer); + } + + /** + * Returns true if the column is fully connected. + * + * @return true if the column is fully connected, false otherwise + */ + private bool isConnected() { + return fControl !is null; + } + + /** + * Sets the annotation model. + * + * @param model the annotation model, possibly null + * @see IVerticalRulerColumn#setModel(IAnnotationModel) + */ + public void setModel(IAnnotationModel model) { + IAnnotationModel diffModel; + if ( cast(IAnnotationModelExtension)model ) + diffModel= (cast(IAnnotationModelExtension) model).getAnnotationModel(stringcast(IChangeRulerColumn.QUICK_DIFF_MODEL_ID)); + else + diffModel= model; + + setDiffer(diffModel); + setAnnotationModel(model); + } + + /** + * Sets the annotation model. + * + * @param model the annotation model. + */ + private void setAnnotationModel(IAnnotationModel model) { + if (fAnnotationModel !is model) + fAnnotationModel= model; + } + + /** + * Sets the line differ. + * + * @param differ the line differ or null if none + */ + private void setDiffer(IAnnotationModel differ) { + if ( cast(ILineDiffer)differ || differ is null) { + if ( cast(Object)fLineDiffer !is cast(Object)differ) { + if (fLineDiffer !is null) + (cast(IAnnotationModel) fLineDiffer).removeAnnotationModelListener(fAnnotationListener); + fLineDiffer= cast(ILineDiffer) differ; + if (fLineDiffer !is null) + (cast(IAnnotationModel) fLineDiffer).addAnnotationModelListener(fAnnotationListener); + } + } + } + + /** + * Disposes of the painter's resources. + */ + private void handleDispose() { + updateFocusLine(-1); + + if (fLineDiffer !is null) { + (cast(IAnnotationModel) fLineDiffer).removeAnnotationModelListener(fAnnotationListener); + fLineDiffer= null; + } + + fRevisionSelectionProvider.uninstall(); + } + + /** + * Paints a single change region onto gc. + * + * @param range the range to paint + * @param gc the {@link GC} to paint on + */ + private void paintRange(RevisionRange range, GC gc) { + ILineRange widgetRange= modelLinesToWidgetLines(range); + if (widgetRange is null) + return; + + Revision revision= range.getRevision(); + bool drawArmedFocus= range is fMouseHandler.fMouseDownRegion; + bool drawSelection= !drawArmedFocus && revision is fSelectedRevision; + bool drawFocus= !drawSelection && !drawArmedFocus && revision is fFocusRevision; + Rectangle box= computeBoxBounds(widgetRange); + + gc.setBackground(lookupColor(revision, false)); + if (drawArmedFocus) { + Color foreground= gc.getForeground(); + Color focusColor= lookupColor(revision, true); + gc.setForeground(focusColor); + gc.fillRectangle(box); + gc.drawRectangle(box.x, box.y, box.width - 1, box.height - 1); // highlight box + gc.drawRectangle(box.x + 1, box.y + 1, box.width - 3, box.height - 3); // inner highlight box + gc.setForeground(foreground); + } else if (drawFocus || drawSelection) { + Color foreground= gc.getForeground(); + Color focusColor= lookupColor(revision, true); + gc.setForeground(focusColor); + gc.fillRectangle(box); + gc.drawRectangle(box.x, box.y, box.width - 1, box.height - 1); // highlight box + gc.setForeground(foreground); + } else { + gc.fillRectangle(box); + } + + if ((fShowAuthor || fShowRevision)) { + int indentation= 1; + int baselineBias= getBaselineBias(gc, widgetRange.getStartLine()); + if (fShowAuthor && fShowRevision) { + gc.drawString(revision.getId(), indentation, box.y + baselineBias, true); + gc.drawString(revision.getAuthor(), fAuthorInset, box.y + baselineBias, true); + } else if (fShowAuthor) { + gc.drawString(revision.getAuthor(), indentation, box.y + baselineBias, true); + } else if (fShowRevision) { + gc.drawString(revision.getId(), indentation, box.y + baselineBias, true); + } + } + } + + /** + * Returns the difference between the baseline of the widget and the + * baseline as specified by the font for gc. When drawing + * line numbers, the returned bias should be added to obtain text lined up + * on the correct base line of the text widget. + * + * @param gc the GC to get the font metrics from + * @param widgetLine the widget line + * @return the baseline bias to use when drawing text that is lined up with + * fCachedTextWidget + * @since 3.3 + */ + private int getBaselineBias(GC gc, int widgetLine) { + /* + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=62951 + * widget line height may be more than the font height used for the + * line numbers, since font styles (bold, italics...) can have larger + * font metrics than the simple font used for the numbers. + */ + int offset= fWidget.getOffsetAtLine(widgetLine); + int widgetBaseline= fWidget.getBaseline(offset); + + FontMetrics fm = gc.getFontMetrics(); + int fontBaseline = fm.getAscent() + fm.getLeading(); + int baselineBias= widgetBaseline - fontBaseline; + return Math.max(0, baselineBias); + } + + /** + * Looks up the color for a certain revision. + * + * @param revision the revision to get the color for + * @param focus true if it is the focus revision + * @return the color for the revision + */ + private Color lookupColor(Revision revision, bool focus) { + return fSharedColors.getColor(fColorTool.getColor(revision, focus)); + } + + /** + * Returns the revision range that contains the given line, or + * null if there is none. + * + * @param line the line of interest + * @return the corresponding RevisionRange or null + */ + private RevisionRange getRange(int line) { + List ranges= getRangeCache(); + + if (ranges.isEmpty() || line is -1) + return null; + + for (Iterator it= ranges.iterator(); it.hasNext();) { + RevisionRange range= cast(RevisionRange) it.next(); + if (contains(range, line)) + return range; + } + + // line may be right after the last region + RevisionRange lastRegion= cast(RevisionRange) ranges.get(ranges.size() - 1); + if (line is end(lastRegion)) + return lastRegion; + return null; + } + + /** + * Returns the sublist of all RevisionRanges that intersect with the given lines. + * + * @param lines the model based lines of interest + * @return elementType: RevisionRange + */ + private List getRanges(ILineRange lines) { + List ranges= getRangeCache(); + + // return the interesting subset + int end_= end(lines); + int first= -1, last= -1; + for (int i= 0; i < ranges.size(); i++) { + RevisionRange range= cast(RevisionRange) ranges.get(i); + int rangeEnd= end(range); + if (first is -1 && rangeEnd > lines.getStartLine()) + first= i; + if (first !is -1 && rangeEnd > end_) { + last= i; + break; + } + } + if (first is -1) + return Collections.EMPTY_LIST; + if (last is -1) + last= ranges.size() - 1; // bottom index may be one too much + + return ranges.subList(first, last + 1); + } + + /** + * Gets all change ranges of the revisions in the revision model and adapts them to the current + * quick diff information. The list is cached. + * + * @return the list of all change regions, with diff information applied + */ + private List getRangeCache() { + if (fRevisionRanges is null) { + if (fRevisionInfo is null) { + fRevisionRanges= Collections.EMPTY_LIST; + } else { + Hunk[] hunks= HunkComputer.computeHunks(fLineDiffer, fViewer.getDocument().getNumberOfLines()); + fRevisionInfo.applyDiff(hunks); + fRevisionRanges= fRevisionInfo.getRanges(); + updateOverviewAnnotations(); + informListeners(); + } + } + + return fRevisionRanges; + } + + /** + * Clears the range cache. + * + * @since 3.3 + */ + private void clearRangeCache() { + fRevisionRanges= null; + } + + /** + * Returns true if range contains line. A line is + * not contained in a range if it is the range's exclusive end line. + * + * @param range the range to check whether it contains line + * @param line the line the line + * @return true if range contains line, + * false if not + */ + private static bool contains(ILineRange range, int line) { + return range.getStartLine() <= line && end(range) > line; + } + + /** + * Computes the end index of a line range. + * + * @param range a line range + * @return the last line (exclusive) of range + */ + private static int end(ILineRange range) { + return range.getStartLine() + range.getNumberOfLines(); + } + + /** + * Returns the visible extent of a document line range in widget lines. + * + * @param range the document line range + * @return the visible extent of range in widget lines + */ + private ILineRange modelLinesToWidgetLines(ILineRange range) { + int widgetStartLine= -1; + int widgetEndLine= -1; + if ( cast(ITextViewerExtension5)fViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) fViewer; + int modelEndLine= end(range); + for (int modelLine= range.getStartLine(); modelLine < modelEndLine; modelLine++) { + int widgetLine= extension.modelLine2WidgetLine(modelLine); + if (widgetLine !is -1) { + if (widgetStartLine is -1) + widgetStartLine= widgetLine; + widgetEndLine= widgetLine; + } + } + } else { + IRegion region= fViewer.getVisibleRegion(); + IDocument document= fViewer.getDocument(); + try { + int visibleStartLine= document.getLineOfOffset(region.getOffset()); + int visibleEndLine= document.getLineOfOffset(region.getOffset() + region.getLength()); + widgetStartLine= Math.max(0, range.getStartLine() - visibleStartLine); + widgetEndLine= Math.min(visibleEndLine, end(range) - 1); + } catch (BadLocationException x) { + ExceptionPrintStackTrace(x); + // ignore and return null + } + } + if (widgetStartLine is -1 || widgetEndLine is -1) + return null; + return new LineRange(widgetStartLine, widgetEndLine - widgetStartLine + 1); + } + + /** + * Returns the revision hover. + * + * @return the revision hover + */ + public IAnnotationHover getHover() { + return fHover; + } + + /** + * Computes and returns the bounds of the rectangle corresponding to a widget line range. The + * rectangle is in pixel coordinates relative to the text widget's + * {@link StyledText#getClientArea() client area} and has the width of the ruler. + * + * @param range the widget line range + * @return the box bounds corresponding to range + */ + private Rectangle computeBoxBounds(ILineRange range) { + int y1= fWidget.getLinePixel(range.getStartLine()); + int y2= fWidget.getLinePixel(range.getStartLine() + range.getNumberOfLines()); + + return new Rectangle(0, y1, getWidth(), y2 - y1 - 1); + } + + /** + * Shows (or hides) the overview annotations. + */ + private void updateOverviewAnnotations() { + if (fAnnotationModel is null) + return; + + Revision revision= fFocusRevision !is null ? fFocusRevision : fSelectedRevision; + + Map added= null; + if (revision !is null) { + added= new HashMap(); + for (Iterator it= revision.getRegions().iterator(); it.hasNext();) { + RevisionRange range= cast(RevisionRange) it.next(); + try { + IRegion charRegion= toCharRegion(range); + Position position= new Position(charRegion.getOffset(), charRegion.getLength()); + Annotation annotation= new RevisionAnnotation(revision.getId()); + added.put(annotation, position); + } catch (BadLocationException x) { + // ignore - document was changed, show no annotations + } + } + } + + if ( cast(IAnnotationModelExtension)fAnnotationModel ) { + IAnnotationModelExtension ext= cast(IAnnotationModelExtension) fAnnotationModel; + ext.replaceAnnotations(arraycast!(Annotation)( fAnnotations.toArray()), added); + } else { + for (Iterator it= fAnnotations.iterator(); it.hasNext();) { + Annotation annotation= cast(Annotation) it.next(); + fAnnotationModel.removeAnnotation(annotation); + } + if (added !is null) { + for (Iterator it= added.entrySet().iterator(); it.hasNext();) { + Map.Entry entry= cast(Map.Entry) it.next(); + fAnnotationModel.addAnnotation(cast(Annotation) entry.getKey(), cast(Position) entry.getValue()); + } + } + } + fAnnotations.clear(); + if (added !is null) + fAnnotations.addAll(added.keySet()); + + } + + /** + * Returns the character offset based region of a line range. + * + * @param lines the line range to convert + * @return the character offset range corresponding to range + * @throws BadLocationException if the line range is not within the document bounds + */ + private IRegion toCharRegion(ILineRange lines) { + IDocument document= fViewer.getDocument(); + int offset= document.getLineOffset(lines.getStartLine()); + int nextLine= end(lines); + int endOffset; + if (nextLine >= document.getNumberOfLines()) + endOffset= document.getLength(); + else + endOffset= document.getLineOffset(nextLine); + return new Region(offset, endOffset - offset); + } + + /** + * Handles the selection of a revision and informs listeners. + * + * @param revision the selected revision, null for none + */ + void handleRevisionSelected(Revision revision) { + fSelectedRevision= revision; + fRevisionSelectionProvider.revisionSelected(revision); + updateOverviewAnnotations(); + postRedraw(); + } + + /** + * Handles the selection of a revision id and informs listeners + * + * @param id the selected revision id + */ + void handleRevisionSelected(String id) { + Assert.isLegal(id !is null); + if (fRevisionInfo is null) + return; + + for (Iterator it= fRevisionInfo.getRevisions().iterator(); it.hasNext();) { + Revision revision= cast(Revision) it.next(); + if (id.equals(revision.getId())) { + handleRevisionSelected(revision); + return; + } + } + + // clear selection if it does not exist + handleRevisionSelected(cast(Revision) null); + } + + /** + * Returns the selection provider. + * + * @return the selection provider + */ + public RevisionSelectionProvider getRevisionSelectionProvider() { + return fRevisionSelectionProvider; + } + + /** + * Updates the focus line with a new line. + * + * @param line the new focus line, -1 for no focus + */ + private void updateFocusLine(int line) { + if (fFocusLine !is line) + onFocusLineChanged(fFocusLine, line); + } + + /** + * Handles a changing focus line. + * + * @param previousLine the old focus line (-1 for no focus) + * @param nextLine the new focus line (-1 for no focus) + */ + private void onFocusLineChanged(int previousLine, int nextLine) { + if (DEBUG) + System.out_.println(Format("line: {} > {}", previousLine, nextLine)); //$NON-NLS-1$ //$NON-NLS-2$ + fFocusLine= nextLine; + RevisionRange region= getRange(nextLine); + updateFocusRange(region); + } + + /** + * Updates the focus range. + * + * @param range the new focus range, null for no focus + */ + private void updateFocusRange(RevisionRange range) { + if (range !is fFocusRange) + onFocusRangeChanged(fFocusRange, range); + } + + /** + * Handles a changing focus range. + * + * @param previousRange the old focus range (null for no focus) + * @param nextRange the new focus range (null for no focus) + */ + private void onFocusRangeChanged(RevisionRange previousRange, RevisionRange nextRange) { + if (DEBUG) + System.out_.println(Format("range: {} > {}", previousRange, nextRange)); //$NON-NLS-1$ //$NON-NLS-2$ + fFocusRange= nextRange; + Revision revision= nextRange is null ? null : nextRange.getRevision(); + updateFocusRevision(revision); + } + + private void updateFocusRevision(Revision revision) { + if (fFocusRevision !is revision) + onFocusRevisionChanged(fFocusRevision, revision); + } + + /** + * Handles a changing focus revision. + * + * @param previousRevision the old focus revision (null for no focus) + * @param nextRevision the new focus revision (null for no focus) + */ + private void onFocusRevisionChanged(Revision previousRevision, Revision nextRevision) { + if (DEBUG) + System.out_.println(Format("revision: {} > {}", previousRevision, nextRevision)); //$NON-NLS-1$ //$NON-NLS-2$ + fFocusRevision= nextRevision; + uninstallWheelHandler(); + installWheelHandler(); + updateOverviewAnnotations(); + redraw(); // pick up new highlights + } + + /** + * Uninstalls the mouse wheel handler. + */ + private void uninstallWheelHandler() { + fControl.removeListener(DWT.MouseWheel, cast(Listener)fMouseHandler); + fWheelHandlerInstalled= false; + } + + /** + * Installs the mouse wheel handler. + */ + private void installWheelHandler() { + if (fFocusRevision !is null && !fWheelHandlerInstalled) { + //FIXME: does not work on Windows, because Canvas cannot get focus and therefore does not send out mouse wheel events: + //https://bugs.eclipse.org/bugs/show_bug.cgi?id=81189 + //see also https://bugs.eclipse.org/bugs/show_bug.cgi?id=75766 + fControl.addListener(DWT.MouseWheel, fMouseHandler); + fWheelHandlerInstalled= true; + } + } + + /** + * Handles a mouse wheel event. + * + * @param event the mouse wheel event + */ + private void handleMouseWheel(Event event) { + bool up= event.count > 0; + int documentHoverLine= fFocusLine; + + ILineRange nextWidgetRange= null; + ILineRange last= null; + List ranges= fFocusRevision.getRegions(); + if (up) { + for (Iterator it= ranges.iterator(); it.hasNext();) { + RevisionRange range= cast(RevisionRange) it.next(); + ILineRange widgetRange= modelLinesToWidgetLines(range); + if (contains(range, documentHoverLine)) { + nextWidgetRange= last; + break; + } + if (widgetRange !is null) + last= widgetRange; + } + } else { + for (ListIterator it= ranges.listIterator(ranges.size()); it.hasPrevious();) { + RevisionRange range= cast(RevisionRange) it.previous(); + ILineRange widgetRange= modelLinesToWidgetLines(range); + if (contains(range, documentHoverLine)) { + nextWidgetRange= last; + break; + } + if (widgetRange !is null) + last= widgetRange; + } + } + + if (nextWidgetRange is null) + return; + + int widgetCurrentFocusLine= modelLinesToWidgetLines(new LineRange(documentHoverLine, 1)).getStartLine(); + int widgetNextFocusLine= nextWidgetRange.getStartLine(); + int newTopPixel= fWidget.getTopPixel() + JFaceTextUtil.computeLineHeight(fWidget, widgetCurrentFocusLine, widgetNextFocusLine, widgetNextFocusLine - widgetCurrentFocusLine); + fWidget.setTopPixel(newTopPixel); + if (newTopPixel < 0) { + Point cursorLocation= fWidget.getDisplay().getCursorLocation(); + cursorLocation.y+= newTopPixel; + fWidget.getDisplay().setCursorLocation(cursorLocation); + } else { + int topPixel= fWidget.getTopPixel(); + if (topPixel < newTopPixel) { + Point cursorLocation= fWidget.getDisplay().getCursorLocation(); + cursorLocation.y+= newTopPixel - topPixel; + fWidget.getDisplay().setCursorLocation(cursorLocation); + } + } + updateFocusLine(toDocumentLineNumber(fWidget.toControl(fWidget.getDisplay().getCursorLocation()).y)); + immediateUpdate(); + } + + /** + * Triggers a redraw in the display thread. + */ + private final void postRedraw() { + if (isConnected() && !fControl.isDisposed()) { + Display d= fControl.getDisplay(); + if (d !is null) { + d.asyncExec(new class() Runnable { + public void run() { + redraw(); + } + }); + } + } + } + + /** + * Translates a y coordinate in the pixel coordinates of the column's control to a document line + * number. + * + * @param y the y coordinate + * @return the corresponding document line, -1 for no line + * @see CompositeRuler#toDocumentLineNumber(int) + */ + private int toDocumentLineNumber(int y) { + return fParentRuler.toDocumentLineNumber(y); + } + + /** + * Triggers redrawing of the column. + */ + private void redraw() { + fColumn.redraw(); + } + + /** + * Triggers immediate redrawing of the entire column - use with care. + */ + private void immediateUpdate() { + fParentRuler.immediateUpdate(); + } + + /** + * Returns the width of the column. + * + * @return the width of the column + */ + private int getWidth() { + return fColumn.getWidth(); + } + + /** + * Returns the System background color for list widgets. + * + * @return the System background color for list widgets + */ + private Color getBackground() { + if (fBackground is null) + return fWidget.getDisplay().getSystemColor(DWT.COLOR_LIST_BACKGROUND); + return fBackground; + } + + /** + * Sets the hover later returned by {@link #getHover()}. + * + * @param hover the hover + */ + public void setHover(IAnnotationHover hover) { + // TODO ignore for now - must make revision hover settable from outside + } + + /** + * Returns true if the receiver can provide a hover for a certain document line. + * + * @param activeLine the document line of interest + * @return true if the receiver can provide a hover + */ + public bool hasHover(int activeLine) { + return cast(ISourceViewer)fViewer && fHover.getHoverLineRange(cast(ISourceViewer) fViewer, activeLine) !is null; + } + + /** + * Returns the revision at a certain document offset, or null for none. + * + * @param offset the document offset + * @return the revision at offset, or null for none + */ + Revision getRevision(int offset) { + IDocument document= fViewer.getDocument(); + int line; + try { + line= document.getLineOfOffset(offset); + } catch (BadLocationException x) { + return null; + } + if (line !is -1) { + RevisionRange range= getRange(line); + if (range !is null) + return range.getRevision(); + } + return null; + } + + /** + * Returns true if a revision model has been set, false otherwise. + * + * @return true if a revision model has been set, false otherwise + */ + public bool hasInformation() { + return fRevisionInfo !is null; + } + + /** + * Returns the width in chars required to display information. + * + * @return the width in chars required to display information + * @since 3.3 + */ + public int getRequiredWidth() { + if (fRequiredWidth is -1) { + if (hasInformation() && (fShowRevision || fShowAuthor)) { + int revisionWidth= 0; + int authorWidth= 0; + for (Iterator it= fRevisionInfo.getRevisions().iterator(); it.hasNext();) { + Revision revision= cast(Revision) it.next(); + revisionWidth= Math.max(revisionWidth, revision.getId().length()); + authorWidth= Math.max(authorWidth, revision.getAuthor().length()); + } + fRevisionIdChars= revisionWidth + 1; + if (fShowAuthor && fShowRevision) + fRequiredWidth= revisionWidth + authorWidth + 2; + else if (fShowAuthor) + fRequiredWidth= authorWidth + 1; + else + fRequiredWidth= revisionWidth + 1; + } else { + fRequiredWidth= 0; + } + } + return fRequiredWidth; + } + + /** + * Enables showing the revision id. + * + * @param show true to show the revision, false to hide it + */ + public void showRevisionId(bool show) { + if (fShowRevision !is show) { + fRequiredWidth= -1; + fRevisionIdChars= 0; + fShowRevision= show; + postRedraw(); + } + } + + /** + * Enables showing the revision author. + * + * @param show true to show the author, false to hide it + */ + public void showRevisionAuthor(bool show) { + if (fShowAuthor !is show) { + fRequiredWidth= -1; + fRevisionIdChars= 0; + fShowAuthor= show; + postRedraw(); + } + } + + /** + * Adds a revision listener. + * + * @param listener the listener + * @since 3.3 + */ + public void addRevisionListener(IRevisionListener listener) { + fRevisionListeners.add(cast(Object)listener); + } + + /** + * Removes a revision listener. + * + * @param listener the listener + * @since 3.3 + */ + public void removeRevisionListener(IRevisionListener listener) { + fRevisionListeners.remove(cast(Object)listener); + } + + /** + * Informs the revision listeners about a change. + * + * @since 3.3 + */ + private void informListeners() { + if (fRevisionInfo is null || fRevisionListeners.isEmpty()) + return; + + RevisionEvent event= new RevisionEvent(fRevisionInfo); + Object[] listeners= fRevisionListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) { + IRevisionListener listener= cast(IRevisionListener) listeners[i]; + listener.revisionInformationChanged(event); + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/revisions/RevisionSelectionProvider.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/revisions/RevisionSelectionProvider.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,216 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.internal.text.revisions.RevisionSelectionProvider; + +import dwtx.jface.internal.text.revisions.HunkComputer; // packageimport +import dwtx.jface.internal.text.revisions.LineIndexOutOfBoundsException; // packageimport +import dwtx.jface.internal.text.revisions.Hunk; // packageimport +import dwtx.jface.internal.text.revisions.Colors; // packageimport +import dwtx.jface.internal.text.revisions.ChangeRegion; // packageimport +import dwtx.jface.internal.text.revisions.Range; // packageimport +import dwtx.jface.internal.text.revisions.RevisionPainter; // packageimport + + +import dwt.dwthelper.utils; + + + +import dwtx.core.runtime.ListenerList; +import dwtx.jface.text.ITextSelection; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.revisions.Revision; +import dwtx.jface.viewers.IPostSelectionProvider; +import dwtx.jface.viewers.ISelection; +import dwtx.jface.viewers.ISelectionChangedListener; +import dwtx.jface.viewers.ISelectionProvider; +import dwtx.jface.viewers.IStructuredSelection; +import dwtx.jface.viewers.SelectionChangedEvent; +import dwtx.jface.viewers.StructuredSelection; + +/** + * A selection provider for annotate revisions. Selections of a revision can currently happen in + * following ways - note that this list may be changed in the future: + *
                  + *
                • when the user clicks the revision ruler with the mouse
                • + *
                • when the caret is moved to a revision's line (only on post-selection)
                • + *
                + *

                + * Calling {@link #setSelection(ISelection)} will set the current sticky revision on the ruler. + *

                + * + * @since 3.2 + */ +public final class RevisionSelectionProvider : ISelectionProvider { + + /** + * Post selection listener on the viewer that remembers the selection provider it is registered + * with. + */ + private final class PostSelectionListener : ISelectionChangedListener { + private const IPostSelectionProvider fPostProvider; + + public this(IPostSelectionProvider postProvider) { + postProvider.addPostSelectionChangedListener(this); + fPostProvider= postProvider; + } + + public void selectionChanged(SelectionChangedEvent event) { + ISelection selection= event.getSelection(); + if ( cast(ITextSelection)selection ) { + ITextSelection ts= cast(ITextSelection) selection; + int offset= ts.getOffset(); + setSelectedRevision(fPainter.getRevision(offset)); + } + + } + + public void dispose() { + fPostProvider.removePostSelectionChangedListener(this); + } + } + + private const RevisionPainter fPainter; + private const ListenerList fListeners; + + /** + * The text viewer once we are installed, null if not installed. + */ + private ITextViewer fViewer; + /** + * The selection listener on the viewer, or null. + */ + private PostSelectionListener fSelectionListener; + /** + * The last selection, or null. + */ + private Revision fSelection; + /** + * Incoming selection changes are ignored while sending out events. + * + * @since 3.3 + */ + private bool fIgnoreEvents= false; + + /** + * Creates a new selection provider. + * + * @param painter the painter that the created provider interacts with + */ + this(RevisionPainter painter) { + fListeners= new ListenerList(); + fPainter= painter; + } + + /* + * @see dwtx.jface.viewers.ISelectionProvider#addSelectionChangedListener(dwtx.jface.viewers.ISelectionChangedListener) + */ + public void addSelectionChangedListener(ISelectionChangedListener listener) { + fListeners.add(cast(Object)listener); + } + + /* + * @see dwtx.jface.viewers.ISelectionProvider#removeSelectionChangedListener(dwtx.jface.viewers.ISelectionChangedListener) + */ + public void removeSelectionChangedListener(ISelectionChangedListener listener) { + fListeners.remove(cast(Object)listener); + } + + /* + * @see dwtx.jface.viewers.ISelectionProvider#getSelection() + */ + public ISelection getSelection() { + if (fSelection is null) + return StructuredSelection.EMPTY; + return new StructuredSelection(fSelection); + } + + /* + * @see dwtx.jface.viewers.ISelectionProvider#setSelection(dwtx.jface.viewers.ISelection) + */ + public void setSelection(ISelection selection) { + if (fIgnoreEvents) + return; + if ( cast(IStructuredSelection)selection ) { + Object first= (cast(IStructuredSelection) selection).getFirstElement(); + if ( cast(Revision)first ) + fPainter.handleRevisionSelected(cast(Revision) first); + else if ( auto str = cast(ArrayWrapperString)first ) + fPainter.handleRevisionSelected(str.array); + else if (selection.isEmpty()) + fPainter.handleRevisionSelected(cast(Revision) null); + } + } + + /** + * Installs the selection provider on the viewer. + * + * @param viewer the viewer on which we listen to for post selection events + */ + void install(ITextViewer viewer) { + uninstall(); + fViewer= viewer; + if (fViewer !is null) { + ISelectionProvider provider= fViewer.getSelectionProvider(); + if ( cast(IPostSelectionProvider)provider ) { + IPostSelectionProvider postProvider= cast(IPostSelectionProvider) provider; + fSelectionListener= new PostSelectionListener(postProvider); + } + } + } + + /** + * Uninstalls the selection provider. + */ + void uninstall() { + fViewer= null; + if (fSelectionListener !is null) { + fSelectionListener.dispose(); + fSelectionListener= null; + } + } + + /** + * Private protocol used by {@link RevisionPainter} to signal selection of a revision. + * + * @param revision the selected revision, or null for none + */ + void revisionSelected(Revision revision) { + setSelectedRevision(revision); + } + + /** + * Updates the currently selected revision and sends out an event if it changed. + * + * @param revision the newly selected revision or null for none + */ + private void setSelectedRevision(Revision revision) { + if (revision !is fSelection) { + fSelection= revision; + fireSelectionEvent(); + } + } + + private void fireSelectionEvent() { + fIgnoreEvents= true; + try { + ISelection selection= getSelection(); + SelectionChangedEvent event= new SelectionChangedEvent(this, selection); + + Object[] listeners= fListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) + (cast(ISelectionChangedListener) listeners[i]).selectionChanged(event); + } finally { + fIgnoreEvents= false; + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/internal/text/source/DiffPainter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/internal/text/source/DiffPainter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,539 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.internal.text.source.DiffPainter; + + + +import dwt.dwthelper.utils; + + + + +import dwt.DWT; +import dwt.custom.StyledText; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.graphics.Color; +import dwt.graphics.GC; +import dwt.graphics.RGB; +import dwt.widgets.Canvas; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwtx.core.runtime.Assert; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.JFaceTextUtil; +import dwtx.jface.text.source.CompositeRuler; +import dwtx.jface.text.source.IAnnotationHover; +import dwtx.jface.text.source.IAnnotationModel; +import dwtx.jface.text.source.IAnnotationModelExtension; +import dwtx.jface.text.source.IAnnotationModelListener; +import dwtx.jface.text.source.IChangeRulerColumn; +import dwtx.jface.text.source.ILineDiffInfo; +import dwtx.jface.text.source.ILineDiffer; +import dwtx.jface.text.source.ILineDifferExtension2; +import dwtx.jface.text.source.ILineRange; +import dwtx.jface.text.source.ISharedTextColors; +import dwtx.jface.text.source.IVerticalRulerColumn; + + +/** + * A strategy for painting the quick diff colors onto the vertical ruler column. It also manages the + * quick diff hover. + * + * @since 3.2 + */ +public final class DiffPainter { + /** + * Internal listener class that will update the ruler when the underlying model changes. + */ + private class AnnotationListener : IAnnotationModelListener { + /* + * @see dwtx.jface.text.source.IAnnotationModelListener#modelChanged(dwtx.jface.text.source.IAnnotationModel) + */ + public void modelChanged(IAnnotationModel model) { + postRedraw(); + } + } + + /** The vertical ruler column that delegates painting to this painter. */ + private const IVerticalRulerColumn fColumn; + /** The parent ruler. */ + private CompositeRuler fParentRuler; + /** The column's control, typically a {@link Canvas}, possibly null. */ + private Control fControl; + /** The text viewer that the column is attached to. */ + private ITextViewer fViewer; + /** The viewer's text widget. */ + private StyledText fWidget; + /** The line differ extracted from the annotation model. */ + private ILineDiffer fLineDiffer= null; + /** Color for changed lines */ + private Color fAddedColor; + /** Color for added lines */ + private Color fChangedColor; + /** Color for the deleted line indicator */ + private Color fDeletedColor; + /** The background color. */ + private Color fBackground; + /** The ruler's hover */ + private IAnnotationHover fHover; + /** The internal listener */ + private const AnnotationListener fAnnotationListener; + /** The shared color provider, possibly null. */ + private const ISharedTextColors fSharedColors; + + /** + * Creates a new diff painter for a vertical ruler column. + * + * @param column the column that will delegate{@link #paint(GC, ILineRange) painting} to the + * newly created painter. + * @param sharedColors a shared colors object to store shaded colors in, may be + * null + */ + public this(IVerticalRulerColumn column, ISharedTextColors sharedColors) { + fAnnotationListener= new AnnotationListener(); + Assert.isLegal(column !is null); + fColumn= column; + fSharedColors= sharedColors; + } + + /** + * Sets the parent ruler - the delegating column must call this method as soon as it creates its + * control. + * + * @param parentRuler the parent ruler + */ + public void setParentRuler(CompositeRuler parentRuler) { + fParentRuler= parentRuler; + } + + /** + * Sets the quick diff hover later returned by {@link #getHover()}. + * + * @param hover the hover + */ + public void setHover(IAnnotationHover hover) { + fHover= hover; + } + + /** + * Returns the quick diff hover set by {@link #setHover(IAnnotationHover)}. + * + * @return the quick diff hover set by {@link #setHover(IAnnotationHover)} + */ + public IAnnotationHover getHover() { + return fHover; + } + + /** + * Sets the background color. + * + * @param background the background color, null to use the platform's list background + */ + public void setBackground(Color background) { + fBackground= background; + } + + /** + * Delegates the painting of the quick diff colors to this painter. The painter will draw the + * color boxes onto the passed {@link GC} for all model (document) lines in + * visibleModelLines. + * + * @param gc the {@link GC} to draw onto + * @param visibleModelLines the lines (in document offsets) that are currently (perhaps only + * partially) visible + */ + public void paint(GC gc, ILineRange visibleModelLines) { + connectIfNeeded(); + if (!isConnected()) + return; + + // draw diff info + final int lastLine= end(visibleModelLines); + final int width= getWidth(); + final Color deletionColor= getDeletionColor(); + for (int line= visibleModelLines.getStartLine(); line < lastLine; line++) { + paintLine(line, gc, width, deletionColor); + } + } + + /** + * Ensures that the column is fully instantiated, i.e. has a control, and that the viewer is + * visible. + */ + private void connectIfNeeded() { + if (isConnected() || fParentRuler is null) + return; + + fViewer= fParentRuler.getTextViewer(); + if (fViewer is null) + return; + + fWidget= fViewer.getTextWidget(); + if (fWidget is null) + return; + + fControl= fColumn.getControl(); + if (fControl is null) + return; + + fControl.addDisposeListener(new class() DisposeListener { + /* + * @see dwt.events.DisposeListener#widgetDisposed(dwt.events.DisposeEvent) + */ + public void widgetDisposed(DisposeEvent e) { + handleDispose(); + } + }); + } + + /** + * Returns true if the column is fully connected. + * + * @return true if the column is fully connected, false otherwise + */ + private bool isConnected() { + return fControl !is null; + } + + /** + * Disposes of this painter and releases any resources. + */ + private void handleDispose() { + if (fLineDiffer !is null) { + (cast(IAnnotationModel) fLineDiffer).removeAnnotationModelListener(fAnnotationListener); + fLineDiffer= null; + } + } + + /** + * Paints a single model line onto gc. + * + * @param line the model line to paint + * @param gc the {@link GC} to paint onto + * @param width the width of the column + * @param deletionColor the background color used to indicate deletions + */ + private void paintLine(int line, GC gc, int width, Color deletionColor) { + int widgetLine= JFaceTextUtil.modelLineToWidgetLine(fViewer, line); + if (widgetLine is -1) + return; + + ILineDiffInfo info= getDiffInfo(line); + + if (info !is null) { + int y= fWidget.getLinePixel(widgetLine); + int lineHeight= fWidget.getLineHeight(fWidget.getOffsetAtLine(widgetLine)); + + // draw background color if special + if (hasSpecialColor(info)) { + gc.setBackground(getColor(info)); + gc.fillRectangle(0, y, width, lineHeight); + } + + /* Deletion Indicator: Simply a horizontal line */ + int delBefore= info.getRemovedLinesAbove(); + int delBelow= info.getRemovedLinesBelow(); + if (delBefore > 0 || delBelow > 0) { + gc.setForeground(deletionColor); + if (delBefore > 0) + gc.drawLine(0, y, width, y); + if (delBelow > 0) + gc.drawLine(0, y + lineHeight - 1, width, y + lineHeight - 1); + } + } + } + + /** + * Returns whether the line background differs from the default. + * + * @param info the info being queried + * @return true if info describes either a changed or an added + * line. + */ + private bool hasSpecialColor(ILineDiffInfo info) { + return info.getChangeType() is ILineDiffInfo.ADDED || info.getChangeType() is ILineDiffInfo.CHANGED; + } + + /** + * Retrieves the ILineDiffInfo for line from the model. There are + * optimizations for direct access and sequential access patterns. + * + * @param line the line we want the info for. + * @return the ILineDiffInfo for line, or null. + */ + private ILineDiffInfo getDiffInfo(int line) { + if (fLineDiffer !is null) + return fLineDiffer.getLineInfo(line); + + return null; + } + + /** + * Returns the color for deleted lines. + * + * @return the color to be used for the deletion indicator + */ + private Color getDeletionColor() { + return fDeletedColor is null ? getBackground() : fDeletedColor; + } + + /** + * Returns the color for the given line diff info. + * + * @param info the ILineDiffInfo being queried + * @return the correct background color for the line type being described by info + */ + private Color getColor(ILineDiffInfo info) { + Assert.isTrue(info !is null && info.getChangeType() !is ILineDiffInfo.UNCHANGED); + Color ret= null; + switch (info.getChangeType()) { + case ILineDiffInfo.CHANGED: + ret= getShadedColor(fChangedColor); + break; + case ILineDiffInfo.ADDED: + ret= getShadedColor(fAddedColor); + break; + } + return ret is null ? getBackground() : ret; + } + + /** + * Sets the background color for changed lines. + * + * @param color the new color to be used for the changed lines background + * @return the shaded color + */ + private Color getShadedColor(Color color) { + if (color is null) + return null; + + if (fSharedColors is null) + return color; + + RGB baseRGB= color.getRGB(); + RGB background= getBackground().getRGB(); + + bool darkBase= isDark(baseRGB); + bool darkBackground= isDark(background); + if (darkBase && darkBackground) + background= new RGB(255, 255, 255); + else if (!darkBase && !darkBackground) + background= new RGB(0, 0, 0); + + return fSharedColors.getColor(interpolate(baseRGB, background, 0.6)); + } + + /** + * Sets the annotation model. + * + * @param model the annotation model, possibly null + * @see IVerticalRulerColumn#setModel(IAnnotationModel) + */ + public void setModel(IAnnotationModel model) { + IAnnotationModel newModel; + if ( cast(IAnnotationModelExtension)model ) + newModel= (cast(IAnnotationModelExtension) model).getAnnotationModel(stringcast(IChangeRulerColumn.QUICK_DIFF_MODEL_ID)); + else + newModel= model; + + setDiffer(newModel); + } + + /** + * Sets the line differ. + * + * @param differ the line differ + */ + private void setDiffer(IAnnotationModel differ) { + if ( cast(ILineDiffer)differ ) { + if ( cast(Object)fLineDiffer !is cast(Object)differ) { + if (fLineDiffer !is null) + (cast(IAnnotationModel) fLineDiffer).removeAnnotationModelListener(fAnnotationListener); + fLineDiffer= cast(ILineDiffer) differ; + if (fLineDiffer !is null) + (cast(IAnnotationModel) fLineDiffer).addAnnotationModelListener(fAnnotationListener); + } + } + } + + /** + * Triggers a redraw in the display thread. + */ + private final void postRedraw() { + if (isConnected() && !fControl.isDisposed()) { + Display d= fControl.getDisplay(); + if (d !is null) { + d.asyncExec(new class() Runnable { + public void run() { + redraw(); + } + }); + } + } + } + + /** + * Triggers redrawing of the column. + */ + private void redraw() { + fColumn.redraw(); + } + + /** + * Returns the width of the column. + * + * @return the width of the column + */ + private int getWidth() { + return fColumn.getWidth(); + } + + /** + * Computes the end index of a line range. + * + * @param range a line range + * @return the last line (exclusive) of range + */ + private static int end(ILineRange range) { + return range.getStartLine() + range.getNumberOfLines(); + } + + /** + * Returns the System background color for list widgets or the set background. + * + * @return the System background color for list widgets + */ + private Color getBackground() { + if (fBackground is null) + return fWidget.getDisplay().getSystemColor(DWT.COLOR_LIST_BACKGROUND); + return fBackground; + } + + /** + * Sets the color for added lines. + * + * @param addedColor the color for added lines + * @see dwtx.jface.text.source.IChangeRulerColumn#setAddedColor(dwt.graphics.Color) + */ + public void setAddedColor(Color addedColor) { + fAddedColor= addedColor; + } + + /** + * Sets the color for changed lines. + * + * @param changedColor the color for changed lines + * @see dwtx.jface.text.source.IChangeRulerColumn#setChangedColor(dwt.graphics.Color) + */ + public void setChangedColor(Color changedColor) { + fChangedColor= changedColor; + } + + /** + * Sets the color for deleted lines. + * + * @param deletedColor the color for deleted lines + * @see dwtx.jface.text.source.IChangeRulerColumn#setDeletedColor(dwt.graphics.Color) + */ + public void setDeletedColor(Color deletedColor) { + fDeletedColor= deletedColor; + } + + /** + * Returns true if the receiver can provide a hover for a certain document line. + * + * @param activeLine the document line of interest + * @return true if the receiver can provide a hover + */ + public bool hasHover(int activeLine) { + return true; + } + + /** + * Returns the display character for the accessibility mode for a certain model line. + * + * @param line the document line of interest + * @return the display character for line + */ + public String getDisplayCharacter(int line) { + return getDisplayCharacter(getDiffInfo(line)); + } + + /** + * Returns the character to display in character display mode for the given + * ILineDiffInfo + * + * @param info the ILineDiffInfo being queried + * @return the character indication for info + */ + private String getDisplayCharacter(ILineDiffInfo info) { + if (info is null) + return " "; //$NON-NLS-1$ + switch (info.getChangeType()) { + case ILineDiffInfo.CHANGED: + return "~"; //$NON-NLS-1$ + case ILineDiffInfo.ADDED: + return "+"; //$NON-NLS-1$ + } + return " "; //$NON-NLS-1$ + } + + /** + * Returns a specification of a color that lies between the given foreground and background + * color using the given scale factor. + * + * @param fg the foreground color + * @param bg the background color + * @param scale the scale factor + * @return the interpolated color + */ + private static RGB interpolate(RGB fg, RGB bg, double scale) { + return new RGB(cast(int) ((1.0 - scale) * fg.red + scale * bg.red), cast(int) ((1.0 - scale) * fg.green + scale * bg.green), cast(int) ((1.0 - scale) * fg.blue + scale * bg.blue)); + } + + /** + * Returns the grey value in which the given color would be drawn in grey-scale. + * + * @param rgb the color + * @return the grey-scale value + */ + private static double greyLevel(RGB rgb) { + if (rgb.red is rgb.green && rgb.green is rgb.blue) + return rgb.red; + return (0.299 * rgb.red + 0.587 * rgb.green + 0.114 * rgb.blue + 0.5); + } + + /** + * Returns whether the given color is dark or light depending on the colors grey-scale level. + * + * @param rgb the color + * @return true if the color is dark, false if it is light + */ + private static bool isDark(RGB rgb) { + return greyLevel(rgb) > 128; + } + + /** + * Returns true if diff information is being displayed, false otherwise. + * + * @return true if diff information is being displayed, false otherwise + * @since 3.3 + */ + public bool hasInformation() { + if ( cast(ILineDifferExtension2)fLineDiffer ) + return !(cast(ILineDifferExtension2) fLineDiffer).isSuspended(); + return fLineDiffer !is null; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/AbstractDocument.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/AbstractDocument.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,1927 @@ +/******************************************************************************* + * 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 + * 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.text.AbstractDocument; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; +import dwtx.dwtxhelper.regex; +import tango.text.convert.Format; + +import dwtx.core.runtime.Assert; +import dwtx.core.runtime.ListenerList; + + +/** + * Abstract default implementation of IDocument and its extension + * interfaces {@link dwtx.jface.text.IDocumentExtension}, + * {@link dwtx.jface.text.IDocumentExtension2}, + * {@link dwtx.jface.text.IDocumentExtension3}, + * {@link dwtx.jface.text.IDocumentExtension4}, as well as + * {@link dwtx.jface.text.IRepairableDocument}. + *

                + * + * An AbstractDocument supports the following implementation + * plug-ins: + *

                  + *
                • a text store implementing {@link dwtx.jface.text.ITextStore} for + * storing and managing the document's content,
                • + *
                • a line tracker implementing {@link dwtx.jface.text.ILineTracker} + * to map character positions to line numbers and vice versa
                • + *
                + * The document can dynamically change the text store when switching between + * sequential rewrite mode and normal mode. + *

                + * + * This class must be subclassed. Subclasses must configure which implementation + * plug-ins the document instance should use. Subclasses are not intended to + * overwrite existing methods. + * + * @see dwtx.jface.text.ITextStore + * @see dwtx.jface.text.ILineTracker + */ +public abstract class AbstractDocument : IDocument, IDocumentExtension, IDocumentExtension2, IDocumentExtension3, IDocumentExtension4, IRepairableDocument, IRepairableDocumentExtension { + + /** + * Tells whether this class is in debug mode. + * @since 3.1 + */ + private static const bool DEBUG= false; + + + /** + * Inner class to bundle a registered post notification replace operation together with its + * owner. + * + * @since 2.0 + */ + static private class RegisteredReplace { + /** The owner of this replace operation. */ + IDocumentListener fOwner; + /** The replace operation */ + IDocumentExtension.IReplace fReplace; + + /** + * Creates a new bundle object. + * @param owner the document listener owning the replace operation + * @param replace the replace operation + */ + this(IDocumentListener owner, IDocumentExtension.IReplace replace) { + fOwner= owner; + fReplace= replace; + } + } + + + /** The document's text store */ + private ITextStore fStore; + /** The document's line tracker */ + private ILineTracker fTracker; + /** The registered document listeners */ + private ListenerList fDocumentListeners; + /** The registered pre-notified document listeners */ + private ListenerList fPrenotifiedDocumentListeners; + /** The registered document partitioning listeners */ + private ListenerList fDocumentPartitioningListeners; + /** All positions managed by the document ordered by their start positions. */ + private Map fPositions; + /** + * All positions managed by the document ordered by there end positions. + * @since 3.4 + */ + private Map fEndPositions; + /** All registered document position updaters */ + private List fPositionUpdaters; + /** + * The list of post notification changes + * @since 2.0 + */ + private List fPostNotificationChanges; + /** + * The reentrance count for post notification changes. + * @since 2.0 + */ + private int fReentranceCount= 0; + /** + * Indicates whether post notification change processing has been stopped. + * @since 2.0 + */ + private int fStoppedCount= 0; + /** + * Indicates whether the registration of post notification changes should be ignored. + * @since 2.1 + */ + private bool fAcceptPostNotificationReplaces= true; + /** + * Indicates whether the notification of listeners has been stopped. + * @since 2.1 + */ + private int fStoppedListenerNotification= 0; + /** + * The document event to be sent after listener notification has been resumed. + * @since 2.1 + */ + private DocumentEvent fDeferredDocumentEvent; + /** + * The registered document partitioners. + * @since 3.0 + */ + private Map fDocumentPartitioners; + /** + * The partitioning changed event. + * @since 3.0 + */ + private DocumentPartitioningChangedEvent fDocumentPartitioningChangedEvent; + /** + * The find/replace document adapter. + * @since 3.0 + */ + private FindReplaceDocumentAdapter fFindReplaceDocumentAdapter; + /** + * The active document rewrite session. + * @since 3.1 + */ + private DocumentRewriteSession fDocumentRewriteSession; + /** + * The registered document rewrite session listeners. + * @since 3.1 + */ + private List fDocumentRewriteSessionListeners; + /** + * The current modification stamp. + * @since 3.1 + */ + private long fModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; + /** + * Keeps track of next modification stamp. + * @since 3.1.1 + */ + private long fNextModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; + /** + * This document's default line delimiter. + * @since 3.1 + */ + private String fInitialLineDelimiter; + + + /** + * The default constructor does not perform any configuration + * but leaves it to the clients who must first initialize the + * implementation plug-ins and then call completeInitialization. + * Results in the construction of an empty document. + */ + protected this() { + fModificationStamp= getNextModificationStamp(); + } + + + /** + * Returns the document's text store. Assumes that the + * document has been initialized with a text store. + * + * @return the document's text store + */ + protected ITextStore getStore() { + Assert.isNotNull(cast(Object)fStore); + return fStore; + } + + /** + * Returns the document's line tracker. Assumes that the + * document has been initialized with a line tracker. + * + * @return the document's line tracker + */ + protected ILineTracker getTracker() { + Assert.isNotNull(cast(Object)fTracker); + return fTracker; + } + + /** + * Returns the document's document listeners. + * + * @return the document's document listeners + */ + protected List getDocumentListeners() { + return Arrays.asList(fDocumentListeners.getListeners()); + } + + /** + * Returns the document's partitioning listeners. + * + * @return the document's partitioning listeners + */ + protected List getDocumentPartitioningListeners() { + return Arrays.asList(fDocumentPartitioningListeners.getListeners()); + } + + /** + * Returns all positions managed by the document grouped by category. + * + * @return the document's positions + */ + protected Map getDocumentManagedPositions() { + return fPositions; + } + + /* + * @see dwtx.jface.text.IDocument#getDocumentPartitioner() + */ + public IDocumentPartitioner getDocumentPartitioner() { + return getDocumentPartitioner(DEFAULT_PARTITIONING); + } + + + + //--- implementation configuration interface ------------ + + /** + * Sets the document's text store. + * Must be called at the beginning of the constructor. + * + * @param store the document's text store + */ + protected void setTextStore(ITextStore store) { + fStore= store; + } + + /** + * Sets the document's line tracker. + * Must be called at the beginning of the constructor. + * + * @param tracker the document's line tracker + */ + protected void setLineTracker(ILineTracker tracker) { + fTracker= tracker; + } + + /* + * @see dwtx.jface.text.IDocument#setDocumentPartitioner(dwtx.jface.text.IDocumentPartitioner) + */ + public void setDocumentPartitioner(IDocumentPartitioner partitioner) { + setDocumentPartitioner(DEFAULT_PARTITIONING, partitioner); + } + + /** + * Initializes document listeners, positions, and position updaters. + * Must be called inside the constructor after the implementation plug-ins + * have been set. + */ + protected void completeInitialization() { + + fPositions= new HashMap(); + fEndPositions= new HashMap(); + fPositionUpdaters= new ArrayList(); + fDocumentListeners= new ListenerList(ListenerList.IDENTITY); + fPrenotifiedDocumentListeners= new ListenerList(ListenerList.IDENTITY); + fDocumentPartitioningListeners= new ListenerList(ListenerList.IDENTITY); + fDocumentRewriteSessionListeners= new ArrayList(); + + addPositionCategory(DEFAULT_CATEGORY); + addPositionUpdater(new DefaultPositionUpdater(DEFAULT_CATEGORY)); + } + + + //------------------------------------------------------- + + /* + * @see dwtx.jface.text.IDocument#addDocumentListener(dwtx.jface.text.IDocumentListener) + */ + public void addDocumentListener(IDocumentListener listener) { + Assert.isNotNull(cast(Object)listener); + fDocumentListeners.add(cast(Object)listener); + } + + /* + * @see dwtx.jface.text.IDocument#removeDocumentListener(dwtx.jface.text.IDocumentListener) + */ + public void removeDocumentListener(IDocumentListener listener) { + Assert.isNotNull(cast(Object)listener); + fDocumentListeners.remove(cast(Object)listener); + } + + /* + * @see dwtx.jface.text.IDocument#addPrenotifiedDocumentListener(dwtx.jface.text.IDocumentListener) + */ + public void addPrenotifiedDocumentListener(IDocumentListener listener) { + Assert.isNotNull(cast(Object)listener); + fPrenotifiedDocumentListeners.add(cast(Object)listener); + } + + /* + * @see dwtx.jface.text.IDocument#removePrenotifiedDocumentListener(dwtx.jface.text.IDocumentListener) + */ + public void removePrenotifiedDocumentListener(IDocumentListener listener) { + Assert.isNotNull(cast(Object)listener); + fPrenotifiedDocumentListeners.remove(cast(Object)listener); + } + + /* + * @see dwtx.jface.text.IDocument#addDocumentPartitioningListener(dwtx.jface.text.IDocumentPartitioningListener) + */ + public void addDocumentPartitioningListener(IDocumentPartitioningListener listener) { + Assert.isNotNull(cast(Object)listener); + fDocumentPartitioningListeners.add(cast(Object)listener); + } + + /* + * @see dwtx.jface.text.IDocument#removeDocumentPartitioningListener(dwtx.jface.text.IDocumentPartitioningListener) + */ + public void removeDocumentPartitioningListener(IDocumentPartitioningListener listener) { + Assert.isNotNull(cast(Object)listener); + fDocumentPartitioningListeners.remove(cast(Object)listener); + } + + /* + * @see dwtx.jface.text.IDocument#addPosition(java.lang.String, dwtx.jface.text.Position) + */ + public void addPosition(String category, Position position) { + + if ((0 > position.offset) || (0 > position.length) || (position.offset + position.length > getLength())) + throw new BadLocationException(); + + if (category is null) + throw new BadPositionCategoryException(); + + List list= cast(List) fPositions.get(category); + if (list is null) + throw new BadPositionCategoryException(); + list.add(computeIndexInPositionList(list, position.offset), position); + + List endPositions= cast(List) fEndPositions.get(category); + if (endPositions is null) + throw new BadPositionCategoryException(); + endPositions.add(computeIndexInPositionList(endPositions, position.offset + position.length - 1, false), position); + } + + /* + * @see dwtx.jface.text.IDocument#addPosition(dwtx.jface.text.Position) + */ + public void addPosition(Position position) { + try { + addPosition(DEFAULT_CATEGORY, position); + } catch (BadPositionCategoryException e) { + } + } + + /* + * @see dwtx.jface.text.IDocument#addPositionCategory(java.lang.String) + */ + public void addPositionCategory(String category) { + + if (category is null) + return; + + if (!containsPositionCategory(category)) { + fPositions.put(category, new ArrayList()); + fEndPositions.put(category, new ArrayList()); + } + } + + /* + * @see dwtx.jface.text.IDocument#addPositionUpdater(dwtx.jface.text.IPositionUpdater) + */ + public void addPositionUpdater(IPositionUpdater updater) { + insertPositionUpdater(updater, fPositionUpdaters.size()); + } + + /* + * @see dwtx.jface.text.IDocument#containsPosition(java.lang.String, int, int) + */ + public bool containsPosition(String category, int offset, int length) { + + if (category is null) + return false; + + List list= cast(List) fPositions.get(category); + if (list is null) + return false; + + int size= list.size(); + if (size is 0) + return false; + + int index= computeIndexInPositionList(list, offset); + if (index < size) { + Position p= cast(Position) list.get(index); + while (p !is null && p.offset is offset) { + if (p.length is length) + return true; + ++ index; + p= (index < size) ? cast(Position) list.get(index) : null; + } + } + + return false; + } + + /* + * @see dwtx.jface.text.IDocument#containsPositionCategory(java.lang.String) + */ + public bool containsPositionCategory(String category) { + if (category !is null) + return fPositions.containsKey(category); + return false; + } + + + /** + * Computes the index in the list of positions at which a position with the given + * offset would be inserted. The position is supposed to become the first in this list + * of all positions with the same offset. + * + * @param positions the list in which the index is computed + * @param offset the offset for which the index is computed + * @return the computed index + * + * @see IDocument#computeIndexInCategory(String, int) + * @deprecated As of 3.4, replaced by {@link #computeIndexInPositionList(List, int, bool)} + */ + protected int computeIndexInPositionList(List positions, int offset) { + return computeIndexInPositionList(positions, offset, true); + } + + /** + * Computes the index in the list of positions at which a position with the given + * position would be inserted. The position to insert is supposed to become the first + * in this list of all positions with the same position. + * + * @param positions the list in which the index is computed + * @param offset the offset for which the index is computed + * @param orderedByOffset true if ordered by offset, false if ordered by end position + * @return the computed index + * @since 3.4 + */ + protected int computeIndexInPositionList(List positions, int offset, bool orderedByOffset) { + if (positions.size() is 0) + return 0; + + int left= 0; + int right= positions.size() -1; + int mid= 0; + Position p= null; + + while (left < right) { + + mid= (left + right) / 2; + + p= cast(Position) positions.get(mid); + int pOffset= getOffset(orderedByOffset, p); + if (offset < pOffset) { + if (left is mid) + right= left; + else + right= mid -1; + } else if (offset > pOffset) { + if (right is mid) + left= right; + else + left= mid +1; + } else if (offset is pOffset) { + left= right= mid; + } + + } + + int pos= left; + p= cast(Position) positions.get(pos); + int pPosition= getOffset(orderedByOffset, p); + if (offset > pPosition) { + // append to the end + pos++; + } else { + // entry will become the first of all entries with the same offset + do { + --pos; + if (pos < 0) + break; + p= cast(Position) positions.get(pos); + pPosition= getOffset(orderedByOffset, p); + } while (offset is pPosition); + ++pos; + } + + Assert.isTrue(0 <= pos && pos <= positions.size()); + + return pos; + } + + /* + * @since 3.4 + */ + private int getOffset(bool orderedByOffset, Position position) { + if (orderedByOffset || position.getLength() is 0) + return position.getOffset(); + return position.getOffset() + position.getLength() - 1; + } + + /* + * @see dwtx.jface.text.IDocument#computeIndexInCategory(java.lang.String, int) + */ + public int computeIndexInCategory(String category, int offset) { + + if (0 > offset || offset > getLength()) + throw new BadLocationException(); + + List c= cast(List) fPositions.get(category); + if (c is null) + throw new BadPositionCategoryException(); + + return computeIndexInPositionList(c, offset); + } + + /** + * Fires the document partitioning changed notification to all registered + * document partitioning listeners. Uses a robust iterator. + * + * @deprecated as of 2.0. Use fireDocumentPartitioningChanged(IRegion) instead. + */ + protected void fireDocumentPartitioningChanged() { + if (fDocumentPartitioningListeners is null) + return; + + Object[] listeners= fDocumentPartitioningListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) + (cast(IDocumentPartitioningListener)listeners[i]).documentPartitioningChanged(this); + } + + /** + * Fires the document partitioning changed notification to all registered + * document partitioning listeners. Uses a robust iterator. + * + * @param region the region in which partitioning has changed + * + * @see IDocumentPartitioningListenerExtension + * @since 2.0 + * @deprecated as of 3.0. Use + * fireDocumentPartitioningChanged(DocumentPartitioningChangedEvent) + * instead. + */ + protected void fireDocumentPartitioningChanged(IRegion region) { + if (fDocumentPartitioningListeners is null) + return; + + Object[] listeners= fDocumentPartitioningListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) { + IDocumentPartitioningListener l= cast(IDocumentPartitioningListener)listeners[i]; + if ( cast(IDocumentPartitioningListenerExtension)l ) + (cast(IDocumentPartitioningListenerExtension) l).documentPartitioningChanged(this, region); + else + l.documentPartitioningChanged(this); + } + } + + /** + * Fires the document partitioning changed notification to all registered + * document partitioning listeners. Uses a robust iterator. + * + * @param event the document partitioning changed event + * + * @see IDocumentPartitioningListenerExtension2 + * @since 3.0 + */ + protected void fireDocumentPartitioningChanged(DocumentPartitioningChangedEvent event) { + if (fDocumentPartitioningListeners is null) + return; + + Object[] listeners= fDocumentPartitioningListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) { + IDocumentPartitioningListener l= cast(IDocumentPartitioningListener)listeners[i]; + if ( cast(IDocumentPartitioningListenerExtension2)l ) { + IDocumentPartitioningListenerExtension2 extension2= cast(IDocumentPartitioningListenerExtension2) l; + extension2.documentPartitioningChanged(event); + } else if ( cast(IDocumentPartitioningListenerExtension)l ) { + IDocumentPartitioningListenerExtension extension= cast(IDocumentPartitioningListenerExtension) l; + extension.documentPartitioningChanged(this, event.getCoverage()); + } else { + l.documentPartitioningChanged(this); + } + } + } + + /** + * Fires the given document event to all registers document listeners informing them + * about the forthcoming document manipulation. Uses a robust iterator. + * + * @param event the event to be sent out + */ + protected void fireDocumentAboutToBeChanged(DocumentEvent event) { + + // IDocumentExtension + if (fReentranceCount is 0) + flushPostNotificationChanges(); + + if (fDocumentPartitioners !is null) { + Iterator e= fDocumentPartitioners.values().iterator(); + while (e.hasNext()) { + IDocumentPartitioner p= cast(IDocumentPartitioner) e.next(); + if ( cast(IDocumentPartitionerExtension3)p ) { + IDocumentPartitionerExtension3 extension= cast(IDocumentPartitionerExtension3) p; + if (extension.getActiveRewriteSession() !is null) + continue; + } + p.documentAboutToBeChanged(event); + } + } + + Object[] listeners= fPrenotifiedDocumentListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) + (cast(IDocumentListener)listeners[i]).documentAboutToBeChanged(event); + + listeners= fDocumentListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) + (cast(IDocumentListener)listeners[i]).documentAboutToBeChanged(event); + } + + + /** + * Updates document partitioning and document positions according to the + * specification given by the document event. + * + * @param event the document event describing the change to which structures must be adapted + */ + protected void updateDocumentStructures(DocumentEvent event) { + + if (fDocumentPartitioners !is null) { + fDocumentPartitioningChangedEvent= new DocumentPartitioningChangedEvent(this); + Iterator e= fDocumentPartitioners.keySet().iterator(); + while (e.hasNext()) { + String partitioning= stringcast( e.next() ); + IDocumentPartitioner partitioner= cast(IDocumentPartitioner) fDocumentPartitioners.get(partitioning); + + if ( cast(IDocumentPartitionerExtension3)partitioner ) { + IDocumentPartitionerExtension3 extension= cast(IDocumentPartitionerExtension3) partitioner; + if (extension.getActiveRewriteSession() !is null) + continue; + } + + if ( cast(IDocumentPartitionerExtension)partitioner ) { + IDocumentPartitionerExtension extension= cast(IDocumentPartitionerExtension) partitioner; + IRegion r= extension.documentChanged2(event); + if (r !is null) + fDocumentPartitioningChangedEvent.setPartitionChange(partitioning, r.getOffset(), r.getLength()); + } else { + if (partitioner.documentChanged(event)) + fDocumentPartitioningChangedEvent.setPartitionChange(partitioning, 0, event.getDocument().getLength()); + } + } + } + + if (fPositions.size() > 0) + updatePositions(event); + } + + /** + * Notifies all listeners about the given document change. Uses a robust + * iterator. + *

                + * Executes all registered post notification replace operation. + * + * @param event the event to be sent out. + */ + protected void doFireDocumentChanged(DocumentEvent event) { + bool changed= fDocumentPartitioningChangedEvent !is null && !fDocumentPartitioningChangedEvent.isEmpty(); + IRegion change= changed ? fDocumentPartitioningChangedEvent.getCoverage() : null; + doFireDocumentChanged(event, changed, change); + } + + /** + * Notifies all listeners about the given document change. + * Uses a robust iterator.

                + * Executes all registered post notification replace operation. + * + * @param event the event to be sent out + * @param firePartitionChange true if a partition change notification should be sent + * @param partitionChange the region whose partitioning changed + * @since 2.0 + * @deprecated as of 3.0. Use doFireDocumentChanged2(DocumentEvent) instead; this method will be removed. + */ + protected void doFireDocumentChanged(DocumentEvent event, bool firePartitionChange, IRegion partitionChange) { + doFireDocumentChanged2(event); + } + + /** + * Notifies all listeners about the given document change. Uses a robust + * iterator. + *

                + * Executes all registered post notification replace operation. + *

                + * This method will be renamed to doFireDocumentChanged. + * + * @param event the event to be sent out + * @since 3.0 + */ + protected void doFireDocumentChanged2(DocumentEvent event) { + + DocumentPartitioningChangedEvent p= fDocumentPartitioningChangedEvent; + fDocumentPartitioningChangedEvent= null; + if (p !is null && !p.isEmpty()) + fireDocumentPartitioningChanged(p); + + Object[] listeners= fPrenotifiedDocumentListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) + (cast(IDocumentListener)listeners[i]).documentChanged(event); + + listeners= fDocumentListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) + (cast(IDocumentListener)listeners[i]).documentChanged(event); + + // IDocumentExtension + ++ fReentranceCount; + try { + if (fReentranceCount is 1) + executePostNotificationChanges(); + } finally { + -- fReentranceCount; + } + } + + /** + * Updates the internal document structures and informs all document listeners + * if listener notification has been enabled. Otherwise it remembers the event + * to be sent to the listeners on resume. + * + * @param event the document event to be sent out + */ + protected void fireDocumentChanged(DocumentEvent event) { + updateDocumentStructures(event); + + if (fStoppedListenerNotification is 0) + doFireDocumentChanged(event); + else + fDeferredDocumentEvent= event; + } + + /* + * @see dwtx.jface.text.IDocument#getChar(int) + */ + public char getChar(int pos) { + if ((0 > pos) || (pos >= getLength())) + throw new BadLocationException(); + return getStore().get(pos); + } + + /* + * @see dwtx.jface.text.IDocument#getContentType(int) + */ + public String getContentType(int offset) { + String contentType= null; + try { + contentType= getContentType(DEFAULT_PARTITIONING, offset, false); + //Assert.isNotNull(contentType); + } catch (BadPartitioningException e) { + Assert.isTrue(false); + } + return contentType; + } + + /* + * @see dwtx.jface.text.IDocument#getLegalContentTypes() + */ + public String[] getLegalContentTypes() { + String[] contentTypes= null; + try { + contentTypes= getLegalContentTypes(DEFAULT_PARTITIONING); + //Assert.isNotNull(contentTypes); + } catch (BadPartitioningException e) { + Assert.isTrue(false); + } + return contentTypes; + } + + /* + * @see dwtx.jface.text.IDocument#getLength() + */ + public int getLength() { + return getStore().getLength(); + } + + /* + * @see dwtx.jface.text.IDocument#getLineDelimiter(int) + */ + public String getLineDelimiter(int line) { + return getTracker().getLineDelimiter(line); + } + + /* + * @see dwtx.jface.text.IDocument#getLegalLineDelimiters() + */ + public String[] getLegalLineDelimiters() { + return getTracker().getLegalLineDelimiters(); + } + + /* + * @see dwtx.jface.text.IDocumentExtension4#getDefaultLineDelimiter() + * @since 3.1 + */ + public String getDefaultLineDelimiter() { + + String lineDelimiter= null; + + try { + lineDelimiter= getLineDelimiter(0); + } catch (BadLocationException x) { + } + + if (lineDelimiter !is null) + return lineDelimiter; + + if (fInitialLineDelimiter !is null) + return fInitialLineDelimiter; + + String sysLineDelimiter= System.getProperty("line.separator"); //$NON-NLS-1$ + String[] delimiters= getLegalLineDelimiters(); + Assert.isTrue(delimiters.length > 0); + for (int i= 0; i < delimiters.length; i++) { + if (delimiters[i].equals(sysLineDelimiter)) { + lineDelimiter= sysLineDelimiter; + break; + } + } + + if (lineDelimiter is null) + lineDelimiter= delimiters[0]; + + return lineDelimiter; + + } + + /* + * @see dwtx.jface.text.IDocumentExtension4#setInitialLineDelimiter(java.lang.String) + * @since 3.1 + */ + public void setInitialLineDelimiter(String lineDelimiter) { + Assert.isNotNull(lineDelimiter); + fInitialLineDelimiter= lineDelimiter; + } + + /* + * @see dwtx.jface.text.IDocument#getLineLength(int) + */ + public int getLineLength(int line) { + return getTracker().getLineLength(line); + } + + /* + * @see dwtx.jface.text.IDocument#getLineOfOffset(int) + */ + public int getLineOfOffset(int pos) { + return getTracker().getLineNumberOfOffset(pos); + } + + /* + * @see dwtx.jface.text.IDocument#getLineOffset(int) + */ + public int getLineOffset(int line) { + return getTracker().getLineOffset(line); + } + + /* + * @see dwtx.jface.text.IDocument#getLineInformation(int) + */ + public IRegion getLineInformation(int line) { + return getTracker().getLineInformation(line); + } + + /* + * @see dwtx.jface.text.IDocument#getLineInformationOfOffset(int) + */ + public IRegion getLineInformationOfOffset(int offset) { + return getTracker().getLineInformationOfOffset(offset); + } + + /* + * @see dwtx.jface.text.IDocument#getNumberOfLines() + */ + public int getNumberOfLines() { + return getTracker().getNumberOfLines(); + } + + /* + * @see dwtx.jface.text.IDocument#getNumberOfLines(int, int) + */ + public int getNumberOfLines(int offset, int length) { + return getTracker().getNumberOfLines(offset, length); + } + + /* + * @see dwtx.jface.text.IDocument#computeNumberOfLines(java.lang.String) + */ + public int computeNumberOfLines(String text) { + return getTracker().computeNumberOfLines(text); + } + + /* + * @see dwtx.jface.text.IDocument#getPartition(int) + */ + public ITypedRegion getPartition(int offset) { + ITypedRegion partition= null; + try { + partition= getPartition(DEFAULT_PARTITIONING, offset, false); +// Assert.isNotNull(cast(Object)partition); + } catch (BadPartitioningException e) { + Assert.isTrue(false); + } + return partition; + } + + /* + * @see dwtx.jface.text.IDocument#computePartitioning(int, int) + */ + public ITypedRegion[] computePartitioning(int offset, int length) { + ITypedRegion[] partitioning= null; + try { + partitioning= computePartitioning(DEFAULT_PARTITIONING, offset, length, false); +// Assert.isNotNull(cast(Object)partitioning); + } catch (BadPartitioningException e) { + Assert.isTrue(false); + } + return partitioning; + } + + /* + * @see dwtx.jface.text.IDocument#getPositions(java.lang.String) + */ + public Position[] getPositions(String category) { + + if (category is null) + throw new BadPositionCategoryException(); + + List c= cast(List) fPositions.get(category); + if (c is null) + throw new BadPositionCategoryException(); + + Position[] positions= new Position[c.size()]; + c.toArray(positions); + return positions; + } + + /* + * @see dwtx.jface.text.IDocument#getPositionCategories() + */ + public String[] getPositionCategories() { + String[] categories= new String[fPositions.size()]; + Iterator keys= fPositions.keySet().iterator(); + for (int i= 0; i < categories.length; i++) + categories[i]= stringcast( keys.next()); + return categories; + } + + /* + * @see dwtx.jface.text.IDocument#getPositionUpdaters() + */ + public IPositionUpdater[] getPositionUpdaters() { + return arraycast!(IPositionUpdater)(fPositionUpdaters.toArray()); + } + + /* + * @see dwtx.jface.text.IDocument#get() + */ + public String get() { + return getStore().get(0, getLength()); + } + + /* + * @see dwtx.jface.text.IDocument#get(int, int) + */ + public String get(int pos, int length) { + int myLength= getLength(); + if ((0 > pos) || (0 > length) || (pos + length > myLength)) + throw new BadLocationException(); + return getStore().get(pos, length); + } + + /* + * @see dwtx.jface.text.IDocument#insertPositionUpdater(dwtx.jface.text.IPositionUpdater, int) + */ + public void insertPositionUpdater(IPositionUpdater updater, int index) { + + for (int i= fPositionUpdaters.size() - 1; i >= 0; i--) { + if (fPositionUpdaters.get(i) is cast(Object)updater) + return; + } + + if (index is fPositionUpdaters.size()) + fPositionUpdaters.add(cast(Object)updater); + else + fPositionUpdaters.add(index, cast(Object)updater); + } + + /* + * @see dwtx.jface.text.IDocument#removePosition(java.lang.String, dwtx.jface.text.Position) + */ + public void removePosition(String category, Position position) { + + if (position is null) + return; + + if (category is null) + throw new BadPositionCategoryException(); + + List c= cast(List) fPositions.get(category); + if (c is null) + throw new BadPositionCategoryException(); + removeFromPositionsList(c, position, true); + + List endPositions= cast(List) fEndPositions.get(category); + if (endPositions is null) + throw new BadPositionCategoryException(); + removeFromPositionsList(endPositions, position, false); + } + + /** + * Remove the given position form the given list of positions based on identity not equality. + * + * @param positions a list of positions + * @param position the position to remove + * @param orderedByOffset true if positions is ordered by offset, false if ordered by end position + * @since 3.4 + */ + private void removeFromPositionsList(List positions, Position position, bool orderedByOffset) { + int size= positions.size(); + + //Assume position is somewhere near it was before + int index= computeIndexInPositionList(positions, orderedByOffset ? position.offset : position.offset + position.length - 1, orderedByOffset); + if (index < size && positions.get(index) is position) { + positions.remove(index); + return; + } + + int back= index - 1; + int forth= index + 1; + while (back >= 0 || forth < size) { + if (back >= 0) { + if (position is positions.get(back)) { + positions.remove(back); + return; + } + back--; + } + + if (forth < size) { + if (position is positions.get(forth)) { + positions.remove(forth); + return; + } + forth++; + } + } + } + + /* + * @see dwtx.jface.text.IDocument#removePosition(dwtx.jface.text.Position) + */ + public void removePosition(Position position) { + try { + removePosition(DEFAULT_CATEGORY, position); + } catch (BadPositionCategoryException e) { + } + } + + /* + * @see dwtx.jface.text.IDocument#removePositionCategory(java.lang.String) + */ + public void removePositionCategory(String category) { + + if (category is null) + return; + + if ( !containsPositionCategory(category)) + throw new BadPositionCategoryException(); + + fPositions.remove(category); + fEndPositions.remove(category); + } + + /* + * @see dwtx.jface.text.IDocument#removePositionUpdater(dwtx.jface.text.IPositionUpdater) + */ + public void removePositionUpdater(IPositionUpdater updater) { + for (int i= fPositionUpdaters.size() - 1; i >= 0; i--) { + if (fPositionUpdaters.get(i) is cast(Object)updater) { + fPositionUpdaters.remove(i); + return; + } + } + } + + private long getNextModificationStamp() { + if (fNextModificationStamp is Long.MAX_VALUE || fNextModificationStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP) + fNextModificationStamp= 0; + else + fNextModificationStamp= fNextModificationStamp + 1; + + return fNextModificationStamp; + } + + /* + * @see dwtx.jface.text.IDocumentExtension4#getModificationStamp() + * @since 3.1 + */ + public long getModificationStamp() { + return fModificationStamp; + } + + /* + * @see dwtx.jface.text.IDocument#replace(int, int, java.lang.String) + * @since 3.1 + */ + public void replace(int pos, int length, String text, long modificationStamp) { + if ((0 > pos) || (0 > length) || (pos + length > getLength())) + throw new BadLocationException(); + + DocumentEvent e= new DocumentEvent(this, pos, length, text); + fireDocumentAboutToBeChanged(e); + + getStore().replace(pos, length, text); + getTracker().replace(pos, length, text); + + fModificationStamp= modificationStamp; + fNextModificationStamp= Math.max(fModificationStamp, fNextModificationStamp); + e.fModificationStamp= fModificationStamp; + + fireDocumentChanged(e); + } + + /** + * {@inheritDoc} + * + * @since 3.4 + */ + public bool isLineInformationRepairNeeded(int offset, int length, String text) { + return false; + } + + /* + * @see dwtx.jface.text.IDocument#replace(int, int, java.lang.String) + */ + public void replace(int pos, int length, String text) { + if (length is 0 && (text is null || text.length is 0)) + replace(pos, length, text, getModificationStamp()); + else + replace(pos, length, text, getNextModificationStamp()); + } + + /* + * @see dwtx.jface.text.IDocument#set(java.lang.String) + */ + public void set(String text) { + set(text, getNextModificationStamp()); + } + + /* + * @see dwtx.jface.text.IDocumentExtension4#set(java.lang.String, long) + * @since 3.1 + */ + public void set(String text, long modificationStamp) { + int length= getStore().getLength(); + + DocumentEvent e= new DocumentEvent(this, 0, length, text); + fireDocumentAboutToBeChanged(e); + + getStore().set(text); + getTracker().set(text); + + fModificationStamp= modificationStamp; + fNextModificationStamp= Math.max(fModificationStamp, fNextModificationStamp); + e.fModificationStamp= fModificationStamp; + + fireDocumentChanged(e); + } + + /** + * Updates all positions of all categories to the change described by the + * document event. All registered document updaters are called in the + * sequence they have been arranged. Uses a robust iterator. + * + * @param event the document event describing the change to which to adapt + * the positions + */ + protected void updatePositions(DocumentEvent event) { + List list= new ArrayList(fPositionUpdaters); + Iterator e= list.iterator(); + while (e.hasNext()) { + IPositionUpdater u= cast(IPositionUpdater) e.next(); + u.update(event); + } + } + + /* + * @see dwtx.jface.text.IDocument#search(int, java.lang.String, bool, bool, bool) + */ + public int search(int startPosition, String findString, bool forwardSearch, bool caseSensitive, bool wholeWord) { + try { + IRegion region= getFindReplaceDocumentAdapter().find(startPosition, findString, forwardSearch, caseSensitive, wholeWord, false); + return region is null ? -1 : region.getOffset(); + } catch (IllegalStateException ex) { + return -1; + } catch (PatternSyntaxException ex) { + return -1; + } + } + + /** + * Returns the find/replace adapter for this document. + * + * @return this document's find/replace document adapter + * @since 3.0 + */ + private FindReplaceDocumentAdapter getFindReplaceDocumentAdapter() { + if (fFindReplaceDocumentAdapter is null) + fFindReplaceDocumentAdapter= new FindReplaceDocumentAdapter(this); + + return fFindReplaceDocumentAdapter; + } + + /** + * Flushes all registered post notification changes. + * + * @since 2.0 + */ + private void flushPostNotificationChanges() { + if (fPostNotificationChanges !is null) + fPostNotificationChanges.clear(); + } + + /** + * Executes all registered post notification changes. The process is + * repeated until no new post notification changes are added. + * + * @since 2.0 + */ + private void executePostNotificationChanges() { + + if (fStoppedCount > 0) + return; + + while (fPostNotificationChanges !is null) { + List changes= fPostNotificationChanges; + fPostNotificationChanges= null; + + Iterator e= changes.iterator(); + while (e.hasNext()) { + RegisteredReplace replace= cast(RegisteredReplace) e.next(); + replace.fReplace.perform(this, replace.fOwner); + } + } + } + + /* + * @see dwtx.jface.text.IDocumentExtension2#acceptPostNotificationReplaces() + * @since 2.1 + */ + public void acceptPostNotificationReplaces() { + fAcceptPostNotificationReplaces= true; + } + + /* + * @see dwtx.jface.text.IDocumentExtension2#ignorePostNotificationReplaces() + * @since 2.1 + */ + public void ignorePostNotificationReplaces() { + fAcceptPostNotificationReplaces= false; + } + + /* + * @see dwtx.jface.text.IDocumentExtension#registerPostNotificationReplace(dwtx.jface.text.IDocumentListener, dwtx.jface.text.IDocumentExtension.IReplace) + * @since 2.0 + */ + public void registerPostNotificationReplace(IDocumentListener owner, IDocumentExtension.IReplace replace) { + if (fAcceptPostNotificationReplaces) { + if (fPostNotificationChanges is null) + fPostNotificationChanges= new ArrayList(1); + fPostNotificationChanges.add(new RegisteredReplace(owner, replace)); + } + } + + /* + * @see dwtx.jface.text.IDocumentExtension#stopPostNotificationProcessing() + * @since 2.0 + */ + public void stopPostNotificationProcessing() { + ++ fStoppedCount; + } + + /* + * @see dwtx.jface.text.IDocumentExtension#resumePostNotificationProcessing() + * @since 2.0 + */ + public void resumePostNotificationProcessing() { + -- fStoppedCount; + if (fStoppedCount is 0 && fReentranceCount is 0) + executePostNotificationChanges(); + } + + /* + * @see dwtx.jface.text.IDocumentExtension#startSequentialRewrite(bool) + * @since 2.0 + */ + public void startSequentialRewrite(bool normalized) { + } + + /* + * @see dwtx.jface.text.IDocumentExtension#stopSequentialRewrite() + * @since 2.0 + */ + public void stopSequentialRewrite() { + } + + /* + * @see dwtx.jface.text.IDocumentExtension2#resumeListenerNotification() + * @since 2.1 + */ + public void resumeListenerNotification() { + -- fStoppedListenerNotification; + if (fStoppedListenerNotification is 0) { + resumeDocumentListenerNotification(); + } + } + + /* + * @see dwtx.jface.text.IDocumentExtension2#stopListenerNotification() + * @since 2.1 + */ + public void stopListenerNotification() { + ++ fStoppedListenerNotification; + } + + /** + * Resumes the document listener notification by sending out the remembered + * partition changed and document event. + * + * @since 2.1 + */ + private void resumeDocumentListenerNotification() { + if (fDeferredDocumentEvent !is null) { + DocumentEvent event= fDeferredDocumentEvent; + fDeferredDocumentEvent= null; + doFireDocumentChanged(event); + } + } + + /* + * @see dwtx.jface.text.IDocumentExtension3#computeZeroLengthPartitioning(java.lang.String, int, int) + * @since 3.0 + */ + public ITypedRegion[] computePartitioning(String partitioning, int offset, int length, bool includeZeroLengthPartitions) { + if ((0 > offset) || (0 > length) || (offset + length > getLength())) + throw new BadLocationException(); + + IDocumentPartitioner partitioner= getDocumentPartitioner(partitioning); + + if ( cast(IDocumentPartitionerExtension2)partitioner ) { + checkStateOfPartitioner(partitioner, partitioning); + return (cast(IDocumentPartitionerExtension2) partitioner).computePartitioning(offset, length, includeZeroLengthPartitions); + } else if (partitioner !is null) { + checkStateOfPartitioner(partitioner, partitioning); + return partitioner.computePartitioning(offset, length); + } else if (DEFAULT_PARTITIONING.equals(partitioning)) + return [ new TypedRegion(offset, length, DEFAULT_CONTENT_TYPE) ]; + else + throw new BadPartitioningException(); + } + + /* + * @see dwtx.jface.text.IDocumentExtension3#getZeroLengthContentType(java.lang.String, int) + * @since 3.0 + */ + public String getContentType(String partitioning, int offset, bool preferOpenPartitions) { + if ((0 > offset) || (offset > getLength())) + throw new BadLocationException(); + + IDocumentPartitioner partitioner= getDocumentPartitioner(partitioning); + + if ( cast(IDocumentPartitionerExtension2)partitioner ) { + checkStateOfPartitioner(partitioner, partitioning); + return (cast(IDocumentPartitionerExtension2) partitioner).getContentType(offset, preferOpenPartitions); + } else if (partitioner !is null) { + checkStateOfPartitioner(partitioner, partitioning); + return partitioner.getContentType(offset); + } else if (DEFAULT_PARTITIONING.equals(partitioning)) + return DEFAULT_CONTENT_TYPE; + else + throw new BadPartitioningException(); + } + + /* + * @see dwtx.jface.text.IDocumentExtension3#getDocumentPartitioner(java.lang.String) + * @since 3.0 + */ + public IDocumentPartitioner getDocumentPartitioner(String partitioning) { + return fDocumentPartitioners !is null ? cast(IDocumentPartitioner) fDocumentPartitioners.get(partitioning) : null; + } + + /* + * @see dwtx.jface.text.IDocumentExtension3#getLegalContentTypes(java.lang.String) + * @since 3.0 + */ + public String[] getLegalContentTypes(String partitioning) { + IDocumentPartitioner partitioner= getDocumentPartitioner(partitioning); + if (partitioner !is null) + return partitioner.getLegalContentTypes(); + if (DEFAULT_PARTITIONING.equals(partitioning)) + return [ DEFAULT_CONTENT_TYPE ]; + throw new BadPartitioningException(); + } + + /* + * @see dwtx.jface.text.IDocumentExtension3#getZeroLengthPartition(java.lang.String, int) + * @since 3.0 + */ + public ITypedRegion getPartition(String partitioning, int offset, bool preferOpenPartitions) { + if ((0 > offset) || (offset > getLength())) + throw new BadLocationException(); + + IDocumentPartitioner partitioner= getDocumentPartitioner(partitioning); + + if ( cast(IDocumentPartitionerExtension2)partitioner ) { + checkStateOfPartitioner(partitioner, partitioning); + return (cast(IDocumentPartitionerExtension2) partitioner).getPartition(offset, preferOpenPartitions); + } else if (partitioner !is null) { + checkStateOfPartitioner(partitioner, partitioning); + return partitioner.getPartition(offset); + } else if (DEFAULT_PARTITIONING.equals(partitioning)) + return new TypedRegion(0, getLength(), DEFAULT_CONTENT_TYPE); + else + throw new BadPartitioningException(); + } + + /* + * @see dwtx.jface.text.IDocumentExtension3#getPartitionings() + * @since 3.0 + */ + public String[] getPartitionings() { + if (fDocumentPartitioners is null) + return new String[0]; + return stringcast(fDocumentPartitioners.keySet().toArray()); + } + + /* + * @see dwtx.jface.text.IDocumentExtension3#setDocumentPartitioner(java.lang.String, dwtx.jface.text.IDocumentPartitioner) + * @since 3.0 + */ + public void setDocumentPartitioner(String partitioning, IDocumentPartitioner partitioner) { + if (partitioner is null) { + if (fDocumentPartitioners !is null) { + fDocumentPartitioners.remove(partitioning); + if (fDocumentPartitioners.size() is 0) + fDocumentPartitioners= null; + } + } else { + if (fDocumentPartitioners is null) + fDocumentPartitioners= new HashMap(); + fDocumentPartitioners.put(partitioning, cast(Object)partitioner); + } + DocumentPartitioningChangedEvent event= new DocumentPartitioningChangedEvent(this); + event.setPartitionChange(partitioning, 0, getLength()); + fireDocumentPartitioningChanged(event); + } + + /* + * @see dwtx.jface.text.IRepairableDocument#repairLineInformation() + * @since 3.0 + */ + public void repairLineInformation() { + getTracker().set(get()); + } + + /** + * Fires the given event to all registered rewrite session listeners. Uses robust iterators. + * + * @param event the event to be fired + * @since 3.1 + */ + protected void fireRewriteSessionChanged(DocumentRewriteSessionEvent event) { + if (fDocumentRewriteSessionListeners.size() > 0) { + List list= new ArrayList(fDocumentRewriteSessionListeners); + Iterator e= list.iterator(); + while (e.hasNext()) { + IDocumentRewriteSessionListener l= cast(IDocumentRewriteSessionListener) e.next(); + l.documentRewriteSessionChanged(event); + } + } + } + + /* + * @see dwtx.jface.text.IDocumentExtension4#getActiveRewriteSession() + */ + public final DocumentRewriteSession getActiveRewriteSession() { + return fDocumentRewriteSession; + } + + /* + * @see dwtx.jface.text.IDocumentExtension4#startRewriteSession(dwtx.jface.text.DocumentRewriteSessionType) + * @since 3.1 + */ + public DocumentRewriteSession startRewriteSession(DocumentRewriteSessionType sessionType) { + + if (getActiveRewriteSession() !is null) + throw new IllegalStateException(); + + + fDocumentRewriteSession= new DocumentRewriteSession(sessionType); + if (DEBUG) + System.out_.println(Format("AbstractDocument: Starting rewrite session: {}", fDocumentRewriteSession)); //$NON-NLS-1$ + + fireRewriteSessionChanged(new DocumentRewriteSessionEvent(this, fDocumentRewriteSession, DocumentRewriteSessionEvent.SESSION_START)); + + startRewriteSessionOnPartitioners(fDocumentRewriteSession); + + ILineTracker tracker= getTracker(); + if ( cast(ILineTrackerExtension)tracker ) { + ILineTrackerExtension extension= cast(ILineTrackerExtension) tracker; + extension.startRewriteSession(fDocumentRewriteSession); + } + + if (DocumentRewriteSessionType.SEQUENTIAL is sessionType) + startSequentialRewrite(false); + else if (DocumentRewriteSessionType.STRICTLY_SEQUENTIAL is sessionType) + startSequentialRewrite(true); + + return fDocumentRewriteSession; + } + + /** + * Starts the given rewrite session. + * + * @param session the rewrite session + * @since 3.1 + */ + protected final void startRewriteSessionOnPartitioners(DocumentRewriteSession session) { + if (fDocumentPartitioners !is null) { + Iterator e= fDocumentPartitioners.values().iterator(); + while (e.hasNext()) { + Object partitioner= e.next(); + if ( cast(IDocumentPartitionerExtension3)partitioner ) { + IDocumentPartitionerExtension3 extension= cast(IDocumentPartitionerExtension3) partitioner; + extension.startRewriteSession(session); + } + } + } + } + + /* + * @see dwtx.jface.text.IDocumentExtension4#stopRewriteSession(dwtx.jface.text.DocumentRewriteSession) + * @since 3.1 + */ + public void stopRewriteSession(DocumentRewriteSession session) { + if (fDocumentRewriteSession is session) { + + if (DEBUG) + System.out_.println(Format("AbstractDocument: Stopping rewrite session: {}", session)); //$NON-NLS-1$ + + DocumentRewriteSessionType sessionType= session.getSessionType(); + if (DocumentRewriteSessionType.SEQUENTIAL is sessionType || DocumentRewriteSessionType.STRICTLY_SEQUENTIAL is sessionType) + stopSequentialRewrite(); + + ILineTracker tracker= getTracker(); + if ( cast(ILineTrackerExtension)tracker ) { + ILineTrackerExtension extension= cast(ILineTrackerExtension) tracker; + extension.stopRewriteSession(session, get()); + } + + stopRewriteSessionOnPartitioners(fDocumentRewriteSession); + + fDocumentRewriteSession= null; + fireRewriteSessionChanged(new DocumentRewriteSessionEvent(this, session, DocumentRewriteSessionEvent.SESSION_STOP)); + } + } + + /** + * Stops the given rewrite session. + * + * @param session the rewrite session + * @since 3.1 + */ + protected final void stopRewriteSessionOnPartitioners(DocumentRewriteSession session) { + if (fDocumentPartitioners !is null) { + DocumentPartitioningChangedEvent event= new DocumentPartitioningChangedEvent(this); + Iterator e= fDocumentPartitioners.keySet().iterator(); + while (e.hasNext()) { + String partitioning= stringcast( e.next()); + IDocumentPartitioner partitioner= cast(IDocumentPartitioner) fDocumentPartitioners.get(partitioning); + if ( cast(IDocumentPartitionerExtension3)partitioner ) { + IDocumentPartitionerExtension3 extension= cast(IDocumentPartitionerExtension3) partitioner; + extension.stopRewriteSession(session); + event.setPartitionChange(partitioning, 0, getLength()); + } + } + if (!event.isEmpty()) + fireDocumentPartitioningChanged(event); + } + } + + /* + * @see dwtx.jface.text.IDocumentExtension4#addDocumentRewriteSessionListener(dwtx.jface.text.IDocumentRewriteSessionListener) + * @since 3.1 + */ + public void addDocumentRewriteSessionListener(IDocumentRewriteSessionListener listener) { + Assert.isNotNull(cast(Object)listener); + if (! fDocumentRewriteSessionListeners.contains(cast(Object)listener)) + fDocumentRewriteSessionListeners.add(cast(Object)listener); + } + + /* + * @see dwtx.jface.text.IDocumentExtension4#removeDocumentRewriteSessionListener(dwtx.jface.text.IDocumentRewriteSessionListener) + * @since 3.1 + */ + public void removeDocumentRewriteSessionListener(IDocumentRewriteSessionListener listener) { + Assert.isNotNull(cast(Object)listener); + fDocumentRewriteSessionListeners.remove(cast(Object)listener); + } + + /** + * Checks the state for the given partitioner and stops the + * active rewrite session. + * + * @param partitioner the document partitioner to be checked + * @param partitioning the document partitioning the partitioner is registered for + * @since 3.1 + */ + protected final void checkStateOfPartitioner(IDocumentPartitioner partitioner, String partitioning) { + if (!( cast(IDocumentPartitionerExtension3)partitioner )) + return; + + IDocumentPartitionerExtension3 extension= cast(IDocumentPartitionerExtension3) partitioner; + DocumentRewriteSession session= extension.getActiveRewriteSession(); + if (session !is null) { + extension.stopRewriteSession(session); + + if (DEBUG) + System.out_.println(Format("AbstractDocument: Flushing rewrite session for partition type: {}", partitioning)); //$NON-NLS-1$ + + DocumentPartitioningChangedEvent event= new DocumentPartitioningChangedEvent(this); + event.setPartitionChange(partitioning, 0, getLength()); + fireDocumentPartitioningChanged(event); + } + } + + /** + * Returns all positions of the given category that are inside the given region. + * + * @param category the position category + * @param offset the start position of the region, must be >= 0 + * @param length the length of the region, must be >= 0 + * @param canStartBefore if true then positions are included + * which start before the region if they end at or after the regions start + * @param canEndAfter if true then positions are included + * which end after the region if they start at or before the regions end + * @return all positions inside the region of the given category + * @throws BadPositionCategoryException if category is undefined in this document + * @since 3.4 + */ + public Position[] getPositions(String category, int offset, int length, bool canStartBefore, bool canEndAfter) { + if (canStartBefore && canEndAfter || (!canStartBefore && !canEndAfter)) { + List documentPositions; + if (canStartBefore && canEndAfter) { + if (offset < getLength() / 2) { + documentPositions= getStartingPositions(category, 0, offset + length); + } else { + documentPositions= getEndingPositions(category, offset, getLength() - offset + 1); + } + } else { + documentPositions= getStartingPositions(category, offset, length); + } + + ArrayList list= new ArrayList(documentPositions.size()); + + Position region= new Position(offset, length); + + for (Iterator iterator= documentPositions.iterator(); iterator.hasNext();) { + Position position= cast(Position) iterator.next(); + if (isWithinRegion(region, position, canStartBefore, canEndAfter)) { + list.add(position); + } + } + + Position[] positions= new Position[list.size()]; + list.toArray(positions); + return positions; + } else if (canStartBefore) { + List list= getEndingPositions(category, offset, length); + Position[] positions= new Position[list.size()]; + list.toArray(positions); + return positions; + } else { + Assert.isLegal(canEndAfter && !canStartBefore); + + List list= getStartingPositions(category, offset, length); + Position[] positions= new Position[list.size()]; + list.toArray(positions); + return positions; + } + } + + /* + * @since 3.4 + */ + private bool isWithinRegion(Position region, Position position, bool canStartBefore, bool canEndAfter) { + if (canStartBefore && canEndAfter) { + return region.overlapsWith(position.getOffset(), position.getLength()); + } else if (canStartBefore) { + return region.includes(position.getOffset() + position.getLength() - 1); + } else if (canEndAfter) { + return region.includes(position.getOffset()); + } else { + int start= position.getOffset(); + return region.includes(start) && region.includes(start + position.getLength() - 1); + } + } + + /** + * A list of positions in the given category with an offset inside the given + * region. The order of the positions is arbitrary. + * + * @param category the position category + * @param offset the offset of the region + * @param length the length of the region + * @return a list of the positions in the region + * @throws BadPositionCategoryException if category is undefined in this document + * @since 3.4 + */ + private List getStartingPositions(String category, int offset, int length) { + List positions= cast(List) fPositions.get(category); + if (positions is null) + throw new BadPositionCategoryException(); + + int indexStart= computeIndexInPositionList(positions, offset, true); + int indexEnd= computeIndexInPositionList(positions, offset + length, true); + + return positions.subList(indexStart, indexEnd); + } + + /** + * A list of positions in the given category with an end position inside + * the given region. The order of the positions is arbitrary. + * + * @param category the position category + * @param offset the offset of the region + * @param length the length of the region + * @return a list of the positions in the region + * @throws BadPositionCategoryException if category is undefined in this document + * @since 3.4 + */ + private List getEndingPositions(String category, int offset, int length) { + List positions= cast(List) fEndPositions.get(category); + if (positions is null) + throw new BadPositionCategoryException(); + + int indexStart= computeIndexInPositionList(positions, offset, false); + int indexEnd= computeIndexInPositionList(positions, offset + length, false); + + return positions.subList(indexStart, indexEnd); + } + + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/AbstractHoverInformationControlManager.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/AbstractHoverInformationControlManager.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,1138 @@ +/******************************************************************************* + * 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 + * 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.text.AbstractHoverInformationControlManager; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; +import tango.text.convert.Format; + +import dwt.DWT; +import dwt.events.ControlEvent; +import dwt.events.ControlListener; +import dwt.events.KeyEvent; +import dwt.events.KeyListener; +import dwt.events.MouseEvent; +import dwt.events.MouseListener; +import dwt.events.MouseMoveListener; +import dwt.events.MouseTrackListener; +import dwt.events.SelectionEvent; +import dwt.events.SelectionListener; +import dwt.events.ShellAdapter; +import dwt.events.ShellEvent; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Listener; +import dwt.widgets.ScrollBar; +import dwt.widgets.Scrollable; +import dwtx.core.runtime.Assert; +import dwtx.core.runtime.IProgressMonitor; +import dwtx.core.runtime.IStatus; +import dwtx.core.runtime.Status; +import dwtx.core.runtime.jobs.Job; +import dwtx.jface.internal.text.DelayedInputChangeListener; +import dwtx.jface.internal.text.InformationControlReplacer; +import dwtx.jface.internal.text.InternalAccessor; +import dwtx.jface.text.ITextViewerExtension8; +import dwtx.jface.text.source.AnnotationBarHoverManager; +import dwtx.jface.util.Geometry; + + +/** + * An information control manager that shows information in response to mouse + * hover events. The mouse hover events are caught by registering a + * {@link dwt.events.MouseTrackListener} on the manager's subject + * control. The manager has by default an information control closer that closes + * the information control as soon as the mouse pointer leaves the subject area, + * the user presses a key, or the subject control is resized, moved, or + * deactivated. + *

                + * When being activated by a mouse hover event, the manager disables itself, + * until the mouse leaves the subject area. Thus, the manager is usually still + * disabled, when the information control has already been closed by the closer. + * + * @see dwt.events.MouseTrackListener + * @since 2.0 + */ +abstract public class AbstractHoverInformationControlManager : AbstractInformationControlManager { + + /** + * The information control closer for the hover information. Closes the information control as + * soon as the mouse pointer leaves the subject area (unless "move into hover" is enabled), + * a mouse button is pressed, the user presses a key, or the subject control is resized, moved, or loses focus. + */ + class Closer : IInformationControlCloser, MouseListener, MouseMoveListener, ControlListener, KeyListener, SelectionListener, Listener { + + /** The closer's subject control */ + private Control fSubjectControl; + /** The subject area */ + private Rectangle fSubjectArea; + /** Indicates whether this closer is active */ + private bool fIsActive= false; + /** + * The cached display. + * @since 3.1 + */ + private Display fDisplay; + + + /** + * Creates a new information control closer. + */ + public this() { + } + + /* + * @see IInformationControlCloser#setSubjectControl(Control) + */ + public void setSubjectControl(Control control) { + fSubjectControl= control; + } + + /* + * @see IInformationControlCloser#setHoverControl(IHoverControl) + */ + public void setInformationControl(IInformationControl control) { + // NOTE: we use getCurrentInformationControl() from the outer class + } + + /* + * @see IInformationControlCloser#start(Rectangle) + */ + public void start(Rectangle subjectArea) { + + if (fIsActive) + return; + fIsActive= true; + fWaitForMouseUp= false; + + fSubjectArea= subjectArea; + + if (fSubjectControl !is null && !fSubjectControl.isDisposed()) { + fSubjectControl.addMouseListener(this); + fSubjectControl.addMouseMoveListener(this); + fSubjectControl.addControlListener(this); + fSubjectControl.addKeyListener(this); + if ( cast(Scrollable)fSubjectControl ) { + Scrollable scrollable= cast(Scrollable) fSubjectControl; + ScrollBar vBar= scrollable.getVerticalBar(); + if (vBar !is null) + vBar.addSelectionListener(this); + ScrollBar hBar= scrollable.getHorizontalBar(); + if (hBar !is null) + hBar.addSelectionListener(this); + } + + fDisplay= fSubjectControl.getDisplay(); + if (!fDisplay.isDisposed()) { + fDisplay.addFilter(DWT.Activate, this); + fDisplay.addFilter(DWT.MouseWheel, this); + + fDisplay.addFilter(DWT.FocusOut, this); + + fDisplay.addFilter(DWT.MouseDown, this); + fDisplay.addFilter(DWT.MouseUp, this); + + fDisplay.addFilter(DWT.MouseMove, this); + fDisplay.addFilter(DWT.MouseEnter, this); + fDisplay.addFilter(DWT.MouseExit, this); + } + } + } + + /* + * @see IInformationControlCloser#stop() + */ + public void stop() { + if (!fIsActive) + return; + + fIsActive= false; + + if (DEBUG) + System.out_.println("AbstractHoverInformationControlManager.Closer stopped"); //$NON-NLS-1$ + + if (fSubjectControl !is null && !fSubjectControl.isDisposed()) { + fSubjectControl.removeMouseListener(this); + fSubjectControl.removeMouseMoveListener(this); + fSubjectControl.removeControlListener(this); + fSubjectControl.removeKeyListener(this); + if ( cast(Scrollable)fSubjectControl ) { + Scrollable scrollable= cast(Scrollable) fSubjectControl; + ScrollBar vBar= scrollable.getVerticalBar(); + if (vBar !is null) + vBar.removeSelectionListener(this); + ScrollBar hBar= scrollable.getHorizontalBar(); + if (hBar !is null) + hBar.removeSelectionListener(this); + } + } + + if (fDisplay !is null && !fDisplay.isDisposed()) { + fDisplay.removeFilter(DWT.Activate, this); + fDisplay.removeFilter(DWT.MouseWheel, this); + + fDisplay.removeFilter(DWT.FocusOut, this); + + fDisplay.removeFilter(DWT.MouseDown, this); + fDisplay.removeFilter(DWT.MouseUp, this); + + fDisplay.removeFilter(DWT.MouseMove, this); + fDisplay.removeFilter(DWT.MouseEnter, this); + fDisplay.removeFilter(DWT.MouseExit, this); + } + fDisplay= null; + } + + /* + * @see dwt.events.MouseMoveListener#mouseMove(dwt.events.MouseEvent) + */ + public void mouseMove(MouseEvent event) { + if (!hasInformationControlReplacer() || !canMoveIntoInformationControl(getCurrentInformationControl())) { + if (!fSubjectArea.contains(event.x, event.y)) { + hideInformationControl(); + } + + } else if (getCurrentInformationControl() !is null && !getCurrentInformationControl().isFocusControl()) { + if (!inKeepUpZone(event.x, event.y, fSubjectControl, fSubjectArea, true)) { + hideInformationControl(); + } + } + } + + /* + * @see dwt.events.MouseListener#mouseUp(dwt.events.MouseEvent) + */ + public void mouseUp(MouseEvent event) { + } + + /* + * @see MouseListener#mouseDown(MouseEvent) + */ + public void mouseDown(MouseEvent event) { + hideInformationControl(); + } + + /* + * @see MouseListener#mouseDoubleClick(MouseEvent) + */ + public void mouseDoubleClick(MouseEvent event) { + hideInformationControl(); + } + + /* + * @see ControlListener#controlResized(ControlEvent) + */ + public void controlResized(ControlEvent event) { + hideInformationControl(); + } + + /* + * @see ControlListener#controlMoved(ControlEvent) + */ + public void controlMoved(ControlEvent event) { + hideInformationControl(); + } + + /* + * @see KeyListener#keyReleased(KeyEvent) + */ + public void keyReleased(KeyEvent event) { + } + + /* + * @see KeyListener#keyPressed(KeyEvent) + */ + public void keyPressed(KeyEvent event) { + hideInformationControl(); + } + + /* + * @see dwt.events.SelectionListener#widgetSelected(dwt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + hideInformationControl(); + } + + /* + * @see dwt.events.SelectionListener#widgetDefaultSelected(dwt.events.SelectionEvent) + */ + public void widgetDefaultSelected(SelectionEvent e) { + } + + /* + * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event) + * @since 3.1 + */ + public void handleEvent(Event event) { + switch (event.type) { + case DWT.Activate: + case DWT.MouseWheel: + if (!hasInformationControlReplacer()) + hideInformationControl(); + else if (!isReplaceInProgress()) { + IInformationControl infoControl= getCurrentInformationControl(); + // During isReplaceInProgress(), events can come from the replacing information control + if ( cast(Control)event.widget && cast(IInformationControlExtension5)infoControl ) { + Control control= cast(Control) event.widget; + IInformationControlExtension5 iControl5= cast(IInformationControlExtension5) infoControl; + if (!(iControl5.containsControl(control))) + hideInformationControl(); + else if (event.type is DWT.MouseWheel && cancelReplacingDelay()) + replaceInformationControl(false); + } else if (infoControl !is null && infoControl.isFocusControl() && cancelReplacingDelay()) { + replaceInformationControl(true); + } + } + break; + + case DWT.MouseUp: + case DWT.MouseDown: + if (!hasInformationControlReplacer()) + hideInformationControl(); + else if (!isReplaceInProgress()) { + IInformationControl infoControl= getCurrentInformationControl(); + if ( cast(Control)event.widget && cast(IInformationControlExtension5)infoControl ) { + Control control= cast(Control) event.widget; + final IInformationControlExtension5 iControl5= cast(IInformationControlExtension5) infoControl; + if (!(iControl5.containsControl(control))) { + hideInformationControl(); + } else if (cancelReplacingDelay()) { + if (event.type is DWT.MouseUp) { + stop(); // avoid that someone else replaces the info control before the async is exec'd + if ( cast(IDelayedInputChangeProvider)infoControl ) { + final IDelayedInputChangeProvider delayedICP= cast(IDelayedInputChangeProvider) infoControl; + final IInputChangedListener inputChangeListener= new DelayedInputChangeListener(delayedICP, getInformationControlReplacer()); + delayedICP.setDelayedInputChangeListener(inputChangeListener); + // cancel automatic input updating after a small timeout: + control.getShell().getDisplay().timerExec(1000, new class() Runnable { + public void run() { + delayedICP.setDelayedInputChangeListener(null); + } + }); + } + + // XXX: workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=212392 : + control.getShell().getDisplay().asyncExec(new class() Runnable { + public void run() { + replaceInformationControl(true); + } + }); + } else { + fWaitForMouseUp= true; + } + } + } else { + handleMouseMove(event); + } + } + break; + + case DWT.FocusOut: + IInformationControl iControl= getCurrentInformationControl(); + if (iControl !is null && ! iControl.isFocusControl()) + hideInformationControl(); + break; + + case DWT.MouseMove: + case DWT.MouseEnter: + case DWT.MouseExit: + handleMouseMove(event); + break; + } + } + + /** + * Handle mouse movement events. + * + * @param event the event + * @since 3.4 + */ + private void handleMouseMove(Event event) { +// if (DEBUG) +// System.out_.println("AbstractHoverInformationControl.Closer.handleMouseMove():" + event); //$NON-NLS-1$ + + if (!( cast(Control)event.widget )) + return; + Control eventControl= cast(Control) event.widget; + + //transform coordinates to subject control: + Point mouseLoc= event.display.map(eventControl, fSubjectControl, event.x, event.y); + + if (fSubjectArea.contains(mouseLoc)) + return; + + IInformationControl iControl= getCurrentInformationControl(); + if (!hasInformationControlReplacer() || !canMoveIntoInformationControl(iControl)) { + if ( cast(AnnotationBarHoverManager)this.outer ) { + if (getInternalAccessor().getAllowMouseExit()) + return; + } + hideInformationControl(); + return; + } + + IInformationControlExtension3 iControl3= cast(IInformationControlExtension3) iControl; + Rectangle controlBounds= iControl3.getBounds(); + if (controlBounds !is null) { + Rectangle tooltipBounds= event.display.map(null, eventControl, controlBounds); + if (tooltipBounds.contains(event.x, event.y)) { + if (!isReplaceInProgress() && event.type !is DWT.MouseExit) + startReplaceInformationControl(event.display); + return; + } + cancelReplacingDelay(); + } + + if (!fSubjectControl.getBounds().contains(mouseLoc)) { + /* + * Use inKeepUpZone() to make sure it also works when the hover is + * completely outside of the subject control. + */ + if (!inKeepUpZone(mouseLoc.x, mouseLoc.y, fSubjectControl, fSubjectArea, true)) { + hideInformationControl(); + return; + } + } + } + } + + /** + * To be installed on the manager's subject control. Serves two different purposes: + *

                  + *
                • start function: initiates the computation of the information to be presented. This happens on + * receipt of a mouse hover event and disables the information control manager, + *
                • restart function: tracks mouse move and shell activation event to determine when the information + * control manager needs to be reactivated. + *
                + */ + class MouseTracker : ShellAdapter , MouseTrackListener, MouseMoveListener { + + /** Margin around the original hover event location for computing the hover area. */ + private const static int EPSILON= 3; + + /** The area in which the original hover event occurred. */ + private Rectangle fHoverArea; + /** The area for which is computed information is valid. */ + private Rectangle fSubjectArea; + /** The tracker's subject control. */ + private Control fSubjectControl; + + /** Indicates whether the tracker is in restart mode ignoring hover events. */ + private bool fIsInRestartMode= false; + /** Indicates whether the tracker is computing the information to be presented. */ + private bool fIsComputing= false; + /** Indicates whether the mouse has been lost. */ + private bool fMouseLostWhileComputing= false; + /** Indicates whether the subject control's shell has been deactivated. */ + private bool fShellDeactivatedWhileComputing= false; + + /** + * Creates a new mouse tracker. + */ + public this() { + } + + /** + * Sets this mouse tracker's subject area, the area to be tracked in order + * to re-enable the information control manager. + * + * @param subjectArea the subject area + */ + public void setSubjectArea(Rectangle subjectArea) { + Assert.isNotNull(subjectArea); + fSubjectArea= subjectArea; + } + + /** + * Starts this mouse tracker. The given control becomes this tracker's subject control. + * Installs itself as mouse track listener on the subject control. + * + * @param subjectControl the subject control + */ + public void start(Control subjectControl) { + fSubjectControl= subjectControl; + if (fSubjectControl !is null && !fSubjectControl.isDisposed()) + fSubjectControl.addMouseTrackListener(this); + + fIsInRestartMode= false; + fIsComputing= false; + fMouseLostWhileComputing= false; + fShellDeactivatedWhileComputing= false; + } + + /** + * Stops this mouse tracker. Removes itself as mouse track, mouse move, and + * shell listener from the subject control. + */ + public void stop() { + if (fSubjectControl !is null && !fSubjectControl.isDisposed()) { + fSubjectControl.removeMouseTrackListener(this); + fSubjectControl.removeMouseMoveListener(this); + fSubjectControl.getShell().removeShellListener(this); + } + } + + /** + * Initiates the computation of the information to be presented. Sets the initial hover area + * to a small rectangle around the hover event location. Adds mouse move and shell activation listeners + * to track whether the computed information is, after completion, useful for presentation and to + * implement the restart function. + * + * @param event the mouse hover event + */ + public void mouseHover(MouseEvent event) { + if (fIsComputing || fIsInRestartMode || + (fSubjectControl !is null && !fSubjectControl.isDisposed() && fSubjectControl.getShell() !is fSubjectControl.getShell().getDisplay().getActiveShell())) { + if (DEBUG) + System.out_.println(Format("AbstractHoverInformationControlManager...mouseHover: @ {}/{} : hover cancelled: fIsComputing= {}, fIsInRestartMode= {}", event.x, event.y, fIsComputing, fIsInRestartMode)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + return; + } + + fIsInRestartMode= true; + fIsComputing= true; + fMouseLostWhileComputing= false; + fShellDeactivatedWhileComputing= false; + + fHoverEventStateMask= event.stateMask; + fHoverEvent= event; + fHoverArea= new Rectangle(event.x - EPSILON, event.y - EPSILON, 2 * EPSILON, 2 * EPSILON ); + if (fHoverArea.x < 0) + fHoverArea.x= 0; + if (fHoverArea.y < 0) + fHoverArea.y= 0; + setSubjectArea(fHoverArea); + + if (fSubjectControl !is null && !fSubjectControl.isDisposed()) { + fSubjectControl.addMouseMoveListener(this); + fSubjectControl.getShell().addShellListener(this); + } + doShowInformation(); + } + + /** + * Deactivates this tracker's restart function and enables the information control + * manager. Does not have any effect if the tracker is still executing the start function (i.e. + * computing the information to be presented. + */ + protected void deactivate() { + if (fIsComputing) + return; + + fIsInRestartMode= false; + if (fSubjectControl !is null && !fSubjectControl.isDisposed()) { + fSubjectControl.removeMouseMoveListener(this); + fSubjectControl.getShell().removeShellListener(this); + } + } + + /* + * @see MouseTrackListener#mouseEnter(MouseEvent) + */ + public void mouseEnter(MouseEvent e) { + } + + /* + * @see MouseTrackListener#mouseExit(MouseEvent) + */ + public void mouseExit(MouseEvent e) { + if (!hasInformationControlReplacer() || !canMoveIntoInformationControl(getCurrentInformationControl()) || !inKeepUpZone(e.x, e.y, fSubjectControl, fSubjectArea, false)) { + fMouseLostWhileComputing= true; + deactivate(); + } + } + + /* + * @see MouseMoveListener#mouseMove(MouseEvent) + */ + public void mouseMove(MouseEvent event) { + if (!hasInformationControlReplacer() || !canMoveIntoInformationControl(getCurrentInformationControl())) { + if (!fSubjectArea.contains(event.x, event.y)) + deactivate(); + } else { + if (!inKeepUpZone(event.x, event.y, fSubjectControl, fSubjectArea, false)) + deactivate(); + } + } + + /* + * @see ShellListener#shellDeactivated(ShellEvent) + */ + public void shellDeactivated(ShellEvent e) { + fShellDeactivatedWhileComputing= true; + deactivate(); + } + + /* + * @see ShellListener#shellIconified(ShellEvent) + */ + public void shellIconified(ShellEvent e) { + fShellDeactivatedWhileComputing= true; + deactivate(); + } + + /** + * Tells this tracker that the start function processing has been completed. + */ + public void computationCompleted() { + fIsComputing= false; + fMouseLostWhileComputing= false; + fShellDeactivatedWhileComputing= false; + } + + /** + * Determines whether the computed information is still useful for presentation. + * This is not the case, if the shell of the subject control has been deactivated, the mouse + * left the subject control, or the mouse moved on, so that it is no longer in the subject + * area. + * + * @return true if information is still useful for presentation, false otherwise + */ + public bool isMouseLost() { + + if (fMouseLostWhileComputing || fShellDeactivatedWhileComputing) + return true; + + if (fSubjectControl !is null && !fSubjectControl.isDisposed()) { + Display display= fSubjectControl.getDisplay(); + Point p= display.getCursorLocation(); + p= fSubjectControl.toControl(p); + if (!fSubjectArea.contains(p) && !fHoverArea.contains(p)) + return true; + } + + return false; + } + } + + /** + * The delay in {@link ITextViewerExtension8.EnrichMode#AFTER_DELAY} mode after which + * the hover is enriched when the mouse has stopped moving inside the hover. + * @since 3.4 + */ + private static const long HOVER_AUTO_REPLACING_DELAY= 200; + + /** The mouse tracker on the subject control */ + private MouseTracker fMouseTracker; + /** + * The remembered hover event. + * @since 3.0 + */ + private MouseEvent fHoverEvent= null; + /** The remembered hover event state mask of the keyboard modifiers */ + private int fHoverEventStateMask= 0; + /** + * The thread that delays replacing of the hover information control. + * To be accessed in the UI thread only! + * + * @since 3.4 + */ + private Job fReplacingDelayJob; + + /** + * The {@link ITextViewerExtension8.EnrichMode}, may be null. + * @since 3.4 + */ + private ITextViewerExtension8_EnrichMode fEnrichMode; + + /** + * Indicates whether we have received a MouseDown event and are waiting for a MouseUp + * (and don't replace the information control until that happened). + * @since 3.4 + */ + private bool fWaitForMouseUp= false; + + /** + * Creates a new hover information control manager using the given information control creator. + * By default a Closer instance is set as this manager's closer. + * + * @param creator the information control creator + */ + protected this(IInformationControlCreator creator) { + fMouseTracker= new MouseTracker(); + super(creator); + setCloser(new Closer()); + setHoverEnrichMode(ITextViewerExtension8_EnrichMode.AFTER_DELAY); + } + + /** + * Tests whether a given mouse location is within the keep-up zone. + * The hover should not be hidden as long as the mouse stays inside this zone. + * + * @param x the x coordinate, relative to the subject control + * @param y the y coordinate, relative to the subject control + * @param subjectControl the subject control + * @param subjectArea the area for which the presented information is valid + * @param blowUp If true, then calculate for the closer, i.e. blow up the keepUp area. + * If false, then use tight bounds for hover detection. + * + * @return true iff the mouse event occurred in the keep-up zone + * @since 3.4 + */ + private bool inKeepUpZone(int x, int y, Control subjectControl, Rectangle subjectArea, bool blowUp) { + if (subjectArea.contains(x, y)) + return true; + + IInformationControl iControl= getCurrentInformationControl(); + if (( cast(IInformationControlExtension5)iControl && !(cast(IInformationControlExtension5) iControl).isVisible())) { + iControl= null; + if (getInformationControlReplacer() !is null) { + iControl= getInformationControlReplacer().getCurrentInformationControl2(); + if (( cast(IInformationControlExtension5)iControl && !(cast(IInformationControlExtension5) iControl).isVisible())) { + return false; + } + } + } + if ( cast(IInformationControlExtension3)iControl ) { + IInformationControlExtension3 iControl3= cast(IInformationControlExtension3) iControl; + + Rectangle iControlBounds= subjectControl.getDisplay().map(null, subjectControl, iControl3.getBounds()); + Rectangle totalBounds= Geometry.copy(iControlBounds); + if (blowUp && isReplaceInProgress()) { + //Problem: blown up iControl overlaps rest of subjectArea's line + // solution for now: only blow up for keep up (closer), but not for further hover detection + int margin= getInformationControlReplacer().getKeepUpMargin(); + Geometry.expand(totalBounds, margin, margin, margin, margin); + } + + if (!blowUp) { + if (iControlBounds.contains(x, y)) + return true; + + if (subjectArea.y + subjectArea.height < iControlBounds.y) { + // special case for hover events: subjectArea totally above iControl: + // +-----------+ + // |subjectArea| + // +-----------+ + // |also keepUp| + // ++-----------+-------+ + // | InformationControl | + // +--------------------+ + if (subjectArea.y + subjectArea.height <= y && y <= totalBounds.y) { + // is vertically between subject area and iControl + if (subjectArea.x <= x && x <= subjectArea.x + subjectArea.width) { + // is below subject area (in a vertical projection) + return true; + } + // FIXME: cases when subjectArea extends to left or right of iControl? + } + return false; + + } else if (iControlBounds.x + iControlBounds.width < subjectArea.x) { + // special case for hover events (e.g. in overview ruler): iControl totally left of subjectArea + // +--------------------+-----------+ + // | | +-----------+ + // | InformationControl |also keepUp|subjectArea| + // | | +-----------+ + // +--------------------+-----------+ + if (iControlBounds.x + iControlBounds.width <= x && x <= subjectArea.x) { + // is horizontally between iControl and subject area + if (iControlBounds.y <= y && y <= iControlBounds.y + iControlBounds.height) { + // is to the right of iControl (in a horizontal projection) + return true; + } + } + return false; + + } else if (subjectArea.x + subjectArea.width < iControlBounds.x) { + // special case for hover events (e.g. in annotation ruler): subjectArea totally left of iControl + // +-----------+--------------------+ + // +-----------+ | | + // |subjectArea|also keepUp| InformationControl | + // +-----------+ | | + // +-----------+--------------------+ + if (subjectArea.x + subjectArea.width <= x && x <= iControlBounds.x) { + // is horizontally between subject area and iControl + if (iControlBounds.y <= y && y <= iControlBounds.y + iControlBounds.height) { + // is to the left of iControl (in a horizontal projection) + return true; + } + } + return false; + } + } + + // FIXME: should maybe use convex hull, not bounding box + totalBounds.add(subjectArea); + if (totalBounds.contains(x, y)) + return true; + } + return false; + } + + /** + * Tests whether the given information control allows the mouse to be moved + * into it. + * + * @param iControl information control or null if none + * @return true if information control allows mouse move into + * control, false otherwise + */ + bool canMoveIntoInformationControl(IInformationControl iControl) { + return fEnrichMode !is null && canReplace(iControl); + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#hideInformationControl() + */ + protected void hideInformationControl() { + cancelReplacingDelay(); + super.hideInformationControl(); + } + + /** + * Sets the hover enrich mode. Only applicable when an information + * control replacer has been set with + * {@link #setInformationControlReplacer(InformationControlReplacer)} . + * + * @param mode the enrich mode + * @since 3.4 + * @see ITextViewerExtension8#setHoverEnrichMode(dwtx.jface.text.ITextViewerExtension8.EnrichMode) + */ + void setHoverEnrichMode(ITextViewerExtension8_EnrichMode mode) { + fEnrichMode= mode; + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#replaceInformationControl(bool) + */ + void replaceInformationControl(bool takeFocus) { + fWaitForMouseUp= false; + super.replaceInformationControl(takeFocus); + } + + /** + * Cancels the replacing delay job. + * @return true iff canceling was successful, false if replacing has already started + */ + bool cancelReplacingDelay() { + fWaitForMouseUp= false; + if (fReplacingDelayJob !is null && fReplacingDelayJob.getState() !is Job.RUNNING) { + bool cancelled= fReplacingDelayJob.cancel(); + fReplacingDelayJob= null; +// if (DEBUG) +// System.out_.println("AbstractHoverInformationControlManager.cancelReplacingDelay(): cancelled=" + cancelled); //$NON-NLS-1$ + return cancelled; + } +// if (DEBUG) +// System.out_.println("AbstractHoverInformationControlManager.cancelReplacingDelay(): not delayed"); //$NON-NLS-1$ + return true; + } + + /** + * Starts replacing the information control, considering the current + * {@link ITextViewerExtension8.EnrichMode}. + * If set to {@link ITextViewerExtension8.EnrichMode#AFTER_DELAY}, this + * method cancels previous requests and restarts the delay timer. + * + * @param display the display to be used for the call to + * {@link #replaceInformationControl(bool)} in the UI thread + */ + private void startReplaceInformationControl(Display display) { + if (fEnrichMode is ITextViewerExtension8_EnrichMode.ON_CLICK) + return; + + if (fReplacingDelayJob !is null) { + if (fReplacingDelayJob.getState() !is Job.RUNNING) { + if (fReplacingDelayJob.cancel()) { + if (fEnrichMode is ITextViewerExtension8_EnrichMode.IMMEDIATELY) { + fReplacingDelayJob= null; + if (! fWaitForMouseUp) + replaceInformationControl(false); + } else { +// if (DEBUG) +// System.out_.println("AbstractHoverInformationControlManager.startReplaceInformationControl(): rescheduled"); //$NON-NLS-1$ + fReplacingDelayJob.schedule(HOVER_AUTO_REPLACING_DELAY); + } + } + } + return; + } + + fReplacingDelayJob= new class("AbstractHoverInformationControlManager Replace Delayer", display) Job { //$NON-NLS-1$ + Display display_; + this( String str, Display b){ + super(str); + display_=b; + } + public IStatus run(IProgressMonitor monitor) { + if (monitor.isCanceled() || display_.isDisposed()) { + return Status.CANCEL_STATUS; + } + display_.syncExec(dgRunnable( (IProgressMonitor monitor_) { + fReplacingDelayJob= null; + if (monitor_.isCanceled()) + return; + if (! fWaitForMouseUp) + replaceInformationControl(false); + }, monitor )); + return Status.OK_STATUS; + } + }; + fReplacingDelayJob.setSystem(true); + fReplacingDelayJob.setPriority(Job.INTERACTIVE); +// if (DEBUG) +// System.out_.println("AbstractHoverInformationControlManager.startReplaceInformationControl(): scheduled"); //$NON-NLS-1$ + fReplacingDelayJob.schedule(HOVER_AUTO_REPLACING_DELAY); + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#presentInformation() + */ + protected void presentInformation() { + if (fMouseTracker is null) { + super.presentInformation(); + return; + } + + Rectangle area= getSubjectArea(); + if (area !is null) + fMouseTracker.setSubjectArea(area); + + if (fMouseTracker.isMouseLost()) { + fMouseTracker.computationCompleted(); + fMouseTracker.deactivate(); + } else { + fMouseTracker.computationCompleted(); + super.presentInformation(); + } + } + + /** + * {@inheritDoc} + * @deprecated visibility will be changed to protected + */ + public void setEnabled(bool enabled) { + + bool was= isEnabled(); + super.setEnabled(enabled); + bool is_= isEnabled(); + + if (was !is is_ && fMouseTracker !is null) { + if (is_) + fMouseTracker.start(getSubjectControl()); + else + fMouseTracker.stop(); + } + } + + /** + * Disposes this manager's information control. + */ + public void dispose() { + if (fMouseTracker !is null) { + fMouseTracker.stop(); + fMouseTracker.fSubjectControl= null; + fMouseTracker= null; + } + super.dispose(); + } + + /** + * Returns the location at which the most recent mouse hover event + * has been issued. + * + * @return the location of the most recent mouse hover event + */ + protected Point getHoverEventLocation() { + return fHoverEvent !is null ? new Point(fHoverEvent.x, fHoverEvent.y) : new Point(-1, -1); + } + package Point getHoverEventLocation_package() { + return getHoverEventLocation(); + } + + /** + * Returns the most recent mouse hover event. + * + * @return the most recent mouse hover event or null + * @since 3.0 + */ + protected MouseEvent getHoverEvent() { + return fHoverEvent; + } + + /** + * Returns the DWT event state of the most recent mouse hover event. + * + * @return the DWT event state of the most recent mouse hover event + */ + protected int getHoverEventStateMask() { + return fHoverEventStateMask; + } + + /** + * Returns an adapter that gives access to internal methods. + *

                + * Note: This method is not intended to be referenced or overridden by clients.

                + * + * @return the replaceable information control accessor + * @since 3.4 + * @noreference This method is not intended to be referenced by clients. + * @nooverride This method is not intended to be re-implemented or extended by clients. + */ + public InternalAccessor getInternalAccessor() { + return new MyInternalAccessor2(this); + } + static class MyInternalAccessor2 : MyInternalAccessor { + AbstractHoverInformationControlManager outer_; + this( AbstractHoverInformationControlManager a ){ + outer_=a; + super(a); + } + public void setHoverEnrichMode(ITextViewerExtension8_EnrichMode mode) { + outer_.setHoverEnrichMode(mode); + } + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/AbstractInformationControl.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/AbstractInformationControl.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,900 @@ +/******************************************************************************* + * 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.text.AbstractInformationControl; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +// import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + +import dwt.DWT; +import dwt.events.DisposeListener; +import dwt.events.FocusEvent; +import dwt.events.FocusListener; +import dwt.events.MouseAdapter; +import dwt.events.MouseEvent; +import dwt.events.MouseMoveListener; +import dwt.events.PaintEvent; +import dwt.events.PaintListener; +import dwt.graphics.Color; +import dwt.graphics.Cursor; +import dwt.graphics.Font; +import dwt.graphics.FontData; +import dwt.graphics.GC; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.layout.FillLayout; +import dwt.layout.GridData; +import dwt.layout.GridLayout; +import dwt.widgets.Canvas; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Label; +import dwt.widgets.Listener; +import dwt.widgets.Shell; +import dwt.widgets.Slider; +import dwt.widgets.ToolBar; +import dwtx.core.runtime.Assert; +import dwtx.core.runtime.ListenerList; +import dwtx.jface.action.ToolBarManager; +import dwtx.jface.resource.JFaceResources; +import dwtx.jface.util.Geometry; + + +/** + * An abstract information control that can show content inside a shell. + * The information control can be created in two styles: + *
                  + *
                • non-resizable tooltip with optional status
                • + *
                • resizable tooltip with optional tool bar
                • + *
                + * Additionally it can present either a status line containing a status text or + * a toolbar containing toolbar buttons. + *

                + * Subclasses must either override {@link IInformationControl#setInformation(String)} + * or implement {@link IInformationControlExtension2}. + * They should also extend {@link #computeTrim()} if they create a content area + * with additional trim (e.g. scrollbars) and override {@link #getInformationPresenterControlCreator()}. + *

                + * + * @since 3.4 + */ +public abstract class AbstractInformationControl : IInformationControl, IInformationControlExtension, IInformationControlExtension3, IInformationControlExtension4, IInformationControlExtension5 { + + /** The information control's shell. */ + private const Shell fShell; + /** Composite containing the content created by subclasses. */ + private const Composite fContentComposite; + /** Whether the information control is resizable. */ + private const bool fResizable; + + /** Composite containing the status line content or null if none. */ + private Composite fStatusComposite; + /** Separator between content and status line or null if none. */ + private Label fSeparator; + /** Label in the status line or null if none. */ + private Label fStatusLabel; + /** The toolbar manager used by the toolbar or null if none. */ + private const ToolBarManager fToolBarManager; + /** Status line toolbar or null if none. */ + private ToolBar fToolBar; + + /** Listener for shell activation and deactivation. */ + private Listener fShellListener; + /** All focus listeners registered to this information control. */ + private ListenerList fFocusListeners; + + /** Size constraints, x is the maxWidth and y is the maxHeight, or null if not set. */ + private Point fSizeConstraints; + /** The size of the resize handle if already set, -1 otherwise */ + private int fResizeHandleSize; + + /** + * Creates an abstract information control with the given shell as parent. + * The control will not be resizable and optionally show a status line with + * the given status field text. + *

                + * Important: Subclasses are required to call {@link #create()} at the end of their constructor. + *

                + * + * @param parentShell the parent of this control's shell + * @param statusFieldText the text to be used in the status field or null to hide the status field + */ + public this(Shell parentShell, String statusFieldText) { + this(parentShell, DWT.TOOL | DWT.ON_TOP, statusFieldText, null); + } + + /** + * Creates an abstract information control with the given shell as parent. + * The control will be resizable and optionally show a tool bar managed by + * the given tool bar manager. + *

                + * Important: Subclasses are required to call {@link #create()} at the end of their constructor. + *

                + * + * @param parentShell the parent of this control's shell + * @param toolBarManager the manager or null if toolbar is not desired + */ + public this(Shell parentShell, ToolBarManager toolBarManager) { + this(parentShell, DWT.TOOL | DWT.ON_TOP | DWT.RESIZE, null, toolBarManager); + } + + /** + * Creates an abstract information control with the given shell as parent. + *

                + * Important: Subclasses are required to call {@link #create()} at the end of their constructor. + *

                + * + * @param parentShell the parent of this control's shell + * @param isResizable true if the control should be resizable + */ + public this(Shell parentShell, bool isResizable) { + this(parentShell, DWT.TOOL | DWT.ON_TOP | (isResizable ? DWT.RESIZE : 0), null, null); + } + + /** + * Creates an abstract information control with the given shell as parent. + * The given shell style is used for the shell (NO_TRIM will be removed to make sure there's a border). + *

                + * The control will optionally show either a status line or a tool bar. + * At most one of toolBarManager or statusFieldText can be non-null. + *

                + *

                + * Important:: Subclasses are required to call {@link #create()} at the end of their constructor. + *

                + * + * @param parentShell the parent of this control's shell + * @param shellStyle style of this control's shell + * @param statusFieldText the text to be used in the status field or null to hide the status field + * @param toolBarManager the manager or null if toolbar is not desired + * + * @deprecated clients should use one of the public constructors + */ + this(Shell parentShell, int shellStyle, String statusFieldText, ToolBarManager toolBarManager) { + + fFocusListeners= new ListenerList(ListenerList.IDENTITY); + + Assert.isTrue(statusFieldText is null || toolBarManager is null); + fResizeHandleSize= -1; + fToolBarManager= toolBarManager; + + if ((shellStyle & DWT.NO_TRIM) !is 0) + shellStyle&= ~(DWT.NO_TRIM | DWT.SHELL_TRIM); // make sure we get the OS border but no other trims + + fResizable= (shellStyle & DWT.RESIZE) !is 0; // on GTK, Shell removes DWT.RESIZE if DWT.ON_TOP is set + fShell= new Shell(parentShell, shellStyle); + Display display= fShell.getDisplay(); + Color foreground= display.getSystemColor(DWT.COLOR_INFO_FOREGROUND); + Color background= display.getSystemColor(DWT.COLOR_INFO_BACKGROUND); + setColor(fShell, foreground, background); + + GridLayout layout= new GridLayout(1, false); + layout.marginHeight= 0; + layout.marginWidth= 0; + layout.verticalSpacing= 0; + fShell.setLayout(layout); + + fContentComposite= new Composite(fShell, DWT.NONE); + fContentComposite.setLayoutData(new GridData(DWT.FILL, DWT.FILL, true, true)); + fContentComposite.setLayout(new FillLayout()); + setColor(fContentComposite, foreground, background); + + createStatusComposite(statusFieldText, toolBarManager, foreground, background); + } + + private void createStatusComposite(String statusFieldText, ToolBarManager toolBarManager, Color foreground, Color background) { + if (toolBarManager is null && statusFieldText is null) + return; + + fStatusComposite= new Composite(fShell, DWT.NONE); + GridData gridData= new GridData(DWT.FILL, DWT.BOTTOM, true, false); + fStatusComposite.setLayoutData(gridData); + GridLayout statusLayout= new GridLayout(1, false); + statusLayout.marginHeight= 0; + statusLayout.marginWidth= 0; + statusLayout.verticalSpacing= 1; + fStatusComposite.setLayout(statusLayout); + + fSeparator= new Label(fStatusComposite, DWT.SEPARATOR | DWT.HORIZONTAL); + fSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + if (statusFieldText !is null) { + createStatusLabel(statusFieldText, foreground, background); + } else { + createToolBar(toolBarManager); + } + } + + private void createStatusLabel(String statusFieldText, Color foreground, Color background) { + fStatusLabel= new Label(fStatusComposite, DWT.RIGHT); + fStatusLabel.setLayoutData(new GridData(DWT.FILL, DWT.CENTER, true, false)); + fStatusLabel.setText(statusFieldText); + + FontData[] fontDatas= JFaceResources.getDialogFont().getFontData(); + for (int i= 0; i < fontDatas.length; i++) { + fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10); + } + fStatusLabel.setFont(new Font(fStatusLabel.getDisplay(), fontDatas)); + + fStatusLabel.setForeground(fStatusLabel.getDisplay().getSystemColor(DWT.COLOR_WIDGET_DARK_SHADOW)); + fStatusLabel.setBackground(background); + setColor(fStatusComposite, foreground, background); + } + + private void createToolBar(ToolBarManager toolBarManager) { + Composite bars= new Composite(fStatusComposite, DWT.NONE); + bars.setLayoutData(new GridData(DWT.FILL, DWT.FILL, false, false)); + + GridLayout layout= new GridLayout(3, false); + layout.marginHeight= 0; + layout.marginWidth= 0; + layout.horizontalSpacing= 0; + layout.verticalSpacing= 0; + bars.setLayout(layout); + + fToolBar= toolBarManager.createControl(bars); + GridData gd= new GridData(DWT.BEGINNING, DWT.BEGINNING, false, false); + fToolBar.setLayoutData(gd); + + Composite spacer= new Composite(bars, DWT.NONE); + gd= new GridData(DWT.FILL, DWT.FILL, true, true); + gd.widthHint= 0; + gd.heightHint= 0; + spacer.setLayoutData(gd); + + addMoveSupport(spacer); + addResizeSupportIfNecessary(bars); + } + + private void addResizeSupportIfNecessary(Composite bars) { + // XXX: workarounds for + // - https://bugs.eclipse.org/bugs/show_bug.cgi?id=219139 : API to add resize grip / grow box in lower right corner of shell + // - https://bugs.eclipse.org/bugs/show_bug.cgi?id=23980 : platform specific shell resize behavior + String platform= DWT.getPlatform(); + bool isWin= platform.equals("win32"); //$NON-NLS-1$ + if (!isWin && !platform.equals("gtk")) //$NON-NLS-1$ + return; + + Canvas resizer= new Canvas(bars, DWT.NONE); + + int size= getResizeHandleSize(bars); + + GridData data= new GridData(DWT.END, DWT.END, false, true); + data.widthHint= size; + data.heightHint= size; + resizer.setLayoutData(data); + resizer.addPaintListener(new class(isWin,resizer) PaintListener { + bool isWin_; + Canvas resizer_; + this(bool a, Canvas b ){ + isWin_=a; + resizer_=b; + } + public void paintControl(PaintEvent e) { + Point s= resizer_.getSize(); + int x= s.x - 2; + int y= s.y - 2; + int min= Math.min(x, y); + if (isWin_) { + // draw dots + e.gc.setBackground(resizer_.getDisplay().getSystemColor(DWT.COLOR_WIDGET_HIGHLIGHT_SHADOW)); + int end= min - 1; + for (int i= 0; i <= 2; i++) + for (int j= 0; j <= 2 - i; j++) + e.gc.fillRectangle(end - 4 * i, end - 4 * j, 2, 2); + end--; + e.gc.setBackground(resizer_.getDisplay().getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW)); + for (int i= 0; i <= 2; i++) + for (int j= 0; j <= 2 - i; j++) + e.gc.fillRectangle(end - 4 * i, end - 4 * j, 2, 2); + + } else { + // draw diagonal lines + e.gc.setForeground(resizer_.getDisplay().getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW)); + for (int i= 1; i < min; i+= 4) { + e.gc.drawLine(i, y, x, i); + } + e.gc.setForeground(resizer_.getDisplay().getSystemColor(DWT.COLOR_WIDGET_HIGHLIGHT_SHADOW)); + for (int i= 2; i < min; i+= 4) { + e.gc.drawLine(i, y, x, i); + } + } + } + }); + + resizer.setCursor(new Cursor(resizer.getDisplay(), DWT.CURSOR_SIZESE)); + MouseAdapter resizeSupport= new class(resizer) MouseAdapter { + Canvas resizer_; + this(Canvas a){ + resizer_=a; + } + private MouseMoveListener fResizeListener; + + public void mouseDown(MouseEvent e) { + Point shellSize= fShell.getSize(); + int shellX= shellSize.x; + int shellY= shellSize.y; + Point mouseLoc= resizer_.toDisplay(e.x, e.y); + int mouseX= mouseLoc.x; + int mouseY= mouseLoc.y; + fResizeListener= new class(shellX,shellY,mouseX,mouseY) MouseMoveListener { + int shellX_; + int shellY_; + int mouseX_; + int mouseY_; + this(int a, int b, int c, int d ){ + shellX_=a; + shellY_=b; + mouseX_=c; + mouseY_=d; + } + public void mouseMove(MouseEvent e2) { + Point mouseLoc2= resizer_.toDisplay(e2.x, e2.y); + int dx= mouseLoc2.x - mouseX_; + int dy= mouseLoc2.y - mouseY_; + setSize(shellX_ + dx, shellY_ + dy); + } + }; + resizer_.addMouseMoveListener(fResizeListener); + } + + public void mouseUp(MouseEvent e) { + resizer_.removeMouseMoveListener(fResizeListener); + fResizeListener= null; + } + }; + resizer.addMouseListener(resizeSupport); + } + + private int getResizeHandleSize(Composite parent) { + if (fResizeHandleSize is -1) { + Slider sliderV= new Slider(parent, DWT.VERTICAL); + Slider sliderH= new Slider(parent, DWT.HORIZONTAL); + int width= sliderV.computeSize(DWT.DEFAULT, DWT.DEFAULT).x; + int height= sliderH.computeSize(DWT.DEFAULT, DWT.DEFAULT).y; + sliderV.dispose(); + sliderH.dispose(); + fResizeHandleSize= Math.min(width, height); + } + + return fResizeHandleSize; + } + + /** + * Adds support to move the shell by dragging the given control. + * + * @param control the control that can be used to move the shell + */ + private void addMoveSupport(Control control) { + MouseAdapter moveSupport= new class(control) MouseAdapter { + private MouseMoveListener fMoveListener; + Control control_; + this(Control a){ + control_=a; + } + public void mouseDown(MouseEvent e) { + Point shellLoc= fShell.getLocation(); + final int shellX= shellLoc.x; + final int shellY= shellLoc.y; + Point mouseLoc= control_.toDisplay(e.x, e.y); + final int mouseX= mouseLoc.x; + final int mouseY= mouseLoc.y; + fMoveListener= new class() MouseMoveListener { + public void mouseMove(MouseEvent e2) { + Point mouseLoc2= control_.toDisplay(e2.x, e2.y); + int dx= mouseLoc2.x - mouseX; + int dy= mouseLoc2.y - mouseY; + fShell.setLocation(shellX + dx, shellY + dy); + } + }; + control_.addMouseMoveListener(fMoveListener); + } + + public void mouseUp(MouseEvent e) { + control_.removeMouseMoveListener(fMoveListener); + fMoveListener= null; + } + }; + control.addMouseListener(moveSupport); + } + + /** + * Utility to set the foreground and the background color of the given + * control + * + * @param control the control to modify + * @param foreground the color to use for the foreground + * @param background the color to use for the background + */ + private static void setColor(Control control, Color foreground, Color background) { + control.setForeground(foreground); + control.setBackground(background); + } + + /** + * The shell of the popup window. + * + * @return the shell used for the popup window + */ + protected final Shell getShell() { + return fShell; + } + + /** + * The toolbar manager used to manage the toolbar, or null if + * no toolbar is shown. + * + * @return the tool bar manager or null + */ + protected final ToolBarManager getToolBarManager() { + return fToolBarManager; + } + + /** + * Creates the content of this information control. Subclasses must call + * this method at the end of their constructor(s). + */ + protected final void create() { + createContent(fContentComposite); + } + + /** + * Creates the content of the popup window. + *

                + * Implementors will usually take over {@link Composite#getBackground()} and + * {@link Composite#getForeground()} from parent. + *

                + *

                + * Implementors are expected to consider {@link #isResizable()}: If + * true, they should show scrollbars if their content may + * exceed the size of the information control. If false, + * they should never show scrollbars. + *

                + *

                + * The given parent comes with a {@link FillLayout}. + * Subclasses may set a different layout. + *

                + * + * @param parent the container of the content + */ + protected abstract void createContent(Composite parent); + + /** + * Sets the information to be presented by this information control. + *

                + * The default implementation does nothing. Subclasses must either override this method + * or implement {@link IInformationControlExtension2}. + * + * @param information the information to be presented + * + * @see dwtx.jface.text.IInformationControl#setInformation(java.lang.String) + */ + public void setInformation(String information) { + + } + + /** + * Returns whether the information control is resizable. + * + * @return true if the information control is resizable, + * false if it is not resizable. + */ + public bool isResizable() { + return fResizable; + } + + /* + * @see IInformationControl#setVisible(bool) + */ + public void setVisible(bool visible) { + if (fShell.isVisible() is visible) + return; + + fShell.setVisible(visible); + } + + /* + * @see IInformationControl#dispose() + */ + public void dispose() { + if (fShell !is null && !fShell.isDisposed()) + fShell.dispose(); + } + + /* + * @see IInformationControl#setSize(int, int) + */ + public void setSize(int width, int height) { + fShell.setSize(width, height); + } + + /* + * @see IInformationControl#setLocation(Point) + */ + public void setLocation(Point location) { + fShell.setLocation(location); + } + + /* + * @see IInformationControl#setSizeConstraints(int, int) + */ + public void setSizeConstraints(int maxWidth, int maxHeight) { + fSizeConstraints= new Point(maxWidth, maxHeight); + } + + /** + * Returns the size constraints. + * + * @return the size constraints or null if not set + * @see #setSizeConstraints(int, int) + */ + protected final Point getSizeConstraints() { + return fSizeConstraints !is null ? Geometry.copy(fSizeConstraints) : null; + } + + /* + * @see IInformationControl#computeSizeHint() + */ + public Point computeSizeHint() { + // XXX: Verify whether this is a good default implementation. If yes, document it. + Point constrains= getSizeConstraints(); + if (constrains is null) + return fShell.computeSize(DWT.DEFAULT, DWT.DEFAULT, true); + + return fShell.computeSize(constrains.x, constrains.y, true); + } + + /** + * Computes the trim (status text and tool bar are considered as trim). + * Subclasses can extend this method to add additional trim (e.g. scroll + * bars for resizable information controls). + * + * @see dwtx.jface.text.IInformationControlExtension3#computeTrim() + */ + public Rectangle computeTrim() { + Rectangle trim= fShell.computeTrim(0, 0, 0, 0); + + if (fStatusComposite !is null) + trim.height+= fStatusComposite.computeSize(DWT.DEFAULT, DWT.DEFAULT).y; + + return trim; + } + + /* + * @see dwtx.jface.text.IInformationControlExtension3#getBounds() + */ + public Rectangle getBounds() { + return fShell.getBounds(); + } + + /** + * {@inheritDoc} + *

                + * The default implementation always returns false. + *

                + * @see dwtx.jface.text.IInformationControlExtension3#restoresLocation() + */ + public bool restoresLocation() { + return false; + } + + /** + * {@inheritDoc} + *

                + * The default implementation always returns false. + *

                + * @see dwtx.jface.text.IInformationControlExtension3#restoresSize() + */ + public bool restoresSize() { + return false; + } + + /* + * @see IInformationControl#addDisposeListener(DisposeListener) + */ + public void addDisposeListener(DisposeListener listener) { + fShell.addDisposeListener(listener); + } + + /* + * @see IInformationControl#removeDisposeListener(DisposeListener) + */ + public void removeDisposeListener(DisposeListener listener) { + fShell.removeDisposeListener(listener); + } + + /* + * @see IInformationControl#setForegroundColor(Color) + */ + public void setForegroundColor(Color foreground) { + fContentComposite.setForeground(foreground); + } + + /* + * @see IInformationControl#setBackgroundColor(Color) + */ + public void setBackgroundColor(Color background) { + fContentComposite.setBackground(background); + } + + /** + * {@inheritDoc} + * This method is not intended to be overridden by subclasses. + */ + public bool isFocusControl() { + return fShell.getDisplay().getActiveShell() is fShell; + } + + /** + * This default implementation sets the focus on the popup shell. + * Subclasses can override or extend. + * + * @see IInformationControl#setFocus() + */ + public void setFocus() { + bool focusTaken= fShell.setFocus(); + if (!focusTaken) + fShell.forceFocus(); + } + + /** + * {@inheritDoc} + * This method is not intended to be overridden by subclasses. + */ + public void addFocusListener(FocusListener listener) { + if (fFocusListeners.isEmpty()) { + fShellListener= new class() Listener { + + public void handleEvent(Event event) { + Object[] listeners= fFocusListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) { + FocusListener focusListener= cast(FocusListener)listeners[i]; + if (event.type is DWT.Activate) { + focusListener.focusGained(new FocusEvent(event)); + } else { + focusListener.focusLost(new FocusEvent(event)); + } + } + } + }; + fShell.addListener(DWT.Deactivate, fShellListener); + fShell.addListener(DWT.Activate, fShellListener); + } + fFocusListeners.add(cast(Object)listener); + } + + /** + * {@inheritDoc} + * This method is not intended to be overridden by subclasses. + */ + public void removeFocusListener(FocusListener listener) { + fFocusListeners.remove(cast(Object)listener); + if (fFocusListeners.isEmpty()) { + fShell.removeListener(DWT.Activate, fShellListener); + fShell.removeListener(DWT.Deactivate, fShellListener); + fShellListener= null; + } + } + + /** + * Sets the text of the status field. + *

                + * The default implementation currently only updates the status field when + * the popup shell is not visible. The status field can currently only be + * shown if the information control has been created with a non-null status + * field text. + *

                + * + * @param statusFieldText the text to be used in the optional status field + * or null if the status field should be hidden + * + * @see dwtx.jface.text.IInformationControlExtension4#setStatusText(java.lang.String) + */ + public void setStatusText(String statusFieldText) { + if (fStatusLabel !is null && ! getShell().isVisible()) { + if (statusFieldText is null ) { + fStatusComposite.setVisible(false); + } else { + fStatusLabel.setText(statusFieldText); + fStatusComposite.setVisible(true); + } + } + } + + /* + * @see dwtx.jface.text.IInformationControlExtension5#containsControl(dwt.widgets.Control) + */ + public bool containsControl(Control control) { + do { + if (control is fShell) + return true; + if (cast(Shell)control ) + return false; + control= control.getParent(); + } while (control !is null); + return false; + } + + /* + * @see dwtx.jface.text.IInformationControlExtension5#isVisible() + */ + public bool isVisible() { + return fShell !is null && !fShell.isDisposed() && fShell.isVisible(); + } + + /** + * {@inheritDoc} + * This default implementation returns null. Subclasses may override. + */ + public IInformationControlCreator getInformationPresenterControlCreator() { + return null; + } + + /** + * Computes the size constraints based on the + * {@link JFaceResources#getDialogFont() dialog font}. Subclasses can + * override or extend. + * + * @see dwtx.jface.text.IInformationControlExtension5#computeSizeConstraints(int, int) + */ + public Point computeSizeConstraints(int widthInChars, int heightInChars) { + GC gc= new GC(fContentComposite); + gc.setFont(JFaceResources.getDialogFont()); + int width= gc.getFontMetrics().getAverageCharWidth(); + int height= gc.getFontMetrics().getHeight(); + gc.dispose(); + + return new Point(widthInChars * width, heightInChars * height); + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/AbstractInformationControlManager.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/AbstractInformationControlManager.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,1601 @@ +/******************************************************************************* + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Sean Montgomery, sean_montgomery@comcast.net - https://bugs.eclipse.org/bugs/show_bug.cgi?id=45095 + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ + + +module dwtx.jface.text.AbstractInformationControlManager; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +// import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + + + + + +import dwt.DWT; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.graphics.GC; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Monitor; +import dwtx.core.runtime.Assert; +import dwtx.core.runtime.Platform; +import dwtx.jface.dialogs.IDialogSettings; +import dwtx.jface.internal.text.InformationControlReplacer; +import dwtx.jface.internal.text.InternalAccessor; +import dwtx.jface.text.ITextViewerExtension8; +import dwtx.jface.util.Geometry; + + +/** + * Manages the life cycle, visibility, layout, and contents of an + * {@link dwtx.jface.text.IInformationControl}. This manager can be + * installed on and removed from a control, referred to as the subject control, + * i.e. the one from which the subject of the information to be shown is + * retrieved. Also a manager can be enabled or disabled. An installed and + * enabled manager can be forced to show information in its information control + * using showInformation. An information control manager uses an + * IInformationControlCloser to define the behavior when a + * presented information control must be closed. The disposal of the subject and + * the information control are internally handled by the information control + * manager and are not the responsibility of the information control closer. + * + * @see dwtx.jface.text.IInformationControl + * @since 2.0 + */ +abstract public class AbstractInformationControlManager { + + /** + * An internal class that gives access to internal methods. + * + * @since 3.4 + */ + public static class MyInternalAccessor : InternalAccessor { + AbstractInformationControlManager outer_; + this( AbstractInformationControlManager a ){ + outer_=a; + } + public IInformationControl getCurrentInformationControl() { + return outer_.getCurrentInformationControl(); + } + + public void setInformationControlReplacer(InformationControlReplacer replacer) { + outer_.setInformationControlReplacer(replacer); + } + + public InformationControlReplacer getInformationControlReplacer() { + return outer_.getInformationControlReplacer(); + } + + public bool canReplace(IInformationControl control) { + return outer_.canReplace(control); + } + + public bool isReplaceInProgress() { + return outer_.isReplaceInProgress(); + } + + public void replaceInformationControl(bool takeFocus) { + outer_.replaceInformationControl(takeFocus); + } + + public void cropToClosestMonitor(Rectangle bounds) { + outer_.cropToClosestMonitor(bounds); + } + + public void setHoverEnrichMode(EnrichMode mode) { + throw new UnsupportedOperationException("only implemented in AbstractHoverInformationControlManager"); //$NON-NLS-1$ + } + + public bool getAllowMouseExit() { + throw new UnsupportedOperationException("only implemented in AnnotationBarHoverManager"); //$NON-NLS-1$ + } + } + + /** + * Interface of an information control closer. An information control closer + * monitors its information control and its subject control and closes the + * information control if necessary. + *

                + * Clients must implement this interface in order to equip an information + * control manager accordingly. + */ + public interface IInformationControlCloser { + + /** + * Sets the closer's subject control. This is the control that parents + * the information control and from which the subject of the information + * to be shown is retrieved.

                + * Must be called before start. May again be called + * between start and stop. + * + * @param subject the subject control + */ + public void setSubjectControl(Control subject); + + /** + * Sets the closer's information control, the one to close if necessary.

                + * Must be called before start. May again be called + * between start and stop. + * + * @param control the information control + */ + public void setInformationControl(IInformationControl control); + + /** + * Tells this closer to start monitoring the subject and the information + * control. The presented information is considered valid for the given + * area of the subject control's display. + * + * @param subjectArea the area for which the presented information is valid + */ + public void start(Rectangle subjectArea); + + /** + * Tells this closer to stop monitoring the subject and the information control. + */ + public void stop(); + } + + + + /** + * Constitutes entities to enumerate anchors for the layout of the information control. + */ + public static final class Anchor { + private const int fFlag; + private this(int flag) { + fFlag= flag; + } + /** + * Returns the DWT direction flag. One of {@link DWT#BOTTOM}, {@link DWT#TOP}, + * {@link DWT#LEFT}, {@link DWT#RIGHT}, {@link DWT#CENTER}, + * + * @return the DWT direction flag + * @since 3.3 + */ + int getSWTFlag() { + return fFlag; + } + + public override String toString() { + switch (fFlag) { + case DWT.BOTTOM: return "BOTTOM"; //$NON-NLS-1$ + case DWT.TOP: return "TOP"; //$NON-NLS-1$ + case DWT.LEFT: return "LEFT"; //$NON-NLS-1$ + case DWT.RIGHT: return "RIGHT"; //$NON-NLS-1$ + case DWT.CENTER: return "CENTER"; //$NON-NLS-1$ + default: return Integer.toHexString(fFlag); + } + } + } + + /** Internal anchor list. */ + private static Anchor[] ANCHORS_; + private static Anchor[] ANCHORS() { + if( ANCHORS_ is null ) ANCHORS_= [ new Anchor(DWT.TOP), new Anchor(DWT.BOTTOM), new Anchor(DWT.LEFT), new Anchor(DWT.RIGHT) ]; + return ANCHORS_; + } + + + /** Anchor representing the top of the information area */ + public static Anchor ANCHOR_TOP() { return ANCHORS()[0]; } + /** Anchor representing the bottom of the information area */ + public static Anchor ANCHOR_BOTTOM() { return ANCHORS()[1]; } + /** Anchor representing the left side of the information area */ + public static Anchor ANCHOR_LEFT() { return ANCHORS()[2]; } + /** Anchor representing the right side of the information area */ + public static Anchor ANCHOR_RIGHT() { return ANCHORS()[3]; } + /** + * Anchor representing the middle of the subject control + * @since 2.1 + */ + public static Anchor ANCHOR_GLOBAL_; + public static Anchor ANCHOR_GLOBAL(){ + if( ANCHOR_GLOBAL_ is null ) ANCHOR_GLOBAL_ = new Anchor(DWT.CENTER); + return ANCHOR_GLOBAL_; + } + + /** + * Dialog store constant for the location's x-coordinate. + * @since 3.0 + */ + public static const String STORE_LOCATION_X= "location.x"; //$NON-NLS-1$ + /** + * Dialog store constant for the location's y-coordinate. + * @since 3.0 + */ + public static const String STORE_LOCATION_Y= "location.y"; //$NON-NLS-1$ + /** + * Dialog store constant for the size's width. + * @since 3.0 + */ + public static const String STORE_SIZE_WIDTH= "size.width"; //$NON-NLS-1$ + /** + * Dialog store constant for the size's height. + * @since 3.0 + */ + public static const String STORE_SIZE_HEIGHT= "size.height"; //$NON-NLS-1$ + + /** + * Tells whether this class and its subclasses are in debug mode. + *

                + * Subclasses may use this. + *

                + * @since 3.4 + */ + private static bool DEBUG_; + private static bool DEBUG_init = false; + protected static bool DEBUG(){ + if( !DEBUG_init ){ + DEBUG_init = true; + DEBUG_ = "true".equalsIgnoreCase(Platform.getDebugOption("dwtx.jface.text/debug/AbstractInformationControlManager")); //$NON-NLS-1$//$NON-NLS-2$ + } + return DEBUG_; + } + + + /** The subject control of the information control */ + private Control fSubjectControl; + + /** The display area for which the information to be presented is valid */ + private Rectangle fSubjectArea; + + /** The information to be presented */ + private Object fInformation; + + /** Indicates whether the information control takes focus when visible */ + private bool fTakesFocusWhenVisible= false; + + /** + * The information control. + * + *

                This field should not be referenced by subclasses. It is protected for API + * compatibility reasons. + */ + protected IInformationControl fInformationControl; + + /** + * The information control creator. + * + *

                This field should not be referenced by subclasses. It is protected for API + * compatibility reasons. + */ + protected IInformationControlCreator fInformationControlCreator; + + /** + * The information control closer. + * + *

                This field should not be referenced by subclasses. It is protected for API + * compatibility reasons. + */ + protected IInformationControlCloser fInformationControlCloser; + + /** + * Indicates that the information control has been disposed. + * + *

                This field should not be referenced by subclasses. It is protected for API + * compatibility reasons. + */ + protected bool fDisposed= false; + + /** + * The information control replacer to be used when this information control + * needs to be replaced with another information control. + * + * @since 3.4 + */ + private InformationControlReplacer fInformationControlReplacer; + + /** Indicates the enable state of this manager */ + private bool fEnabled= false; + + /** Cached, computed size constraints of the information control in points */ + private Point fSizeConstraints; + + /** The vertical margin when laying out the information control */ + private int fMarginY= 5; + + /** The horizontal margin when laying out the information control */ + private int fMarginX= 5; + + /** The width constraint of the information control in characters */ + private int fWidthConstraint= 60; + + /** The height constraint of the information control in characters */ + private int fHeightConstraint= 6; + + /** Indicates whether the size constraints should be enforced as minimal control size */ + private bool fEnforceAsMinimalSize= false; + + /** Indicates whether the size constraints should be enforced as maximal control size */ + private bool fEnforceAsMaximalSize= false; + + /** The anchor for laying out the information control in relation to the subject control */ + private Anchor fAnchor; + + /** + * The anchor sequence used to layout the information control if the original anchor + * can not be used because the information control would not fit in the display client area. + *

                + * The fallback anchor for a given anchor is the one that comes directly after the given anchor or + * is the first one in the sequence if the given anchor is the last one in the sequence. + *

                + *

                + * Note: This sequence is ignored if the original anchor is not contained in this sequence. + *

                + * + * @see #fAnchor + */ + private Anchor[] fFallbackAnchors; + /** + * The custom information control creator. + * @since 3.0 + */ + private /+volatile+/ IInformationControlCreator fCustomInformationControlCreator; + + /** + * Tells whether a custom information control is in use. + * @since 3.0 + */ + private bool fIsCustomInformationControl= false; + + /** + * The dialog settings for the control's bounds. + * @since 3.0 + */ + private IDialogSettings fDialogSettings; + + /** + * Tells whether the control's location should be read + * from the dialog settings and whether the last + * valid control's size is stored back into the settings. + * + * @since 3.0 + */ + private bool fIsRestoringLocation; + + /** + * Tells whether the control's size should be read + * from the dialog settings and whether the last + * valid control's size is stored back into the settings. + * + * @since 3.0 + */ + private bool fIsRestoringSize; + + /** + * The dispose listener on the subject control. + * + * @since 3.1 + */ + private DisposeListener fSubjectControlDisposeListener; + + + /** + * Creates a new information control manager using the given information control creator. + * By default the following configuration is given: + *
                  + *
                • enabled is false + *
                • horizontal margin is 5 points + *
                • vertical margin is 5 points + *
                • width constraint is 60 characters + *
                • height constraint is 6 characters + *
                • enforce constraints as minimal size is false + *
                • enforce constraints as maximal size is false + *
                • layout anchor is ANCHOR_BOTTOM + *
                • fall back anchors is { ANCHOR_TOP, ANCHOR_BOTTOM, ANCHOR_LEFT, ANCHOR_RIGHT, ANCHOR_GLOBAL } + *
                • takes focus when visible is false + *
                + * + * @param creator the information control creator + */ + protected this(IInformationControlCreator creator) { + fAnchor= ANCHOR_BOTTOM(); + fFallbackAnchors= ANCHORS(); + Assert.isNotNull(cast(Object)creator); + fInformationControlCreator= creator; + } + + /** + * Computes the information to be displayed and the area in which the computed + * information is valid. Implementation of this method must finish their computation + * by setting the computation results using setInformation. + */ + abstract protected void computeInformation(); + + /** + * Sets the parameters of the information to be displayed. These are the information itself and + * the area for which the given information is valid. This so called subject area is a graphical + * region of the information control's subject control. This method calls presentInformation() + * to trigger the presentation of the computed information. + * + * @param information the information, or null if none is available + * @param subjectArea the subject area, or null if none is available + */ + protected final void setInformation(String information, Rectangle subjectArea) { + setInformation(stringcast(information), subjectArea); + } + + /** + * Sets the parameters of the information to be displayed. These are the information itself and + * the area for which the given information is valid. This so called subject area is a graphical + * region of the information control's subject control. This method calls presentInformation() + * to trigger the presentation of the computed information. + * + * @param information the information, or null if none is available + * @param subjectArea the subject area, or null if none is available + * @since 2.1 + */ + protected final void setInformation(Object information, Rectangle subjectArea) { + fInformation= information; + fSubjectArea= subjectArea; + presentInformation(); + } + + /** + * Sets the information control closer for this manager. + * + * @param closer the information control closer for this manager + */ + protected void setCloser(IInformationControlCloser closer) { + fInformationControlCloser= closer; + } + + /** + * Sets the information control replacer for this manager and disposes the + * old one if set. + * + * @param replacer the information control replacer for this manager, or + * null if no information control replacing should + * take place + * @since 3.4 + */ + void setInformationControlReplacer(InformationControlReplacer replacer) { + if (fInformationControlReplacer !is null) + fInformationControlReplacer.dispose(); + fInformationControlReplacer= replacer; + } + + /** + * Returns the current information control replacer or null if none has been installed. + * + * @return the current information control replacer or null if none has been installed + * @since 3.4 + */ + InformationControlReplacer getInformationControlReplacer() { + return fInformationControlReplacer; + } + + /** + * Returns whether an information control replacer has been installed. + * + * @return whether an information control replacer has been installed + * @since 3.4 + */ + bool hasInformationControlReplacer() { + return fInformationControlReplacer !is null; + } + + /** + * Tests whether the given information control is replaceable. + * + * @param iControl information control or null if none + * @return true if information control is replaceable, false otherwise + * @since 3.4 + */ + bool canReplace(IInformationControl iControl) { + return cast(IInformationControlExtension3)iControl + && cast(IInformationControlExtension5)iControl + && (cast(IInformationControlExtension5) iControl).getInformationPresenterControlCreator() !is null; + } + + /** + * Returns the current information control, or null if none. + * + * @return the current information control, or null if none + * @since 3.4 + */ + IInformationControl getCurrentInformationControl() { + return fInformationControl; + } + + /** + * Tells whether this manager's information control is currently being replaced. + * + * @return true if a replace is in progress + * @since 3.4 + */ + bool isReplaceInProgress() { + return fInformationControlReplacer !is null && fInformationControlReplacer.isReplacing(); + } + + /** + * Sets the horizontal and vertical margin to be used when laying out the + * information control relative to the subject control. + * + * @param xMargin the x-margin + * @param yMargin the y-Margin + */ + public void setMargins(int xMargin, int yMargin) { + fMarginX= xMargin; + fMarginY= yMargin; + } + + /** + * Sets the width- and height constraints of the information control. + * + * @param widthInChar the width constraint in number of characters + * @param heightInChar the height constrain in number of characters + * @param enforceAsMinimalSize indicates whether the constraints describe the minimal allowed size of the control + * @param enforceAsMaximalSize indicates whether the constraints describe the maximal allowed size of the control + */ + public void setSizeConstraints(int widthInChar, int heightInChar, bool enforceAsMinimalSize, bool enforceAsMaximalSize) { + fSizeConstraints= null; + fWidthConstraint= widthInChar; + fHeightConstraint= heightInChar; + fEnforceAsMinimalSize= enforceAsMinimalSize; + fEnforceAsMaximalSize= enforceAsMaximalSize; + + } + + /** + * Tells this information control manager to open the information + * control with the values contained in the given dialog settings + * and to store the control's last valid size in the given dialog + * settings. + *

                + * Note: This API is only valid if the information control implements + * {@link IInformationControlExtension3}. Not following this restriction + * will later result in an {@link UnsupportedOperationException}. + *

                + *

                + * The constants used to store the values are: + *

                  + *
                • {@link AbstractInformationControlManager#STORE_LOCATION_X}
                • + *
                • {@link AbstractInformationControlManager#STORE_LOCATION_Y}
                • + *
                • {@link AbstractInformationControlManager#STORE_SIZE_WIDTH}
                • + *
                • {@link AbstractInformationControlManager#STORE_SIZE_HEIGHT}
                • + *
                + *

                + * + * @param dialogSettings + * @param restoreLocation true iff the location is must be (re-)stored + * @param restoreSize trueiff the size is (re-)stored + * @since 3.0 + */ + public void setRestoreInformationControlBounds(IDialogSettings dialogSettings, bool restoreLocation, bool restoreSize) { + Assert.isTrue(dialogSettings !is null && (restoreLocation || restoreSize)); + fDialogSettings= dialogSettings; + fIsRestoringLocation= restoreLocation; + fIsRestoringSize= restoreSize; + } + + /** + * Sets the anchor used for laying out the information control relative to the + * subject control. E.g, using ANCHOR_TOP indicates that the + * information control is position above the area for which the information to + * be displayed is valid. + * + * @param anchor the layout anchor + */ + public void setAnchor(Anchor anchor) { + fAnchor= anchor; + } + + /** + * Sets the anchors fallback sequence used to layout the information control if the original + * anchor can not be used because the information control would not fit in the display client + * area. + *

                + * The fallback anchor for a given anchor is the one that comes directly after the given anchor or + * is the first one in the sequence if the given anchor is the last one in the sequence. + *

                + *

                + * Note: This sequence is ignored if the original anchor is not contained in this list. + *

                + * + * @param fallbackAnchors the array with the anchor fallback sequence + * @see #setAnchor(AbstractInformationControlManager.Anchor) + */ + public void setFallbackAnchors(Anchor[] fallbackAnchors) { + if (fallbackAnchors !is null) { + fFallbackAnchors= new Anchor[fallbackAnchors.length]; + System.arraycopy(fallbackAnchors, 0, fFallbackAnchors, 0, fallbackAnchors.length); + } else + fFallbackAnchors= null; + } + + /** + * Sets the temporary custom control creator, overriding this manager's default information control creator. + * + * @param informationControlCreator the creator, possibly null + * @since 3.0 + */ + protected void setCustomInformationControlCreator(IInformationControlCreator informationControlCreator) { + if (informationControlCreator !is null && cast(IInformationControlCreatorExtension)fCustomInformationControlCreator) { + IInformationControlCreatorExtension extension= cast(IInformationControlCreatorExtension) fCustomInformationControlCreator; + if (extension.canReplace(informationControlCreator)) + return; + } + fCustomInformationControlCreator= informationControlCreator; + } + + /** + * Tells the manager whether it should set the focus to the information control when made visible. + * + * @param takesFocus true if information control should take focus when made visible + */ + public void takesFocusWhenVisible(bool takesFocus) { + fTakesFocusWhenVisible= takesFocus; + } + + /** + * Handles the disposal of the subject control. By default, the information control + * is disposed by calling disposeInformationControl. Subclasses may extend + * this method. + */ + protected void handleSubjectControlDisposed() { + disposeInformationControl(); + } + + /** + * Installs this manager on the given control. The control is now taking the role of + * the subject control. This implementation sets the control also as the information + * control closer's subject control and automatically enables this manager. + * + * @param subjectControl the subject control + */ + public void install(Control subjectControl) { + if (fSubjectControl !is null && !fSubjectControl.isDisposed() && fSubjectControlDisposeListener !is null) + fSubjectControl.removeDisposeListener(fSubjectControlDisposeListener); + + fSubjectControl= subjectControl; + + if (fSubjectControl !is null) + fSubjectControl.addDisposeListener(getSubjectControlDisposeListener()); + + if (fInformationControlCloser !is null) + fInformationControlCloser.setSubjectControl(subjectControl); + + setEnabled(true); + fDisposed= false; + } + + /** + * Returns the dispose listener which gets added + * to the subject control. + * + * @return the dispose listener + * @since 3.1 + */ + private DisposeListener getSubjectControlDisposeListener() { + if (fSubjectControlDisposeListener is null) { + fSubjectControlDisposeListener= new class() DisposeListener { + public void widgetDisposed(DisposeEvent e) { + handleSubjectControlDisposed(); + } + }; + } + return fSubjectControlDisposeListener; + } + + /** + * Returns the subject control of this manager/information control. + * + * @return the subject control + */ + protected Control getSubjectControl() { + return fSubjectControl; + } + + /** + * Returns the actual subject area. + * + * @return the actual subject area + */ + protected Rectangle getSubjectArea() { + return fSubjectArea; + } + + /** + * Sets the enable state of this manager. + * + * @param enabled the enable state + * @deprecated visibility will be changed to protected + */ + public void setEnabled(bool enabled) { + fEnabled= enabled; + } + + /** + * Returns whether this manager is enabled or not. + * + * @return true if this manager is enabled otherwise false + */ + protected bool isEnabled() { + return fEnabled; + } + + /** + * Computes the size constraints of the information control in points based on the + * default font of the given subject control as well as the size constraints in character + * width. + * + * @param subjectControl the subject control + * @param informationControl the information control whose size constraints are computed + * @return the computed size constraints in points + */ + protected Point computeSizeConstraints(Control subjectControl, IInformationControl informationControl) { + + if (fSizeConstraints is null) { + if ( cast(IInformationControlExtension5)informationControl ) { + IInformationControlExtension5 iControl5= cast(IInformationControlExtension5) informationControl; + fSizeConstraints= iControl5.computeSizeConstraints(fWidthConstraint, fHeightConstraint); + if (fSizeConstraints !is null) + return Geometry.copy(fSizeConstraints); + } + if (subjectControl is null) + return null; + + GC gc= new GC(subjectControl); + gc.setFont(subjectControl.getFont()); + int width= gc.getFontMetrics().getAverageCharWidth(); + int height = gc.getFontMetrics().getHeight(); + gc.dispose(); + + fSizeConstraints= new Point (fWidthConstraint * width, fHeightConstraint * height); + } + + return new Point(fSizeConstraints.x, fSizeConstraints.y); + } + + /** + * Computes the size constraints of the information control in points. + * + * @param subjectControl the subject control + * @param subjectArea the subject area + * @param informationControl the information control whose size constraints are computed + * @return the computed size constraints in points + * @since 3.0 + */ + protected Point computeSizeConstraints(Control subjectControl, Rectangle subjectArea, IInformationControl informationControl) { + return computeSizeConstraints(subjectControl, informationControl); + } + + /** + * Handles the disposal of the information control. By default, the information + * control closer is stopped. + */ + protected void handleInformationControlDisposed() { + + storeInformationControlBounds(); + + if ( cast(IInformationControlExtension5)fInformationControl ) + fSizeConstraints= null; + fInformationControl= null; + if (fInformationControlCloser !is null) { + fInformationControlCloser.setInformationControl(null); //XXX: null is against the spec + fInformationControlCloser.stop(); + } + } + + /** + * Returns the information control. If the information control has not been created yet, + * it is automatically created. + * + * @return the information control + */ + protected IInformationControl getInformationControl() { + + if (fDisposed) + return fInformationControl; + + IInformationControlCreator creator= null; + + if (fCustomInformationControlCreator is null) { + creator= fInformationControlCreator; + if (fIsCustomInformationControl && fInformationControl !is null) { + if ( cast(IInformationControlExtension5)fInformationControl ) + fSizeConstraints= null; + fInformationControl.dispose(); + fInformationControl= null; + } + fIsCustomInformationControl= false; + + } else { + + creator= fCustomInformationControlCreator; + if ( cast(IInformationControlCreatorExtension)creator ) { + IInformationControlCreatorExtension extension= cast(IInformationControlCreatorExtension) creator; + if (fInformationControl !is null && extension.canReuse(fInformationControl)) + return fInformationControl; + } + if (fInformationControl !is null) { + if ( cast(IInformationControlExtension5)fInformationControl ) + fSizeConstraints= null; + fInformationControl.dispose(); + fInformationControl= null; + } + fIsCustomInformationControl= true; + } + + if (fInformationControl is null) { + fInformationControl= creator.createInformationControl(fSubjectControl.getShell()); + fInformationControl.addDisposeListener(new class() DisposeListener { + public void widgetDisposed(DisposeEvent e) { + handleInformationControlDisposed(); + } + }); + + if (fInformationControlCloser !is null) + fInformationControlCloser.setInformationControl(fInformationControl); + } + + return fInformationControl; + } + + /** + * Computes the display location of the information control. The location is computed + * considering the given subject area, the anchor at the subject area, and the + * size of the information control. This method does not care about whether the information + * control would be completely visible when placed at the result location. + * + * @param subjectArea the subject area + * @param controlSize the size of the information control + * @param anchor the anchor at the subject area + * @return the display location of the information control + */ + protected Point computeLocation(Rectangle subjectArea, Point controlSize, Anchor anchor) { + int xShift= 0; + int yShift= 0; + + switch (anchor.getSWTFlag()) { + case DWT.CENTER: + Point subjectControlSize= fSubjectControl.getSize(); + Point location= new Point(subjectControlSize.x / 2, subjectControlSize.y / 2); + location.x -= (controlSize.x / 2); + location.y -= (controlSize.y / 2); + return fSubjectControl.toDisplay(location); + case DWT.BOTTOM: + yShift= subjectArea.height + fMarginY; + break; + case DWT.RIGHT: + xShift= fMarginX + subjectArea.width; + break; + case DWT.TOP: + yShift= -controlSize.y - fMarginY; + break; + case DWT.LEFT: + xShift= -controlSize.x - fMarginX; + break; + } + + bool isRTL= fSubjectControl !is null && (fSubjectControl.getStyle() & DWT.RIGHT_TO_LEFT) !is 0; + if (isRTL) + xShift += controlSize.x; + + return fSubjectControl.toDisplay(new Point(subjectArea.x + xShift, subjectArea.y + yShift)); + } + + /** + * Computes the area available for an information control given an anchor and the subject area + * within bounds. + * + * @param subjectArea the subject area + * @param bounds the bounds + * @param anchor the anchor at the subject area + * @return the area available at the given anchor relative to the subject area, confined to the + * monitor's client area + * @since 3.3 + */ + protected Rectangle computeAvailableArea(Rectangle subjectArea, Rectangle bounds, Anchor anchor) { + Rectangle area; + switch (anchor.getSWTFlag()) { + case DWT.CENTER: + area= bounds; + break; + case DWT.BOTTOM: + int y= subjectArea.y + subjectArea.height + fMarginY; + area= new Rectangle(bounds.x, y, bounds.width, bounds.y + bounds.height - y); + break; + case DWT.RIGHT: + int x= subjectArea.x + subjectArea.width + fMarginX; + area= new Rectangle(x, bounds.y, bounds.x + bounds.width - x, bounds.height); + break; + case DWT.TOP: + area= new Rectangle(bounds.x, bounds.y, bounds.width, subjectArea.y - bounds.y - fMarginY); + break; + case DWT.LEFT: + area= new Rectangle(bounds.x, bounds.y, subjectArea.x - bounds.x - fMarginX, bounds.height); + break; + default: + Assert.isLegal(false); + return null; + } + + // Don't return negative areas if the subjectArea overlaps with the monitor bounds. + area.intersect(bounds); + return area; + } + + /** + * Checks whether a control of the given size at the given location would be completely visible + * in the given display area when laid out by using the given anchor. If not, this method tries + * to shift the control orthogonal to the direction given by the anchor to make it visible. If possible + * it updates the location.

                + * This method returns true if the potentially updated position results in a + * completely visible control, or false otherwise. + * + * + * @param location the location of the control + * @param size the size of the control + * @param displayArea the display area in which the control should be visible + * @param anchor anchor for lying out the control + * @return trueif the updated location is useful + */ + protected bool updateLocation(Point location, Point size, Rectangle displayArea, Anchor anchor) { + + int displayLowerRightX= displayArea.x + displayArea.width; + int displayLowerRightY= displayArea.y + displayArea.height; + int lowerRightX= location.x + size.x; + int lowerRightY= location.y + size.y; + + if (ANCHOR_BOTTOM is anchor || ANCHOR_TOP is anchor) { + + if (ANCHOR_BOTTOM is anchor) { + if (lowerRightY > displayLowerRightY) + return false; + } else { + if (location.y < displayArea.y) + return false; + } + + if (lowerRightX > displayLowerRightX) + location.x= location.x - (lowerRightX - displayLowerRightX); + + return (location.x >= displayArea.x && location.y >= displayArea.y); + + } else if (ANCHOR_RIGHT is anchor || ANCHOR_LEFT is anchor) { + + if (ANCHOR_RIGHT is anchor) { + if (lowerRightX > displayLowerRightX) + return false; + } else { + if (location.x < displayArea.x) + return false; + } + + if (lowerRightY > displayLowerRightY) + location.y= location.y - (lowerRightY - displayLowerRightY); + + return (location.x >= displayArea.x && location.y >= displayArea.y); + + } else if (ANCHOR_GLOBAL is anchor) { + + if (lowerRightX > displayLowerRightX) + location.x= location.x - (lowerRightX - displayLowerRightX); + + if (lowerRightY > displayLowerRightY) + location.y= location.y - (lowerRightY - displayLowerRightY); + + return (location.x >= displayArea.x && location.y >= displayArea.y); + } + + return false; + } + + /** + * Returns the next fallback anchor as specified by this manager's + * fallback anchor sequence. + *

                + * The fallback anchor for the given anchor is the one that comes directly after + * the given anchor or is the first one in the sequence if the given anchor is the + * last one in the sequence. + *

                + *

                + * Note: It is the callers responsibility to prevent an endless loop i.e. to test + * whether a given anchor has already been used once. + * then + *

                + * + * @param anchor the current anchor + * @return the next fallback anchor or null if no fallback anchor is available + */ + protected Anchor getNextFallbackAnchor(Anchor anchor) { + + if (anchor is null || fFallbackAnchors is null) + return null; + + for (int i= 0; i < fFallbackAnchors.length; i++) { + if (fFallbackAnchors[i] is anchor) + return fFallbackAnchors[i + 1 is fFallbackAnchors.length ? 0 : i + 1]; + } + + return null; + } + + /** + * Computes the location of the information control depending on the + * subject area and the size of the information control. This method attempts + * to find a location at which the information control lies completely in the display's + * client area while honoring the manager's default anchor. If this isn't possible using the + * default anchor, the fallback anchors are tried out. + * + * @param subjectArea the information area + * @param controlSize the size of the information control + * @return the computed location of the information control + */ + protected Point computeInformationControlLocation(Rectangle subjectArea, Point controlSize) { + Rectangle subjectAreaDisplayRelative= Geometry.toDisplay(fSubjectControl, subjectArea); + + Point upperLeft; + Anchor testAnchor= fAnchor; + Rectangle bestBounds= null; + int bestArea= Integer.MIN_VALUE; + Anchor bestAnchor= null; + do { + + upperLeft= computeLocation(subjectArea, controlSize, testAnchor); + dwt.widgets.Monitor.Monitor monitor= getClosestMonitor(subjectAreaDisplayRelative, testAnchor); + if (updateLocation(upperLeft, controlSize, monitor.getClientArea(), testAnchor)) + return upperLeft; + + // compute available area for this anchor and update if better than best + Rectangle available= computeAvailableArea(subjectAreaDisplayRelative, monitor.getClientArea(), testAnchor); + Rectangle proposed= new Rectangle(upperLeft.x, upperLeft.y, controlSize.x, controlSize.y); + available.intersect(proposed); + int area= available.width * available.height; + if (area > bestArea) { + bestArea= area; + bestBounds= available; + bestAnchor= testAnchor; + } + + testAnchor= getNextFallbackAnchor(testAnchor); + + } while (testAnchor !is fAnchor && testAnchor !is null); + + // no anchor is perfect - select the one with larges area and set the size to not overlap with the subjectArea + if (bestAnchor !is ANCHOR_GLOBAL) + Geometry.set(controlSize, Geometry.getSize(bestBounds)); + return Geometry.getLocation(bestBounds); + } + + /** + * Gets the closest monitor given an anchor and the subject area. + * + * @param area the subject area + * @param anchor the anchor + * @return the monitor closest to the edge of area defined by + * anchor + * @since 3.3 + */ + private dwt.widgets.Monitor.Monitor getClosestMonitor(Rectangle area, Anchor anchor) { + Point center; + if (ANCHOR_GLOBAL is anchor) + center= Geometry.centerPoint(area); + else + center= Geometry.centerPoint(Geometry.getExtrudedEdge(area, 0, anchor.getSWTFlag())); + return getClosestMonitor(fSubjectControl.getDisplay(), Geometry.createRectangle(center, new Point(0, 0))); + } + + /** + * Copied from dwtx.jface.window.Window. Returns the monitor whose client area contains + * the given point. If no monitor contains the point, returns the monitor that is closest to the + * point. If this is ever made public, it should be moved into a separate utility class. + * + * @param display the display to search for monitors + * @param rectangle the rectangle to find the closest monitor for (display coordinates) + * @return the monitor closest to the given point + * @since 3.3 + */ + private dwt.widgets.Monitor.Monitor getClosestMonitor(Display display, Rectangle rectangle) { + int closest = Integer.MAX_VALUE; + + Point toFind= Geometry.centerPoint(rectangle); + dwt.widgets.Monitor.Monitor[] monitors = display.getMonitors(); + dwt.widgets.Monitor.Monitor result = monitors[0]; + + for (int idx = 0; idx < monitors.length; idx++) { + dwt.widgets.Monitor.Monitor current = monitors[idx]; + + Rectangle clientArea = current.getClientArea(); + + if (clientArea.contains(toFind)) { + return current; + } + + int distance = Geometry.distanceSquared(Geometry.centerPoint(clientArea), toFind); + if (distance < closest) { + closest = distance; + result = current; + } + } + + return result; + } + + /** + * Computes information to be displayed as well as the subject area + * and initiates that this information is presented in the information control. + * This happens only if this controller is enabled. + */ + public void showInformation() { + if (fEnabled) + doShowInformation(); + } + + /** + * Computes information to be displayed as well as the subject area + * and initiates that this information is presented in the information control. + */ + protected void doShowInformation() { + fSubjectArea= null; + fInformation= null; + computeInformation(); + } + + /** + * Presents the information in the information control or hides the information + * control if no information should be presented. The information has previously + * been set using setInformation. + */ + protected void presentInformation() { + bool hasContents= false; + if ( stringcast(fInformation) ) + hasContents= (stringcast(fInformation)).trim().length() > 0; + else + hasContents= (fInformation !is null); + + if (fSubjectArea !is null && hasContents) + internalShowInformationControl(fSubjectArea, fInformation); + else + hideInformationControl(); + } + + /** + * Opens the information control with the given information and the specified + * subject area. It also activates the information control closer. + * + * @param subjectArea the information area + * @param information the information + */ + private void internalShowInformationControl(Rectangle subjectArea, Object information) { + if ( cast(InformationControlReplacer)this ) { + (cast(InformationControlReplacer) this).showInformationControl(subjectArea, information); + return; + } + + IInformationControl informationControl= getInformationControl(); + if (informationControl !is null) { + + Point sizeConstraints= computeSizeConstraints(fSubjectControl, fSubjectArea, informationControl); + if ( cast(IInformationControlExtension3)informationControl ) { + IInformationControlExtension3 iControl3= cast(IInformationControlExtension3) informationControl; + Rectangle trim= iControl3.computeTrim(); + sizeConstraints.x += trim.width; + sizeConstraints.y += trim.height; + } + informationControl.setSizeConstraints(sizeConstraints.x, sizeConstraints.y); + + if ( cast(IInformationControlExtension2)informationControl ) + (cast(IInformationControlExtension2)informationControl).setInput(information); + else + informationControl.setInformation(information.toString()); + + if ( cast(IInformationControlExtension)informationControl ) { + IInformationControlExtension extension= cast(IInformationControlExtension)informationControl; + if (!extension.hasContents()) + return; + } + + Point size= null; + Point location= null; + Rectangle bounds= restoreInformationControlBounds(); + + if (bounds !is null) { + if (bounds.x > -1 && bounds.y > -1) + location= Geometry.getLocation(bounds); + + if (bounds.width > -1 && bounds.height > -1) + size= Geometry.getSize(bounds); + } + + if (size is null) + size= informationControl.computeSizeHint(); + + if (fEnforceAsMinimalSize) + size= Geometry.max(size, sizeConstraints); + if (fEnforceAsMaximalSize) + size= Geometry.min(size, sizeConstraints); + + if (location is null) + location= computeInformationControlLocation(subjectArea, size); + + Rectangle controlBounds= Geometry.createRectangle(location, size); + cropToClosestMonitor(controlBounds); + location= Geometry.getLocation(controlBounds); + size= Geometry.getSize(controlBounds); + informationControl.setLocation(location); + informationControl.setSize(size.x, size.y); + + showInformationControl(subjectArea); + } + } + + /** + * Crops the given bounds such that they lie completely on the closest monitor. + * + * @param bounds shell bounds to crop + * @since 3.4 + */ + void cropToClosestMonitor(Rectangle bounds) { + Rectangle monitorBounds= getClosestMonitor(fSubjectControl.getDisplay(), bounds).getClientArea(); + bounds.intersect(monitorBounds); + } + + /** + * Hides the information control and stops the information control closer. + */ + protected void hideInformationControl() { + if (fInformationControl !is null) { + storeInformationControlBounds(); + fInformationControl.setVisible(false); + if (fInformationControlCloser !is null) + fInformationControlCloser.stop(); + } + } + + /** + * Shows the information control and starts the information control closer. + * This method may not be called by clients. + * + * @param subjectArea the information area + */ + protected void showInformationControl(Rectangle subjectArea) { + fInformationControl.setVisible(true); + + if (fTakesFocusWhenVisible) + fInformationControl.setFocus(); + + if (fInformationControlCloser !is null) + fInformationControlCloser.start(subjectArea); + } + + /** + * Replaces this manager's information control as defined by + * the information control replacer. + * Must only be called when {@link #fInformationControl} instanceof {@link IInformationControlExtension3}! + * + * @param takeFocus true iff the replacing information control should take focus + * + * @since 3.4 + */ + void replaceInformationControl(bool takeFocus) { + if (fInformationControlReplacer !is null && canReplace(fInformationControl)) { + IInformationControlExtension3 iControl3= cast(IInformationControlExtension3) fInformationControl; + Rectangle b= iControl3.getBounds(); + Rectangle t= iControl3.computeTrim(); + Rectangle contentBounds= new Rectangle(b.x - t.x, b.y - t.y, b.width - t.width, b.height - t.height); + IInformationControlCreator informationPresenterControlCreator= (cast(IInformationControlExtension5) fInformationControl).getInformationPresenterControlCreator(); + fInformationControlReplacer.replaceInformationControl(informationPresenterControlCreator, contentBounds, fInformation, fSubjectArea, takeFocus); + } + hideInformationControl(); + } + + /** + * Disposes this manager's information control. + */ + public void disposeInformationControl() { + if (fInformationControl !is null) { + fInformationControl.dispose(); + handleInformationControlDisposed(); + } + } + + /** + * Disposes this manager and if necessary all dependent parts such as + * the information control. For symmetry it first disables this manager. + */ + public void dispose() { + if (!fDisposed) { + + fDisposed= true; + + setEnabled(false); + disposeInformationControl(); + + if (fInformationControlReplacer !is null) { + fInformationControlReplacer.dispose(); + fInformationControlReplacer= null; + } + + if (fSubjectControl !is null && !fSubjectControl.isDisposed() && fSubjectControlDisposeListener !is null) + fSubjectControl.removeDisposeListener(fSubjectControlDisposeListener); + fSubjectControl= null; + fSubjectControlDisposeListener= null; + + fIsCustomInformationControl= false; + fCustomInformationControlCreator= null; + fInformationControlCreator= null; + fInformationControlCloser= null; + } + } + + // ------ control's size handling dialog settings ------ + + /** + * Stores the information control's bounds. + * + * @since 3.0 + */ + protected void storeInformationControlBounds() { + if (fDialogSettings is null || fInformationControl is null || !(fIsRestoringLocation || fIsRestoringSize)) + return; + + if (!( cast(IInformationControlExtension3)fInformationControl )) + throw new UnsupportedOperationException(); + + bool controlRestoresSize= (cast(IInformationControlExtension3)fInformationControl).restoresSize(); + bool controlRestoresLocation= (cast(IInformationControlExtension3)fInformationControl).restoresLocation(); + + Rectangle bounds= (cast(IInformationControlExtension3)fInformationControl).getBounds(); + if (bounds is null) + return; + + if (fIsRestoringSize && controlRestoresSize) { + fDialogSettings.put(STORE_SIZE_WIDTH, bounds.width); + fDialogSettings.put(STORE_SIZE_HEIGHT, bounds.height); + } + if (fIsRestoringLocation && controlRestoresLocation) { + fDialogSettings.put(STORE_LOCATION_X, bounds.x); + fDialogSettings.put(STORE_LOCATION_Y, bounds.y); + } + } + /** + * Restores the information control's bounds. + * + * @return the stored bounds + * @since 3.0 + */ + protected Rectangle restoreInformationControlBounds() { + if (fDialogSettings is null || !(fIsRestoringLocation || fIsRestoringSize)) + return null; + + if (!( cast(IInformationControlExtension3)fInformationControl )) + throw new UnsupportedOperationException(); + + bool controlRestoresSize= (cast(IInformationControlExtension3)fInformationControl).restoresSize(); + bool controlRestoresLocation= (cast(IInformationControlExtension3)fInformationControl).restoresLocation(); + + Rectangle bounds= new Rectangle(-1, -1, -1, -1); + + if (fIsRestoringSize && controlRestoresSize) { + try { + bounds.width= fDialogSettings.getInt(STORE_SIZE_WIDTH); + bounds.height= fDialogSettings.getInt(STORE_SIZE_HEIGHT); + } catch (NumberFormatException ex) { + bounds.width= -1; + bounds.height= -1; + } + } + + if (fIsRestoringLocation && controlRestoresLocation) { + try { + bounds.x= fDialogSettings.getInt(STORE_LOCATION_X); + bounds.y= fDialogSettings.getInt(STORE_LOCATION_Y); + } catch (NumberFormatException ex) { + bounds.x= -1; + bounds.y= -1; + } + } + + // sanity check + if (bounds.x is -1 && bounds.y is -1 && bounds.width is -1 && bounds.height is -1) + return null; + + Rectangle maxBounds= null; + if (fSubjectControl !is null && !fSubjectControl.isDisposed()) + maxBounds= fSubjectControl.getDisplay().getBounds(); + else { + // fallback + Display display= Display.getCurrent(); + if (display is null) + display= Display.getDefault(); + if (display !is null && !display.isDisposed()) + maxBounds= display.getBounds(); + } + + + if (bounds.width > -1 && bounds.height > -1) { + if (maxBounds !is null) { + bounds.width= Math.min(bounds.width, maxBounds.width); + bounds.height= Math.min(bounds.height, maxBounds.height); + } + + // Enforce an absolute minimal size + bounds.width= Math.max(bounds.width, 30); + bounds.height= Math.max(bounds.height, 30); + } + + if (bounds.x > -1 && bounds.y > -1 && maxBounds !is null) { + bounds.x= Math.max(bounds.x, maxBounds.x); + bounds.y= Math.max(bounds.y, maxBounds.y); + + if (bounds .width > -1 && bounds.height > -1) { + bounds.x= Math.min(bounds.x, maxBounds.width - bounds.width); + bounds.y= Math.min(bounds.y, maxBounds.height - bounds.height); + } + } + + return bounds; + } + + /** + * Returns an adapter that gives access to internal methods. + *

                + * Note: This method is not intended to be referenced or overridden by clients.

                + * + * @return the replaceable information control accessor + * @since 3.4 + * @noreference This method is not intended to be referenced by clients. + * @nooverride This method is not intended to be re-implemented or extended by clients. + */ + public InternalAccessor getInternalAccessor() { + return new MyInternalAccessor(this); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/AbstractLineTracker.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/AbstractLineTracker.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,471 @@ +/******************************************************************************* + * 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 + * 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.text.AbstractLineTracker; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; +import tango.text.convert.Format; + +import dwtx.dwtxhelper.Collection; + + + /** + * Combines the information of the occurrence of a line delimiter. delimiterIndex + * is the index where a line delimiter starts, whereas delimiterLength, + * indicates the length of the delimiter. + */ + protected class DelimiterInfo { + public int delimiterIndex; + public int delimiterLength; + public String delimiter; + } + alias DelimiterInfo AbstractLineTracker_DelimiterInfo; + +/** + * Abstract implementation of ILineTracker. It lets the definition of line + * delimiters to subclasses. Assuming that '\n' is the only line delimiter, this abstract + * implementation defines the following line scheme: + *
                  + *
                • "" -> [0,0] + *
                • "a" -> [0,1] + *
                • "\n" -> [0,1], [1,0] + *
                • "a\n" -> [0,2], [2,0] + *
                • "a\nb" -> [0,2], [2,1] + *
                • "a\nbc\n" -> [0,2], [2,3], [5,0] + *
                + *

                + * This class must be subclassed. + *

                + */ +public abstract class AbstractLineTracker : ILineTracker, ILineTrackerExtension { + + /** + * Tells whether this class is in debug mode. + * + * @since 3.1 + */ + private static const bool DEBUG= false; + + /** + * Representation of replace and set requests. + * + * @since 3.1 + */ + protected static class Request { + public const int offset; + public const int length; + public const String text; + + public this(int offset, int length, String text) { + this.offset= offset; + this.length= length; + this.text= text; + } + + public this(String text) { + this.offset= -1; + this.length= -1; + this.text= text; + } + + public bool isReplaceRequest() { + return this.offset > -1 && this.length > -1; + } + } + + /** + * The active rewrite session. + * + * @since 3.1 + */ + private DocumentRewriteSession fActiveRewriteSession; + /** + * The list of pending requests. + * + * @since 3.1 + */ + private List fPendingRequests; + /** + * The implementation that this tracker delegates to. + * + * @since 3.2 + */ + private ILineTracker fDelegate; + private void fDelegate_init() { + fDelegate = new class() ListLineTracker { + public String[] getLegalLineDelimiters() { + return this.outer.getLegalLineDelimiters(); + } + + protected DelimiterInfo nextDelimiterInfo(String text, int offset) { + return this.outer.nextDelimiterInfo(text, offset); + } + }; + } + /** + * Whether the delegate needs conversion when the line structure is modified. + */ + private bool fNeedsConversion= true; + + /** + * Creates a new line tracker. + */ + protected this() { + fDelegate_init(); + } + + /* + * @see dwtx.jface.text.ILineTracker#computeNumberOfLines(java.lang.String) + */ + public int computeNumberOfLines(String text) { + return fDelegate.computeNumberOfLines(text); + } + + /* + * @see dwtx.jface.text.ILineTracker#getLineDelimiter(int) + */ + public String getLineDelimiter(int line) { + checkRewriteSession(); + return fDelegate.getLineDelimiter(line); + } + + /* + * @see dwtx.jface.text.ILineTracker#getLineInformation(int) + */ + public IRegion getLineInformation(int line) { + checkRewriteSession(); + return fDelegate.getLineInformation(line); + } + + /* + * @see dwtx.jface.text.ILineTracker#getLineInformationOfOffset(int) + */ + public IRegion getLineInformationOfOffset(int offset) { + checkRewriteSession(); + return fDelegate.getLineInformationOfOffset(offset); + } + + /* + * @see dwtx.jface.text.ILineTracker#getLineLength(int) + */ + public int getLineLength(int line) { + checkRewriteSession(); + return fDelegate.getLineLength(line); + } + + /* + * @see dwtx.jface.text.ILineTracker#getLineNumberOfOffset(int) + */ + public int getLineNumberOfOffset(int offset) { + checkRewriteSession(); + return fDelegate.getLineNumberOfOffset(offset); + } + + /* + * @see dwtx.jface.text.ILineTracker#getLineOffset(int) + */ + public int getLineOffset(int line) { + checkRewriteSession(); + return fDelegate.getLineOffset(line); + } + + /* + * @see dwtx.jface.text.ILineTracker#getNumberOfLines() + */ + public int getNumberOfLines() { + try { + checkRewriteSession(); + } catch (BadLocationException x) { + // TODO there is currently no way to communicate that exception back to the document + } + return fDelegate.getNumberOfLines(); + } + + /* + * @see dwtx.jface.text.ILineTracker#getNumberOfLines(int, int) + */ + public int getNumberOfLines(int offset, int length) { + checkRewriteSession(); + return fDelegate.getNumberOfLines(offset, length); + } + + /* + * @see dwtx.jface.text.ILineTracker#set(java.lang.String) + */ + public void set(String text) { + if (hasActiveRewriteSession()) { + fPendingRequests.clear(); + fPendingRequests.add(new Request(text)); + return; + } + + fDelegate.set(text); + } + + /* + * @see dwtx.jface.text.ILineTracker#replace(int, int, java.lang.String) + */ + public void replace(int offset, int length, String text) { + if (hasActiveRewriteSession()) { + fPendingRequests.add(new Request(offset, length, text)); + return; + } + + checkImplementation(); + + fDelegate.replace(offset, length, text); + } + + /** + * Converts the implementation to be a {@link TreeLineTracker} if it isn't yet. + * + * @since 3.2 + */ + private void checkImplementation() { + if (fNeedsConversion) { + fNeedsConversion= false; + fDelegate= new class(cast(ListLineTracker) fDelegate) TreeLineTracker { + this(ListLineTracker arg){ + super(arg); + } + protected DelimiterInfo nextDelimiterInfo(String text, int offset) { + return this.outer.nextDelimiterInfo(text, offset); + } + + public String[] getLegalLineDelimiters() { + return this.outer.getLegalLineDelimiters(); + } + }; + } + } + + /** + * Returns the information about the first delimiter found in the given text starting at the + * given offset. + * + * @param text the text to be searched + * @param offset the offset in the given text + * @return the information of the first found delimiter or null + */ + protected abstract DelimiterInfo nextDelimiterInfo(String text, int offset); + + /* + * @see dwtx.jface.text.ILineTrackerExtension#startRewriteSession(dwtx.jface.text.DocumentRewriteSession) + * @since 3.1 + */ + public final void startRewriteSession(DocumentRewriteSession session) { + if (fActiveRewriteSession !is null) + throw new IllegalStateException(); + fActiveRewriteSession= session; + fPendingRequests= new ArrayList(20); + } + + /* + * @see dwtx.jface.text.ILineTrackerExtension#stopRewriteSession(dwtx.jface.text.DocumentRewriteSession, java.lang.String) + * @since 3.1 + */ + public final void stopRewriteSession(DocumentRewriteSession session, String text) { + if (fActiveRewriteSession is session) { + fActiveRewriteSession= null; + fPendingRequests= null; + set(text); + } + } + + /** + * Tells whether there's an active rewrite session. + * + * @return true if there is an active rewrite session, false + * otherwise + * @since 3.1 + */ + protected final bool hasActiveRewriteSession() { + return fActiveRewriteSession !is null; + } + + /** + * Flushes the active rewrite session. + * + * @throws BadLocationException in case the recorded requests cannot be processed correctly + * @since 3.1 + */ + protected final void flushRewriteSession() { + if (DEBUG) + System.out_.println(Format("AbstractLineTracker: Flushing rewrite session: {}", fActiveRewriteSession)); //$NON-NLS-1$ + + Iterator e= fPendingRequests.iterator(); + + fPendingRequests= null; + fActiveRewriteSession= null; + + while (e.hasNext()) { + Request request= cast(Request) e.next(); + if (request.isReplaceRequest()) + replace(request.offset, request.length, request.text); + else + set(request.text); + } + } + + /** + * Checks the presence of a rewrite session and flushes it. + * + * @throws BadLocationException in case flushing does not succeed + * @since 3.1 + */ + protected final void checkRewriteSession() { + if (hasActiveRewriteSession()) + flushRewriteSession(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/AbstractReusableInformationControlCreator.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/AbstractReusableInformationControlCreator.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,227 @@ +/******************************************************************************* + * 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.text.AbstractReusableInformationControlCreator; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.widgets.Composite; +import dwt.widgets.Shell; + + +/** + * Abstract class for a reusable information control creators. + * + * @since 3.3 + */ +public abstract class AbstractReusableInformationControlCreator : IInformationControlCreator, IInformationControlCreatorExtension, DisposeListener { + + private Map fInformationControls; + + /** + * Creates the control. + * + * @param parent the parent shell + * @return the created information control + */ + protected abstract IInformationControl doCreateInformationControl(Shell parent); + + this(){ + fInformationControls= new HashMap(); + } + + /* + * @see dwtx.jface.text.IInformationControlCreator#createInformationControl(dwt.widgets.Shell) + */ + public IInformationControl createInformationControl(Shell parent) { + IInformationControl control= cast(IInformationControl)fInformationControls.get(parent); + if (control is null) { + control= doCreateInformationControl(parent); + control.addDisposeListener(this); + fInformationControls.put(parent, cast(Object)control); + } + return control; + } + + /* + * @see dwt.events.DisposeListener#widgetDisposed(dwt.events.DisposeEvent) + */ + public void widgetDisposed(DisposeEvent e) { + Composite parent= null; + if (cast(Shell)e.widget ) + parent= (cast(Shell)e.widget).getParent(); + if ( cast(Shell)parent ) + fInformationControls.remove(parent); + } + + + /* + * @see dwtx.jface.text.IInformationControlCreatorExtension#canReuse(dwtx.jface.text.IInformationControl) + */ + public bool canReuse(IInformationControl control) { + return fInformationControls.containsValue(cast(Object)control); + } + + /* + * @see dwtx.jface.text.IInformationControlCreatorExtension#canReplace(dwtx.jface.text.IInformationControlCreator) + */ + public bool canReplace(IInformationControlCreator creator) { + return creator.classinfo is this.classinfo; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/Assert.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/Assert.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,341 @@ +/******************************************************************************* + * 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 + * 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.text.Assert; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Assert is useful for for embedding runtime sanity checks + * in code. The static predicate methods all test a condition and throw some + * type of unchecked exception if the condition does not hold. + *

                + * Assertion failure exceptions, like most runtime exceptions, are + * thrown when something is misbehaving. Assertion failures are invariably + * unspecified behavior; consequently, clients should never rely on + * these being thrown (or not thrown). If you find yourself in the + * position where you need to catch an assertion failure, you have most + * certainly written your program incorrectly. + *

                + *

                + * Note that an assert statement is slated to be added to the + * Java language in JDK 1.4, rending this class obsolete. + *

                + * + * @deprecated As of 3.3, replaced by {@link dwtx.core.runtime.Assert} + * @noinstantiate This class is not intended to be instantiated by clients. + */ +public final class Assert { + + /** + * AssertionFailedException is a runtime exception thrown + * by some of the methods in Assert. + *

                + * This class is not declared public to prevent some misuses; programs that catch + * or otherwise depend on assertion failures are susceptible to unexpected + * breakage when assertions in the code are added or removed. + *

                + *

                + * This class is not intended to be serialized. + *

                + */ + private static class AssertionFailedException : RuntimeException { + + /** + * Serial version UID for this class. + *

                + * Note: This class is not intended to be serialized. + *

                + * @since 3.1 + */ + private static const long serialVersionUID= 3689918374733886002L; + + /** + * Constructs a new exception. + */ + public this() { + } + + /** + * Constructs a new exception with the given message. + * + * @param detail the detailed message + */ + public this(String detail) { + super(detail); + } + } + + /* This class is not intended to be instantiated. */ + private this() { + } + + /** + * Asserts that an argument is legal. If the given bool is + * not true, an IllegalArgumentException + * is thrown. + * + * @param expression the outcome of the check + * @return true if the check passes (does not return + * if the check fails) + * @exception IllegalArgumentException if the legality test failed + */ + public static bool isLegal(bool expression) { + // succeed as quickly as possible + if (expression) { + return true; + } + return isLegal(expression, "");//$NON-NLS-1$ + } + + /** + * Asserts that an argument is legal. If the given bool is + * not true, an IllegalArgumentException + * is thrown. + * The given message is included in that exception, to aid debugging. + * + * @param expression the outcome of the check + * @param message the message to include in the exception + * @return true if the check passes (does not return + * if the check fails) + * @exception IllegalArgumentException if the legality test failed + */ + public static bool isLegal(bool expression, String message) { + if (!expression) + throw new IllegalArgumentException("assertion failed; " ~ message); //$NON-NLS-1$ + return expression; + } + + /** + * Asserts that the given object is not null. If this + * is not the case, some kind of unchecked exception is thrown. + *

                + * As a general rule, parameters passed to API methods must not be + * null unless explicitly allowed in the method's + * specification. Similarly, results returned from API methods are never + * null unless explicitly allowed in the method's + * specification. Implementations are encouraged to make regular use of + * Assert.isNotNull to ensure that null + * parameters are detected as early as possible. + *

                + * + * @param object the value to test + * @exception RuntimeException an unspecified unchecked exception if the object + * is null + */ + public static void isNotNull(Object object) { + // succeed as quickly as possible + if (object !is null) { + return; + } + isNotNull(object, "");//$NON-NLS-1$ + } + + /** + * Asserts that the given object is not null. If this + * is not the case, some kind of unchecked exception is thrown. + * The given message is included in that exception, to aid debugging. + *

                + * As a general rule, parameters passed to API methods must not be + * null unless explicitly allowed in the method's + * specification. Similarly, results returned from API methods are never + * null unless explicitly allowed in the method's + * specification. Implementations are encouraged to make regular use of + * Assert.isNotNull to ensure that null + * parameters are detected as early as possible. + *

                + * + * @param object the value to test + * @param message the message to include in the exception + * @exception RuntimeException an unspecified unchecked exception if the object + * is null + */ + public static void isNotNull(Object object, String message) { + if (object is null) + throw new AssertionFailedException("null argument;" ~ message);//$NON-NLS-1$ + } + + /** + * Asserts that the given bool is true. If this + * is not the case, some kind of unchecked exception is thrown. + * + * @param expression the outcome of the check + * @return true if the check passes (does not return + * if the check fails) + */ + public static bool isTrue(bool expression) { + // succeed as quickly as possible + if (expression) { + return true; + } + return isTrue(expression, "");//$NON-NLS-1$ + } + + /** + * Asserts that the given bool is true. If this + * is not the case, some kind of unchecked exception is thrown. + * The given message is included in that exception, to aid debugging. + * + * @param expression the outcome of the check + * @param message the message to include in the exception + * @return true if the check passes (does not return + * if the check fails) + */ + public static bool isTrue(bool expression, String message) { + if (!expression) + throw new AssertionFailedException("Assertion failed: "~message);//$NON-NLS-1$ + return expression; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/BadLocationException.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/BadLocationException.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,194 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.BadLocationException; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + + +/** + * Indicates the attempt to access a non-existing position. The attempt has been + * performed on a text store such as a document or string. + *

                + * This class is not intended to be serialized. + *

                + */ +public class BadLocationException : Exception { + + /** + * Serial version UID for this class. + *

                + * Note: This class is not intended to be serialized. + *

                + * @since 3.1 + */ + private static const long serialVersionUID= 3257281452776370224L; + + /** + * Creates a new bad location exception. + */ + public this() { + super(null); + } + + /** + * Creates a new bad location exception. + * + * @param message the exception message + */ + public this(String message) { + super(message); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/BadPartitioningException.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/BadPartitioningException.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,195 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.BadPartitioningException; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Represents the attempt to refer to a non-existing document partitioning. + *

                + * This class is not intended to be serialized. + *

                + * + * @see dwtx.jface.text.IDocument + * @see dwtx.jface.text.IDocumentExtension3 + * @since 3.0 + */ +public class BadPartitioningException : Exception { + + /** + * Serial version UID for this class. + *

                + * Note: This class is not intended to be serialized. + *

                + * @since 3.1 + */ + private static const long serialVersionUID= 3256439205327876408L; + + /** + * Creates a new bad partitioning exception. + */ + public this() { + super(""); + } + + /** + * Creates a new bad partitioning exception. + * + * @param message message describing the exception + */ + public this(String message) { + super(message); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/BadPositionCategoryException.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/BadPositionCategoryException.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,196 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.BadPositionCategoryException; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + + +/** + * Indicates the attempt to access a non-existing position + * category in a document. + *

                + * This class is not intended to be serialized. + *

                + * + * @see dwtx.jface.text.IDocument + */ +public class BadPositionCategoryException : Exception { + + /** + * Serial version UID for this class. + *

                + * Note: This class is not intended to be serialized. + *

                + * @since 3.1 + */ + private static const long serialVersionUID= 3761405300745713206L; + + /** + * Creates a new bad position category exception. + */ + public this() { + super( null ); + } + + /** + * Creates a new bad position category exception. + * + * @param message the exception's message + */ + public this(String message) { + super(message); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ConfigurableLineTracker.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ConfigurableLineTracker.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,223 @@ +/******************************************************************************* + * 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 + * 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.text.ConfigurableLineTracker; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.core.runtime.Assert; + + +/** + * Standard implementation of a generic + * {@link dwtx.jface.text.ILineTracker}. + *

                + * The line tracker can be configured with the set of legal line delimiters. + * Line delimiters are unconstrained. The line delimiters are used to compute + * the tracker's line structure. In the case of overlapping line delimiters, the + * longest line delimiter is given precedence of the shorter ones. + *

                + * This class is not intended to be subclassed. + *

                + * @noextend This class is not intended to be subclassed by clients. + */ +public class ConfigurableLineTracker : AbstractLineTracker { + + + /** The strings which are considered being the line delimiter */ + private String[] fDelimiters; + /** A predefined delimiter information which is always reused as return value */ + private AbstractLineTracker_DelimiterInfo fDelimiterInfo; + + + /** + * Creates a standard line tracker for the given line delimiters. + * + * @param legalLineDelimiters the tracker's legal line delimiters, + * may not be null and must be longer than 0 + */ + public this(String[] legalLineDelimiters) { + Assert.isTrue(legalLineDelimiters.length > 0); + fDelimiterInfo= new AbstractLineTracker_DelimiterInfo(); + fDelimiters= TextUtilities.copy(legalLineDelimiters); + } + + /* + * @see dwtx.jface.text.ILineTracker#getLegalLineDelimiters() + */ + public String[] getLegalLineDelimiters() { + return TextUtilities.copy(fDelimiters); + } + + /* + * @see dwtx.jface.text.AbstractLineTracker#nextDelimiterInfo(java.lang.String, int) + */ + protected AbstractLineTracker_DelimiterInfo nextDelimiterInfo(String text, int offset) { + if (fDelimiters.length > 1) { + int[] info= TextUtilities.indexOf(fDelimiters, text, offset); + if (info[0] is -1) + return null; + fDelimiterInfo.delimiterIndex= info[0]; + fDelimiterInfo.delimiter= fDelimiters[info[1]]; + } else { + int index= text.indexOf(fDelimiters[0], offset); + if (index is -1) + return null; + fDelimiterInfo.delimiterIndex= index; + fDelimiterInfo.delimiter= fDelimiters[0]; + } + + fDelimiterInfo.delimiterLength= fDelimiterInfo.delimiter.length(); + return fDelimiterInfo; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/CopyOnWriteTextStore.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/CopyOnWriteTextStore.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,302 @@ +/******************************************************************************* + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Anton Leherbauer (anton.leherbauer@windriver.com) - initial API and implementation + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.text.CopyOnWriteTextStore; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.core.runtime.Assert; + + +/** + * Copy-on-write ITextStore wrapper. + *

                + * This implementation uses an unmodifiable text store for the initial content. + * Upon first modification attempt, the unmodifiable store is replaced with + * a modifiable instance which must be supplied in the constructor.

                + *

                + * This class is not intended to be subclassed. + *

                + * + * @since 3.2 + * @noextend This class is not intended to be subclassed by clients. + */ +public class CopyOnWriteTextStore : ITextStore { + + /** + * An unmodifiable String based text store. It is not possible to modify the content + * other than using {@link #set}. Trying to {@link #replace} a text range will + * throw an UnsupportedOperationException. + */ + private static class StringTextStore : ITextStore { + + /** Represents the content of this text store. */ + private String fText= ""; //$NON-NLS-1$ + + /** + * Create an empty text store. + */ + private this() { +// super(); + } + + /** + * Create a text store with initial content. + * @param text the initial content + */ + private this(String text) { +// super(); + set(text); + } + + /* + * @see dwtx.jface.text.ITextStore#get(int) + */ + public char get(int offset) { + return fText.charAt(offset); + } + + /* + * @see dwtx.jface.text.ITextStore#get(int, int) + */ + public String get(int offset, int length) { + return fText.substring(offset, offset + length); + } + + /* + * @see dwtx.jface.text.ITextStore#getLength() + */ + public int getLength() { + return fText.length(); + } + + /* + * @see dwtx.jface.text.ITextStore#replace(int, int, java.lang.String) + */ + public void replace(int offset, int length, String text) { + // modification not supported + throw new UnsupportedOperationException(); + } + + /* + * @see dwtx.jface.text.ITextStore#set(java.lang.String) + */ + public void set(String text) { + fText= text !is null ? text : ""; //$NON-NLS-1$ + } + + } + + /** The underlying "real" text store */ + protected ITextStore fTextStore; + + /** A modifiable ITextStore instance */ + private const ITextStore fModifiableTextStore; + + /** + * Creates an empty text store. The given text store will be used upon first + * modification attempt. + * + * @param modifiableTextStore + * a modifiable ITextStore instance, may not be + * null + */ + public this(ITextStore modifiableTextStore) { + Assert.isNotNull(cast(Object)modifiableTextStore); + fTextStore= new StringTextStore(); + fTextStore= new StringTextStore(); + fModifiableTextStore= modifiableTextStore; + } + + /* + * @see dwtx.jface.text.ITextStore#get(int) + */ + public char get(int offset) { + return fTextStore.get(offset); + } + + /* + * @see dwtx.jface.text.ITextStore#get(int, int) + */ + public String get(int offset, int length) { + return fTextStore.get(offset, length); + } + + /* + * @see dwtx.jface.text.ITextStore#getLength() + */ + public int getLength() { + return fTextStore.getLength(); + } + + /* + * @see dwtx.jface.text.ITextStore#replace(int, int, java.lang.String) + */ + public void replace(int offset, int length, String text) { + if (fTextStore !is fModifiableTextStore) { + String content= fTextStore.get(0, fTextStore.getLength()); + fTextStore= fModifiableTextStore; + fTextStore.set(content); + } + fTextStore.replace(offset, length, text); + } + + /* + * @see dwtx.jface.text.ITextStore#set(java.lang.String) + */ + public void set(String text) { + fTextStore= new StringTextStore(text); + fModifiableTextStore.set(""); //$NON-NLS-1$ + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/CursorLinePainter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/CursorLinePainter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,406 @@ +/******************************************************************************* + * 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 + * 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.text.CursorLinePainter; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + + + + +import dwt.custom.LineBackgroundEvent; +import dwt.custom.LineBackgroundListener; +import dwt.custom.StyledText; +import dwt.graphics.Color; +import dwt.graphics.Point; + + +/** + * A painter the draws the background of the caret line in a configured color. + *

                + * Clients usually instantiate and configure object of this class.

                + *

                + * This class is not intended to be subclassed.

                + * + * @since 2.1 + * @noextend This class is not intended to be subclassed by clients. + */ +public class CursorLinePainter : IPainter, LineBackgroundListener { + + /** The viewer the painter works on */ + private const ITextViewer fViewer; + /** The cursor line back ground color */ + private Color fHighlightColor; + /** The paint position manager for managing the line coordinates */ + private IPaintPositionManager fPositionManager; + + /** Keeps track of the line to be painted */ + private Position fCurrentLine; + /** Keeps track of the line to be cleared */ + private Position fLastLine; + /** Keeps track of the line number of the last painted line */ + private int fLastLineNumber= -1; + /** Indicates whether this painter is active */ + private bool fIsActive; + + /** + * Creates a new painter for the given source viewer. + * + * @param textViewer the source viewer for which to create a painter + */ + public this(ITextViewer textViewer) { + fCurrentLine= new Position(0, 0); + fLastLine= new Position(0, 0); + fViewer= textViewer; + } + + /** + * Sets the color in which to draw the background of the cursor line. + * + * @param highlightColor the color in which to draw the background of the cursor line + */ + public void setHighlightColor(Color highlightColor) { + fHighlightColor= highlightColor; + } + + /* + * @see LineBackgroundListener#lineGetBackground(LineBackgroundEvent) + */ + public void lineGetBackground(LineBackgroundEvent event) { + // don't use cached line information because of asynchronous painting + + StyledText textWidget= fViewer.getTextWidget(); + if (textWidget !is null) { + + int caret= textWidget.getCaretOffset(); + int length= event.lineText.length(); + + if (event.lineOffset <= caret && caret <= event.lineOffset + length) + event.lineBackground= fHighlightColor; + else + event.lineBackground= textWidget.getBackground(); + } + } + + /** + * Updates all the cached information about the lines to be painted and to be cleared. Returns true + * if the line number of the cursor line has changed. + * + * @return true if cursor line changed + */ + private bool updateHighlightLine() { + try { + + IDocument document= fViewer.getDocument(); + int modelCaret= getModelCaret(); + int lineNumber= document.getLineOfOffset(modelCaret); + + // redraw if the current line number is different from the last line number we painted + // initially fLastLineNumber is -1 + if (lineNumber !is fLastLineNumber || !fCurrentLine.overlapsWith(modelCaret, 0)) { + + fLastLine.offset= fCurrentLine.offset; + fLastLine.length= fCurrentLine.length; + fLastLine.isDeleted_= fCurrentLine.isDeleted_; + + if (fCurrentLine.isDeleted_) { + fCurrentLine.isDeleted_= false; + fPositionManager.managePosition(fCurrentLine); + } + + fCurrentLine.offset= document.getLineOffset(lineNumber); + if (lineNumber is document.getNumberOfLines() - 1) + fCurrentLine.length= document.getLength() - fCurrentLine.offset; + else + fCurrentLine.length= document.getLineOffset(lineNumber + 1) - fCurrentLine.offset; + + fLastLineNumber= lineNumber; + return true; + + } + + } catch (BadLocationException e) { + } + + return false; + } + + /** + * Returns the location of the caret as offset in the source viewer's + * input document. + * + * @return the caret location + */ + private int getModelCaret() { + int widgetCaret= fViewer.getTextWidget().getCaretOffset(); + if ( cast(ITextViewerExtension5)fViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) fViewer; + return extension.widgetOffset2ModelOffset(widgetCaret); + } + IRegion visible= fViewer.getVisibleRegion(); + return widgetCaret + visible.getOffset(); + } + + /** + * Assumes the given position to specify offset and length of a line to be painted. + * + * @param position the specification of the line to be painted + */ + private void drawHighlightLine(Position position) { + + // if the position that is about to be drawn was deleted then we can't + if (position.isDeleted()) + return; + + int widgetOffset= 0; + if ( cast(ITextViewerExtension5)fViewer ) { + + ITextViewerExtension5 extension= cast(ITextViewerExtension5) fViewer; + widgetOffset= extension.modelOffset2WidgetOffset(position.getOffset()); + if (widgetOffset is -1) + return; + + } else { + + IRegion visible= fViewer.getVisibleRegion(); + widgetOffset= position.getOffset() - visible.getOffset(); + if (widgetOffset < 0 || visible.getLength() < widgetOffset ) + return; + } + + StyledText textWidget= fViewer.getTextWidget(); + // check for https://bugs.eclipse.org/bugs/show_bug.cgi?id=64898 + // this is a guard against the symptoms but not the actual solution + if (0 <= widgetOffset && widgetOffset <= textWidget.getCharCount()) { + Point upperLeft= textWidget.getLocationAtOffset(widgetOffset); + int width= textWidget.getClientArea().width + textWidget.getHorizontalPixel(); + int height= textWidget.getLineHeight(widgetOffset); + textWidget.redraw(0, upperLeft.y, width, height, false); + } + } + + /* + * @see IPainter#deactivate(bool) + */ + public void deactivate(bool redraw) { + if (fIsActive) { + fIsActive= false; + + /* on turning off the feature one has to paint the currently + * highlighted line with the standard background color + */ + if (redraw) + drawHighlightLine(fCurrentLine); + + fViewer.getTextWidget().removeLineBackgroundListener(this); + + if (fPositionManager !is null) + fPositionManager.unmanagePosition(fCurrentLine); + + fLastLineNumber= -1; + fCurrentLine.offset= 0; + fCurrentLine.length= 0; + } + } + + /* + * @see IPainter#dispose() + */ + public void dispose() { + } + + /* + * @see IPainter#paint(int) + */ + public void paint(int reason) { + if (fViewer.getDocument() is null) { + deactivate(false); + return; + } + + StyledText textWidget= fViewer.getTextWidget(); + + // check selection + Point selection= textWidget.getSelection(); + int startLine= textWidget.getLineAtOffset(selection.x); + int endLine= textWidget.getLineAtOffset(selection.y); + if (startLine !is endLine) { + deactivate(true); + return; + } + + // initialization + if (!fIsActive) { + textWidget.addLineBackgroundListener(this); + fPositionManager.managePosition(fCurrentLine); + fIsActive= true; + } + + //redraw line highlight only if it hasn't been drawn yet on the respective line + if (updateHighlightLine()) { + // clear last line + drawHighlightLine(fLastLine); + // draw new line + drawHighlightLine(fCurrentLine); + } + } + + /* + * @see IPainter#setPositionManager(IPaintPositionManager) + */ + public void setPositionManager(IPaintPositionManager manager) { + fPositionManager = manager; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/DefaultAutoIndentStrategy.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/DefaultAutoIndentStrategy.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,176 @@ +/******************************************************************************* + * 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 + * 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.text.DefaultAutoIndentStrategy; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Default implementation of {@link dwtx.jface.text.IAutoIndentStrategy}. + * This strategy always copies the indentation of the previous line. + *

                + * This class is not intended to be subclassed.

                + * + * @deprecated since 3.1 use {@link dwtx.jface.text.DefaultIndentLineAutoEditStrategy} instead + * @noextend This class is not intended to be subclassed by clients. + */ +public class DefaultAutoIndentStrategy : DefaultIndentLineAutoEditStrategy , IAutoIndentStrategy { + + /** + * Creates a new default auto indent strategy. + */ + public this() { + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/DefaultDocumentAdapter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/DefaultDocumentAdapter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,575 @@ +/******************************************************************************* + * 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.text.DefaultDocumentAdapter; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.dwtxhelper.Collection; + + + +import dwt.DWT; +import dwt.custom.TextChangeListener; +import dwt.custom.TextChangedEvent; +import dwt.custom.TextChangingEvent; +import dwtx.core.runtime.Assert; + + +/** + * Default implementation of {@link dwtx.jface.text.IDocumentAdapter}. + *

                + * Note: This adapter does not work if the widget auto-wraps the text. + *

                + */ +class DefaultDocumentAdapter : IDocumentAdapter, IDocumentListener, IDocumentAdapterExtension { + + /** The adapted document. */ + private IDocument fDocument; + /** The document clone for the non-forwarding case. */ + private IDocument fDocumentClone; + /** The original content */ + private String fOriginalContent; + /** The original line delimiters */ + private String[] fOriginalLineDelimiters; + /** The registered text change listeners */ + private List fTextChangeListeners; + /** + * The remembered document event + * @since 2.0 + */ + private DocumentEvent fEvent; + /** The line delimiter */ + private String fLineDelimiter= null; + /** + * Indicates whether this adapter is forwarding document changes + * @since 2.0 + */ + private bool fIsForwarding= true; + /** + * Length of document at receipt of documentAboutToBeChanged + * @since 2.1 + */ + private int fRememberedLengthOfDocument; + /** + * Length of first document line at receipt of documentAboutToBeChanged + * @since 2.1 + */ + private int fRememberedLengthOfFirstLine; + /** + * The data of the event at receipt of documentAboutToBeChanged + * @since 2.1 + */ + private DocumentEvent fOriginalEvent; + + + /** + * Creates a new document adapter which is initially not connected to + * any document. + */ + public this() { + fTextChangeListeners= new ArrayList(1); + fOriginalEvent= new DocumentEvent(); + } + + /** + * Sets the given document as the document to be adapted. + * + * @param document the document to be adapted or null if there is no document + */ + public void setDocument(IDocument document) { + + if (fDocument !is null) + fDocument.removePrenotifiedDocumentListener(this); + + fDocument= document; + fLineDelimiter= null; + + if (!fIsForwarding) { + fDocumentClone= null; + if (fDocument !is null) { + fOriginalContent= fDocument.get(); + fOriginalLineDelimiters= fDocument.getLegalLineDelimiters(); + } else { + fOriginalContent= null; + fOriginalLineDelimiters= null; + } + } + + if (fDocument !is null) + fDocument.addPrenotifiedDocumentListener(this); + } + + /* + * @see StyledTextContent#addTextChangeListener(TextChangeListener) + */ + public void addTextChangeListener(TextChangeListener listener) { + Assert.isNotNull(cast(Object)listener); + if (!fTextChangeListeners.contains(cast(Object)listener)) + fTextChangeListeners.add(cast(Object)listener); + } + + /* + * @see StyledTextContent#removeTextChangeListener(TextChangeListener) + */ + public void removeTextChangeListener(TextChangeListener listener) { + Assert.isNotNull(cast(Object)listener); + fTextChangeListeners.remove(cast(Object)listener); + } + + /** + * Tries to repair the line information. + * + * @param document the document + * @see IRepairableDocument#repairLineInformation() + * @since 3.0 + */ + private void repairLineInformation(IDocument document) { + if ( cast(IRepairableDocument)document ) { + IRepairableDocument repairable= cast(IRepairableDocument) document; + repairable.repairLineInformation(); + } + } + + /** + * Returns the line for the given line number. + * + * @param document the document + * @param line the line number + * @return the content of the line of the given number in the given document + * @throws BadLocationException if the line number is invalid for the adapted document + * @since 3.0 + */ + private String doGetLine(IDocument document, int line) { + IRegion r= document.getLineInformation(line); + return document.get(r.getOffset(), r.getLength()); + } + + private IDocument getDocumentForRead() { + if (!fIsForwarding) { + if (fDocumentClone is null) { + String content= fOriginalContent is null ? "" : fOriginalContent; //$NON-NLS-1$ + String[] delims= fOriginalLineDelimiters is null ? DefaultLineTracker.DELIMITERS : fOriginalLineDelimiters; + fDocumentClone= new DocumentClone(content, delims); + } + return fDocumentClone; + } + + return fDocument; + } + + /* + * @see StyledTextContent#getLine(int) + */ + public String getLine(int line) { + + IDocument document= getDocumentForRead(); + try { + return doGetLine(document, line); + } catch (BadLocationException x) { + repairLineInformation(document); + try { + return doGetLine(document, line); + } catch (BadLocationException x2) { + } + } + + DWT.error(DWT.ERROR_INVALID_ARGUMENT); + return null; + } + + /* + * @see StyledTextContent#getLineAtOffset(int) + */ + public int getLineAtOffset(int offset) { + IDocument document= getDocumentForRead(); + try { + return document.getLineOfOffset(offset); + } catch (BadLocationException x) { + repairLineInformation(document); + try { + return document.getLineOfOffset(offset); + } catch (BadLocationException x2) { + } + } + + DWT.error(DWT.ERROR_INVALID_ARGUMENT); + return -1; + } + + /* + * @see StyledTextContent#getLineCount() + */ + public int getLineCount() { + return getDocumentForRead().getNumberOfLines(); + } + + /* + * @see StyledTextContent#getOffsetAtLine(int) + */ + public int getOffsetAtLine(int line) { + IDocument document= getDocumentForRead(); + try { + return document.getLineOffset(line); + } catch (BadLocationException x) { + repairLineInformation(document); + try { + return document.getLineOffset(line); + } catch (BadLocationException x2) { + } + } + + DWT.error(DWT.ERROR_INVALID_ARGUMENT); + return -1; + } + + /* + * @see StyledTextContent#getTextRange(int, int) + */ + public String getTextRange(int offset, int length) { + try { + return getDocumentForRead().get(offset, length); + } catch (BadLocationException x) { + DWT.error(DWT.ERROR_INVALID_ARGUMENT); + return null; + } + } + + /* + * @see StyledTextContent#replaceTextRange(int, int, String) + */ + public void replaceTextRange(int pos, int length, String text) { + try { + fDocument.replace(pos, length, text); + } catch (BadLocationException x) { + DWT.error(DWT.ERROR_INVALID_ARGUMENT); + } + } + + /* + * @see StyledTextContent#setText(String) + */ + public void setText(String text) { + fDocument.set(text); + } + + /* + * @see StyledTextContent#getCharCount() + */ + public int getCharCount() { + return getDocumentForRead().getLength(); + } + + /* + * @see StyledTextContent#getLineDelimiter() + */ + public String getLineDelimiter() { + if (fLineDelimiter is null) + fLineDelimiter= TextUtilities.getDefaultLineDelimiter(fDocument); + return fLineDelimiter; + } + + /* + * @see IDocumentListener#documentChanged(DocumentEvent) + */ + public void documentChanged(DocumentEvent event) { + // check whether the given event is the one which was remembered + if (fEvent is null || event !is fEvent) + return; + + if (isPatchedEvent(event) || (event.getOffset() is 0 && event.getLength() is fRememberedLengthOfDocument)) { + fLineDelimiter= null; + fireTextSet(); + } else { + if (event.getOffset() < fRememberedLengthOfFirstLine) + fLineDelimiter= null; + fireTextChanged(); + } + } + + /* + * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent) + */ + public void documentAboutToBeChanged(DocumentEvent event) { + + fRememberedLengthOfDocument= fDocument.getLength(); + try { + fRememberedLengthOfFirstLine= fDocument.getLineLength(0); + } catch (BadLocationException e) { + fRememberedLengthOfFirstLine= -1; + } + + fEvent= event; + rememberEventData(fEvent); + fireTextChanging(); + } + + /** + * Checks whether this event has been changed between documentAboutToBeChanged and + * documentChanged. + * + * @param event the event to be checked + * @return true if the event has been changed, false otherwise + */ + private bool isPatchedEvent(DocumentEvent event) { + return fOriginalEvent.fOffset !is event.fOffset || fOriginalEvent.fLength !is event.fLength || fOriginalEvent.fText !is event.fText; + } + + /** + * Makes a copy of the given event and remembers it. + * + * @param event the event to be copied + */ + private void rememberEventData(DocumentEvent event) { + fOriginalEvent.fOffset= event.fOffset; + fOriginalEvent.fLength= event.fLength; + fOriginalEvent.fText= event.fText; + } + + /** + * Sends a text changed event to all registered listeners. + */ + private void fireTextChanged() { + + if (!fIsForwarding) + return; + + TextChangedEvent event= new TextChangedEvent(this); + + if (fTextChangeListeners !is null && fTextChangeListeners.size() > 0) { + Iterator e= (new ArrayList(fTextChangeListeners)).iterator(); + while (e.hasNext()) + (cast(TextChangeListener) e.next()).textChanged(event); + } + } + + /** + * Sends a text set event to all registered listeners. + */ + private void fireTextSet() { + + if (!fIsForwarding) + return; + + TextChangedEvent event = new TextChangedEvent(this); + + if (fTextChangeListeners !is null && fTextChangeListeners.size() > 0) { + Iterator e= (new ArrayList(fTextChangeListeners)).iterator(); + while (e.hasNext()) + (cast(TextChangeListener) e.next()).textSet(event); + } + } + + /** + * Sends the text changing event to all registered listeners. + */ + private void fireTextChanging() { + + if (!fIsForwarding) + return; + + try { + IDocument document= fEvent.getDocument(); + if (document is null) + return; + + TextChangingEvent event= new TextChangingEvent(this); + event.start= fEvent.fOffset; + event.replaceCharCount= fEvent.fLength; + event.replaceLineCount= document.getNumberOfLines(fEvent.fOffset, fEvent.fLength) - 1; + event.newText= fEvent.fText; + event.newCharCount= (fEvent.fText is null ? 0 : fEvent.fText.length()); + event.newLineCount= (fEvent.fText is null ? 0 : document.computeNumberOfLines(fEvent.fText)); + + if (fTextChangeListeners !is null && fTextChangeListeners.size() > 0) { + Iterator e= (new ArrayList(fTextChangeListeners)).iterator(); + while (e.hasNext()) + (cast(TextChangeListener) e.next()).textChanging(event); + } + + } catch (BadLocationException e) { + } + } + + /* + * @see IDocumentAdapterExtension#resumeForwardingDocumentChanges() + * @since 2.0 + */ + public void resumeForwardingDocumentChanges() { + fIsForwarding= true; + fDocumentClone= null; + fOriginalContent= null; + fOriginalLineDelimiters= null; + fireTextSet(); + } + + /* + * @see IDocumentAdapterExtension#stopForwardingDocumentChanges() + * @since 2.0 + */ + public void stopForwardingDocumentChanges() { + fDocumentClone= null; + fOriginalContent= fDocument.get(); + fOriginalLineDelimiters= fDocument.getLegalLineDelimiters(); + fIsForwarding= false; + } + + /++ + + DWT extension + +/ + public int utf8AdjustOffset( int offset ){ + implMissing(__FILE__,__LINE__); + return offset; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/DefaultIndentLineAutoEditStrategy.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/DefaultIndentLineAutoEditStrategy.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,238 @@ +/******************************************************************************* + * 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 + * 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.text.DefaultIndentLineAutoEditStrategy; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * This strategy always copies the indentation of the previous line. + *

                + * This class is not intended to be subclassed.

                + * + * @since 3.1 + */ +public class DefaultIndentLineAutoEditStrategy : IAutoEditStrategy { + + /** + * Creates a new indent line auto edit strategy which can be installed on + * text viewers. + */ + public this() { + } + + /** + * Returns the first offset greater than offset and smaller than + * end whose character is not a space or tab character. If no such + * offset is found, end is returned. + * + * @param document the document to search in + * @param offset the offset at which searching start + * @param end the offset at which searching stops + * @return the offset in the specified range whose character is not a space or tab + * @exception BadLocationException if position is an invalid range in the given document + */ + protected int findEndOfWhiteSpace(IDocument document, int offset, int end) { + while (offset < end) { + char c= document.getChar(offset); + if (c !is ' ' && c !is '\t') { + return offset; + } + offset++; + } + return end; + } + + /** + * Copies the indentation of the previous line. + * + * @param d the document to work on + * @param c the command to deal with + */ + private void autoIndentAfterNewLine(IDocument d, DocumentCommand c) { + + if (c.offset is -1 || d.getLength() is 0) + return; + + try { + // find start of line + int p= (c.offset is d.getLength() ? c.offset - 1 : c.offset); + IRegion info= d.getLineInformationOfOffset(p); + int start= info.getOffset(); + + // find white spaces + int end= findEndOfWhiteSpace(d, start, c.offset); + + StringBuffer buf= new StringBuffer(c.text); + if (end > start) { + // append to input + buf.append(d.get(start, end - start)); + } + + c.text= buf.toString(); + + } catch (BadLocationException excp) { + // stop work + } + } + + /* + * @see dwtx.jface.text.IAutoEditStrategy#customizeDocumentCommand(dwtx.jface.text.IDocument, dwtx.jface.text.DocumentCommand) + */ + public void customizeDocumentCommand(IDocument d, DocumentCommand c) { + if (c.length is 0 && c.text !is null && TextUtilities.endsWith(d.getLegalLineDelimiters(), c.text) !is -1) + autoIndentAfterNewLine(d, c); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/DefaultInformationControl.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/DefaultInformationControl.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,584 @@ +/******************************************************************************* + * 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 + * 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.text.DefaultInformationControl; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + + +import dwt.DWT; +import dwt.custom.StyledText; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.graphics.Color; +import dwt.graphics.Drawable; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.layout.FillLayout; +import dwt.widgets.Composite; +import dwt.widgets.Display; +import dwt.widgets.Shell; +import dwtx.jface.action.ToolBarManager; +import dwtx.jface.internal.text.html.HTMLTextPresenter; +import dwtx.jface.resource.JFaceResources; +import dwtx.jface.util.Geometry; + + /** + * An information presenter determines the style presentation + * of information displayed in the default information control. + * The interface can be implemented by clients. + */ + public interface IInformationPresenter { + + /** + * Updates the given presentation of the given information and + * thereby may manipulate the information to be displayed. The manipulation + * could be the extraction of textual encoded style information etc. Returns the + * manipulated information. + *

                + * Note: The given display must only be used for measuring.

                + * + * @param display the display of the information control + * @param hoverInfo the information to be presented + * @param presentation the presentation to be updated + * @param maxWidth the maximal width in pixels + * @param maxHeight the maximal height in pixels + * + * @return the manipulated information + * @deprecated As of 3.2, replaced by {@link DefaultInformationControl.IInformationPresenterExtension#updatePresentation(Drawable, String, TextPresentation, int, int)} + */ + String updatePresentation(Display display, String hoverInfo, TextPresentation presentation, int maxWidth, int maxHeight); + } + alias IInformationPresenter DefaultInformationControl_IInformationPresenter; + + /** + * An information presenter determines the style presentation + * of information displayed in the default information control. + * The interface can be implemented by clients. + * + * @since 3.2 + */ + public interface IInformationPresenterExtension { + + /** + * Updates the given presentation of the given information and + * thereby may manipulate the information to be displayed. The manipulation + * could be the extraction of textual encoded style information etc. Returns the + * manipulated information. + *

                + * Replaces {@link DefaultInformationControl.IInformationPresenter#updatePresentation(Display, String, TextPresentation, int, int)} + * Implementations should use the font of the given drawable to calculate + * the size of the text to be presented. + *

                + * + * @param drawable the drawable of the information control + * @param hoverInfo the information to be presented + * @param presentation the presentation to be updated + * @param maxWidth the maximal width in pixels + * @param maxHeight the maximal height in pixels + * + * @return the manipulated information + */ + String updatePresentation(Drawable drawable, String hoverInfo, TextPresentation presentation, int maxWidth, int maxHeight); + } + alias IInformationPresenterExtension DefaultInformationControl_IInformationPresenterExtension; + + +/** + * Default implementation of {@link dwtx.jface.text.IInformationControl}. + *

                + * Displays textual information in a {@link dwt.custom.StyledText} + * widget. Before displaying, the information set to this information control is + * processed by an IInformationPresenter. + * + * @since 2.0 + */ +public class DefaultInformationControl : AbstractInformationControl , DisposeListener { + + /** + * Inner border thickness in pixels. + * @since 3.1 + */ + private static const int INNER_BORDER= 1; + + /** The control's text widget */ + private StyledText fText; + /** The information presenter, or null if none. */ + private const IInformationPresenter fPresenter; + /** A cached text presentation */ + private const TextPresentation fPresentation; + + /** + * Additional styles to use for the text control. + * @since 3.4, previously called fTextStyle + */ + private const int fAdditionalTextStyles; + + /** + * Creates a default information control with the given shell as parent. An information + * presenter that can handle simple HTML is used to process the information to be displayed. + * + * @param parent the parent shell + * @param isResizeable true if the control should be resizable + * @since 3.4 + */ + public this(Shell parent, bool isResizeable) { + fPresentation= new TextPresentation(); + super(parent, isResizeable); + fAdditionalTextStyles= isResizeable ? DWT.V_SCROLL | DWT.H_SCROLL : DWT.NONE; + fPresenter= new HTMLTextPresenter(!isResizeable); + create(); + } + + /** + * Creates a default information control with the given shell as parent. An information + * presenter that can handle simple HTML is used to process the information to be displayed. + * + * @param parent the parent shell + * @param statusFieldText the text to be used in the status field or null to hide the status field + * @since 3.4 + */ + public this(Shell parent, String statusFieldText) { + this(parent, statusFieldText, new HTMLTextPresenter(true)); + } + + /** + * Creates a default information control with the given shell as parent. The + * given information presenter is used to process the information to be + * displayed. + * + * @param parent the parent shell + * @param statusFieldText the text to be used in the status field or null to hide the status field + * @param presenter the presenter to be used, or null if no presenter should be used + * @since 3.4 + */ + public this(Shell parent, String statusFieldText, IInformationPresenter presenter) { + fPresentation= new TextPresentation(); + super(parent, statusFieldText); + fAdditionalTextStyles= DWT.NONE; + fPresenter= presenter; + create(); + } + + /** + * Creates a resizable default information control with the given shell as parent. An + * information presenter that can handle simple HTML is used to process the information to be + * displayed. + * + * @param parent the parent shell + * @param toolBarManager the manager or null if toolbar is not desired + * @since 3.4 + */ + public this(Shell parent, ToolBarManager toolBarManager) { + this(parent, toolBarManager, new HTMLTextPresenter(false)); + } + + /** + * Creates a resizable default information control with the given shell as + * parent. The given information presenter is used to process the + * information to be displayed. + * + * @param parent the parent shell + * @param toolBarManager the manager or null if toolbar is not desired + * @param presenter the presenter to be used, or null if no presenter should be used + * @since 3.4 + */ + public this(Shell parent, ToolBarManager toolBarManager, IInformationPresenter presenter) { + fPresentation= new TextPresentation(); + super(parent, toolBarManager); + fAdditionalTextStyles= DWT.V_SCROLL | DWT.H_SCROLL; + fPresenter= presenter; + create(); + } + + /** + * Creates a default information control with the given shell as parent. + * No information presenter is used to process the information + * to be displayed. + * + * @param parent the parent shell + */ + public this(Shell parent) { + this(parent, cast(String)null, null); + } + + /** + * Creates a default information control with the given shell as parent. The given + * information presenter is used to process the information to be displayed. + * + * @param parent the parent shell + * @param presenter the presenter to be used + */ + public this(Shell parent, IInformationPresenter presenter) { + this(parent, cast(String)null, presenter); + } + + /** + * Creates a default information control with the given shell as parent. The + * given information presenter is used to process the information to be + * displayed. The given styles are applied to the created styled text + * widget. + * + * @param parent the parent shell + * @param shellStyle the additional styles for the shell + * @param style the additional styles for the styled text widget + * @param presenter the presenter to be used + * @deprecated As of 3.4, replaced by simpler constructors + */ + public this(Shell parent, int shellStyle, int style, IInformationPresenter presenter) { + this(parent, shellStyle, style, presenter, null); + } + + /** + * Creates a default information control with the given shell as parent. The + * given information presenter is used to process the information to be + * displayed. The given styles are applied to the created styled text + * widget. + * + * @param parentShell the parent shell + * @param shellStyle the additional styles for the shell + * @param style the additional styles for the styled text widget + * @param presenter the presenter to be used + * @param statusFieldText the text to be used in the status field or null to hide the status field + * @since 3.0 + * @deprecated As of 3.4, replaced by simpler constructors + */ + public this(Shell parentShell, int shellStyle, int style, IInformationPresenter presenter, String statusFieldText) { + fPresentation= new TextPresentation(); + super(parentShell, DWT.NO_FOCUS | DWT.ON_TOP | shellStyle, statusFieldText, null); + fAdditionalTextStyles= style; + fPresenter= presenter; + create(); + } + + /** + * Creates a default information control with the given shell as parent. The + * given information presenter is used to process the information to be + * displayed. + * + * @param parent the parent shell + * @param textStyles the additional styles for the styled text widget + * @param presenter the presenter to be used + * @deprecated As of 3.4, replaced by {@link #DefaultInformationControl(Shell, DefaultInformationControl.IInformationPresenter)} + */ + public this(Shell parent, int textStyles, IInformationPresenter presenter) { + this(parent, textStyles, presenter, null); + } + + /** + * Creates a default information control with the given shell as parent. The + * given information presenter is used to process the information to be + * displayed. + * + * @param parent the parent shell + * @param textStyles the additional styles for the styled text widget + * @param presenter the presenter to be used + * @param statusFieldText the text to be used in the status field or null to hide the status field + * @since 3.0 + * @deprecated As of 3.4, replaced by {@link #DefaultInformationControl(Shell, String, DefaultInformationControl.IInformationPresenter)} + */ + public this(Shell parent, int textStyles, IInformationPresenter presenter, String statusFieldText) { + fPresentation= new TextPresentation(); + super(parent, statusFieldText); + fAdditionalTextStyles= textStyles; + fPresenter= presenter; + create(); + } + + /* + * @see dwtx.jface.text.AbstractInformationControl#createContent(dwt.widgets.Composite) + */ + protected void createContent(Composite parent) { + fText= new StyledText(parent, DWT.MULTI | DWT.READ_ONLY | fAdditionalTextStyles); + fText.setForeground(parent.getForeground()); + fText.setBackground(parent.getBackground()); + fText.setFont(JFaceResources.getDialogFont()); + FillLayout layout= cast(FillLayout)parent.getLayout(); + if (fText.getWordWrap()) { + // indent does not work for wrapping StyledText, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=56342 and https://bugs.eclipse.org/bugs/show_bug.cgi?id=115432 + layout.marginHeight= INNER_BORDER; + layout.marginWidth= INNER_BORDER; + } else { + fText.setIndent(INNER_BORDER); + } + } + + /* + * @see IInformationControl#setInformation(String) + */ + public void setInformation(String content) { + if (fPresenter is null) { + fText.setText(content); + } else { + fPresentation.clear(); + + int maxWidth= -1; + int maxHeight= -1; + Point constraints= getSizeConstraints(); + if (constraints !is null) { + maxWidth= constraints.x; + maxHeight= constraints.y; + if (fText.getWordWrap()) { + maxWidth-= INNER_BORDER * 2; + maxHeight-= INNER_BORDER * 2; + } else { + maxWidth-= INNER_BORDER; // indent + } + Rectangle trim= computeTrim(); + maxWidth-= trim.width; + maxHeight-= trim.height; + maxWidth-= fText.getCaret().getSize().x; // StyledText adds a border at the end of the line for the caret. + } + if (isResizable()) + maxHeight= Integer.MAX_VALUE; + + if ( cast(IInformationPresenterExtension)fPresenter ) + content= (cast(IInformationPresenterExtension)fPresenter).updatePresentation(fText, content, fPresentation, maxWidth, maxHeight); + else + content= fPresenter.updatePresentation(getShell().getDisplay(), content, fPresentation, maxWidth, maxHeight); + + if (content !is null) { + fText.setText(content); + TextPresentation.applyTextPresentation(fPresentation, fText); + } else { + fText.setText(""); //$NON-NLS-1$ + } + } + } + + /* + * @see IInformationControl#setVisible(bool) + */ + public void setVisible(bool visible) { + if (visible) { + if (fText.getWordWrap()) { + Point currentSize= getShell().getSize(); + getShell().pack(true); + Point newSize= getShell().getSize(); + if (newSize.x > currentSize.x || newSize.y > currentSize.y) + setSize(currentSize.x, currentSize.y); // restore previous size + } + } + + super.setVisible(visible); + } + + /* + * @see IInformationControl#computeSizeHint() + */ + public Point computeSizeHint() { + // see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=117602 + int widthHint= DWT.DEFAULT; + Point constraints= getSizeConstraints(); + if (constraints !is null && fText.getWordWrap()) + widthHint= constraints.x; + + return getShell().computeSize(widthHint, DWT.DEFAULT, true); + } + + /* + * @see dwtx.jface.text.AbstractInformationControl#computeTrim() + */ + public Rectangle computeTrim() { + return Geometry.add(super.computeTrim(), fText.computeTrim(0, 0, 0, 0)); + } + + /* + * @see IInformationControl#setForegroundColor(Color) + */ + public void setForegroundColor(Color foreground) { + super.setForegroundColor(foreground); + fText.setForeground(foreground); + } + + /* + * @see IInformationControl#setBackgroundColor(Color) + */ + public void setBackgroundColor(Color background) { + super.setBackgroundColor(background); + fText.setBackground(background); + } + + /* + * @see IInformationControlExtension#hasContents() + */ + public bool hasContents() { + return fText.getCharCount() > 0; + } + + /** + * @see dwt.events.DisposeListener#widgetDisposed(dwt.events.DisposeEvent) + * @since 3.0 + * @deprecated As of 3.2, no longer used and called + */ + public void widgetDisposed(DisposeEvent event) { + } + + /* + * @see dwtx.jface.text.IInformationControlExtension5#getInformationPresenterControlCreator() + * @since 3.4 + */ + public IInformationControlCreator getInformationPresenterControlCreator() { + return new class() IInformationControlCreator { + /* + * @see dwtx.jface.text.IInformationControlCreator#createInformationControl(dwt.widgets.Shell) + */ + public IInformationControl createInformationControl(Shell parent) { + return new DefaultInformationControl(parent, cast(ToolBarManager) null, fPresenter); + } + }; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/DefaultLineTracker.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/DefaultLineTracker.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,229 @@ +/******************************************************************************* + * 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 + * 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.text.DefaultLineTracker; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Standard implementation of {@link dwtx.jface.text.ILineTracker}. + *

                + * The line tracker considers the three common line delimiters which are '\n', + * '\r', '\r\n'. + *

                + * This class is not intended to be subclassed. + *

                + * @noextend This class is not intended to be subclassed by clients. + */ +public class DefaultLineTracker : AbstractLineTracker { + + /** The predefined delimiters of this tracker */ + public const static String[] DELIMITERS= [ "\r", "\n", "\r\n" ]; //$NON-NLS-3$ //$NON-NLS-1$ //$NON-NLS-2$ + /** A predefined delimiter information which is always reused as return value */ + private AbstractLineTracker_DelimiterInfo fDelimiterInfo; + + + /** + * Creates a standard line tracker. + */ + public this() { + fDelimiterInfo= new AbstractLineTracker_DelimiterInfo(); + } + + /* + * @see dwtx.jface.text.ILineTracker#getLegalLineDelimiters() + */ + public String[] getLegalLineDelimiters() { + return TextUtilities.copy(DELIMITERS); + } + + /* + * @see dwtx.jface.text.AbstractLineTracker#nextDelimiterInfo(java.lang.String, int) + */ + protected AbstractLineTracker_DelimiterInfo nextDelimiterInfo(String text, int offset) { + + char ch; + int length= text.length(); + for (int i= offset; i < length; i++) { + + ch= text.charAt(i); + if (ch is '\r') { + + if (i + 1 < length) { + if (text.charAt(i + 1) is '\n') { + fDelimiterInfo.delimiter= DELIMITERS[2]; + fDelimiterInfo.delimiterIndex= i; + fDelimiterInfo.delimiterLength= 2; + return fDelimiterInfo; + } + } + + fDelimiterInfo.delimiter= DELIMITERS[0]; + fDelimiterInfo.delimiterIndex= i; + fDelimiterInfo.delimiterLength= 1; + return fDelimiterInfo; + + } else if (ch is '\n') { + + fDelimiterInfo.delimiter= DELIMITERS[1]; + fDelimiterInfo.delimiterIndex= i; + fDelimiterInfo.delimiterLength= 1; + return fDelimiterInfo; + } + } + + return null; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/DefaultPositionUpdater.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/DefaultPositionUpdater.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,393 @@ +/******************************************************************************* + * 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.text.DefaultPositionUpdater; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Default implementation of {@link dwtx.jface.text.IPositionUpdater}. + *

                + * A default position updater must be configured with the position category whose positions it will + * update. Other position categories are not affected by this updater. + *

                + *

                + * This implementation follows the specification below: + *

                + *
                  + *
                • Inserting or deleting text before the position shifts the position accordingly.
                • + *
                • Inserting text at the position offset shifts the position accordingly.
                • + *
                • Inserting or deleting text strictly contained by the position shrinks or stretches the + * position.
                • + *
                • Inserting or deleting text after a position does not affect the position.
                • + *
                • Deleting text which strictly contains the position deletes the position. Note that the + * position is not deleted if its only shrunken to length zero. To delete a position, the + * modification must delete from strictly before to strictly after the position.
                • + *
                • Replacing text overlapping with the position is considered as a sequence of first deleting + * the replaced text and afterwards inserting the new text. Thus, a position might first be shifted + * and shrunken and then be stretched.
                • + *
                + * This class can be used as is or be adapted by subclasses. Fields are protected to allow + * subclasses direct access. Because of the frequency with which position updaters are used this is + * a performance decision. + */ +public class DefaultPositionUpdater : IPositionUpdater { + + /** The position category the updater draws responsible for */ + private String fCategory; + + /** Caches the currently investigated position */ + protected Position fPosition; + /** + * Remembers the original state of the investigated position + * @since 2.1 + */ + protected Position fOriginalPosition; + /** Caches the offset of the replaced text */ + protected int fOffset; + /** Caches the length of the replaced text */ + protected int fLength; + /** Caches the length of the newly inserted text */ + protected int fReplaceLength; + /** Catches the document */ + protected IDocument fDocument; + + + /** + * Creates a new default position updater for the given category. + * + * @param category the category the updater is responsible for + */ + public this(String category) { + fOriginalPosition= new Position(0, 0); + fCategory= category; + } + + /** + * Returns the category this updater is responsible for. + * + * @return the category this updater is responsible for + */ + protected String getCategory() { + return fCategory; + } + + /** + * Returns whether the current event describes a well formed replace + * by which the current position is directly affected. + * + * @return true the current position is directly affected + * @since 3.0 + */ + protected bool isAffectingReplace() { + return fLength > 0 && fReplaceLength > 0 && fPosition.length < fOriginalPosition.length; + } + + /** + * Adapts the currently investigated position to an insertion. + */ + protected void adaptToInsert() { + + int myStart= fPosition.offset; + int myEnd= fPosition.offset + fPosition.length - 1; + myEnd= Math.max(myStart, myEnd); + + int yoursStart= fOffset; + int yoursEnd= fOffset + fReplaceLength -1; + yoursEnd= Math.max(yoursStart, yoursEnd); + + if (myEnd < yoursStart) + return; + + if (fLength <= 0) { + + if (myStart < yoursStart) + fPosition.length += fReplaceLength; + else + fPosition.offset += fReplaceLength; + + } else { + + if (myStart <= yoursStart && fOriginalPosition.offset <= yoursStart) + fPosition.length += fReplaceLength; + else + fPosition.offset += fReplaceLength; + } + } + + /** + * Adapts the currently investigated position to a deletion. + */ + protected void adaptToRemove() { + + int myStart= fPosition.offset; + int myEnd= fPosition.offset + fPosition.length -1; + myEnd= Math.max(myStart, myEnd); + + int yoursStart= fOffset; + int yoursEnd= fOffset + fLength -1; + yoursEnd= Math.max(yoursStart, yoursEnd); + + if (myEnd < yoursStart) + return; + + if (myStart <= yoursStart) { + + if (yoursEnd <= myEnd) + fPosition.length -= fLength; + else + fPosition.length -= (myEnd - yoursStart +1); + + } else if (yoursStart < myStart) { + + if (yoursEnd < myStart) + fPosition.offset -= fLength; + else { + fPosition.offset -= (myStart - yoursStart); + fPosition.length -= (yoursEnd - myStart +1); + } + + } + + // validate position to allowed values + if (fPosition.offset < 0) + fPosition.offset= 0; + + if (fPosition.length < 0) + fPosition.length= 0; + } + + /** + * Adapts the currently investigated position to the replace operation. + * First it checks whether the change replaces the whole range of the position. + * If not, it performs first the deletion of the previous text and afterwards + * the insertion of the new text. + */ + protected void adaptToReplace() { + + if (fPosition.offset is fOffset && fPosition.length is fLength && fPosition.length > 0) { + + // replace the whole range of the position + fPosition.length += (fReplaceLength - fLength); + if (fPosition.length < 0) { + fPosition.offset += fPosition.length; + fPosition.length= 0; + } + + } else { + + if (fLength > 0) + adaptToRemove(); + + if (fReplaceLength > 0) + adaptToInsert(); + } + } + + /** + * Determines whether the currently investigated position has been deleted by + * the replace operation specified in the current event. If so, it deletes + * the position and removes it from the document's position category. + * + * @return true if position has not been deleted + */ + protected bool notDeleted() { + + if (fOffset < fPosition.offset && (fPosition.offset + fPosition.length < fOffset + fLength)) { + + fPosition.delete_(); + + try { + fDocument.removePosition(fCategory, fPosition); + } catch (BadPositionCategoryException x) { + } + + return false; + } + + return true; + } + + /* + * @see dwtx.jface.text.IPositionUpdater#update(dwtx.jface.text.DocumentEvent) + */ + public void update(DocumentEvent event) { + + try { + + + fOffset= event.getOffset(); + fLength= event.getLength(); + fReplaceLength= (event.getText() is null ? 0 : event.getText().length()); + fDocument= event.getDocument(); + + Position[] category= fDocument.getPositions(fCategory); + for (int i= 0; i < category.length; i++) { + + fPosition= category[i]; + fOriginalPosition.offset= fPosition.offset; + fOriginalPosition.length= fPosition.length; + + if (notDeleted()) + adaptToReplace(); + } + + } catch (BadPositionCategoryException x) { + // do nothing + } finally { + fDocument= null; + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/DefaultTextDoubleClickStrategy.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/DefaultTextDoubleClickStrategy.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,369 @@ +/******************************************************************************* + * 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 + * 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.text.DefaultTextDoubleClickStrategy; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.CharacterIterator; + +import dwtx.dwtxhelper.mangoicu.UBreakIterator; + +/** + * Standard implementation of + * {@link dwtx.jface.text.ITextDoubleClickStrategy}. + *

                + * Selects words using java.text.UBreakIterator for the default + * locale.

                + *

                + * This class is not intended to be subclassed. + *

                + * + * @see java.text.UBreakIterator + * @noextend This class is not intended to be subclassed by clients. + */ +public class DefaultTextDoubleClickStrategy : ITextDoubleClickStrategy { + + + /** + * Implements a character iterator that works directly on + * instances of IDocument. Used to collaborate with + * the break iterator. + * + * @see IDocument + * @since 2.0 + */ + static class DocumentCharacterIterator : CharacterIterator { + + /** Document to iterate over. */ + private IDocument fDocument; + /** Start offset of iteration. */ + private int fOffset= -1; + /** End offset of iteration. */ + private int fEndOffset= -1; + /** Current offset of iteration. */ + private int fIndex= -1; + + /** Creates a new document iterator. */ + public this() { + } + + /** + * Configures this document iterator with the document section to be visited. + * + * @param document the document to be iterated + * @param iteratorRange the range in the document to be iterated + */ + public void setDocument(IDocument document, IRegion iteratorRange) { + fDocument= document; + fOffset= iteratorRange.getOffset(); + fEndOffset= fOffset + iteratorRange.getLength(); + } + + /* + * @see CharacterIterator#first() + */ + public char first() { + fIndex= fOffset; + return current(); + } + + /* + * @see CharacterIterator#last() + */ + public char last() { + fIndex= fOffset < fEndOffset ? fEndOffset -1 : fEndOffset; + return current(); + } + + /* + * @see CharacterIterator#current() + */ + public char current() { + if (fOffset <= fIndex && fIndex < fEndOffset) { + try { + return fDocument.getChar(fIndex); + } catch (BadLocationException x) { + } + } + return DONE; + } + + /* + * @see CharacterIterator#next() + */ + public char next() { + ++fIndex; + int end= getEndIndex(); + if (fIndex >= end) { + fIndex= end; + return DONE; + } + return current(); + } + + /* + * @see CharacterIterator#previous() + */ + public char previous() { + if (fIndex is fOffset) + return DONE; + + if (fIndex > fOffset) + -- fIndex; + + return current(); + } + + /* + * @see CharacterIterator#setIndex(int) + */ + public char setIndex(int index) { + fIndex= index; + return current(); + } + + /* + * @see CharacterIterator#getBeginIndex() + */ + public int getBeginIndex() { + return fOffset; + } + + /* + * @see CharacterIterator#getEndIndex() + */ + public int getEndIndex() { + return fEndOffset; + } + + /* + * @see CharacterIterator#getIndex() + */ + public int getIndex() { + return fIndex; + } + + /* + * @see CharacterIterator#clone() + */ + public Object clone() { + DocumentCharacterIterator i= new DocumentCharacterIterator(); + i.fDocument= fDocument; + i.fIndex= fIndex; + i.fOffset= fOffset; + i.fEndOffset= fEndOffset; + return i; + } + } + + + /** + * The document character iterator used by this strategy. + * @since 2.0 + */ + private DocumentCharacterIterator fDocIter= new DocumentCharacterIterator(); + + + /** + * Creates a new default text double click strategy. + */ + public this() { +// super(); + } + + /* + * @see dwtx.jface.text.ITextDoubleClickStrategy#doubleClicked(dwtx.jface.text.ITextViewer) + */ + public void doubleClicked(ITextViewer text) { + + int position= text.getSelectedRange().x; + + if (position < 0) + return; + + try { + + IDocument document= text.getDocument(); + IRegion line= document.getLineInformationOfOffset(position); + if (position is line.getOffset() + line.getLength()) + return; + + fDocIter.setDocument(document, line); + + UBreakIterator breakIter= UBreakIterator.openWordIterator( ULocale.Default, fDocIter ); + + int start= breakIter.preceding(position); + if (start is UBreakIterator.DONE) + start= line.getOffset(); + + int end= breakIter.following(position); + if (end is UBreakIterator.DONE) + end= line.getOffset() + line.getLength(); + + if (breakIter.isBoundary(position)) { + if (end - position > position- start) + start= position; + else + end= position; + } + + if (start !is end) + text.setSelectedRange(start, end - start); + + } catch (BadLocationException x) { + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/DefaultTextHover.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/DefaultTextHover.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,283 @@ +/******************************************************************************* + * 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 + * 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.text.DefaultTextHover; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.source.Annotation; +import dwtx.jface.text.source.IAnnotationModel; +import dwtx.jface.text.source.ISourceViewer; +import dwtx.jface.text.source.ISourceViewerExtension2; + +/** + * Standard implementation of {@link dwtx.jface.text.ITextHover}. + * + * @since 3.2 + */ +public class DefaultTextHover : ITextHover { + + /** This hover's source viewer */ + private ISourceViewer fSourceViewer; + + /** + * Creates a new annotation hover. + * + * @param sourceViewer this hover's annotation model + */ + public this(ISourceViewer sourceViewer) { + dwtx.core.runtime.Assert.Assert.isNotNull(cast(Object)sourceViewer); + fSourceViewer= sourceViewer; + } + + /* + * @see dwtx.jface.text.ITextHover#getHoverInfo(dwtx.jface.text.ITextViewer, dwtx.jface.text.IRegion) + */ + public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) { + IAnnotationModel model= getAnnotationModel(fSourceViewer); + if (model is null) + return null; + + Iterator e= model.getAnnotationIterator(); + while (e.hasNext()) { + Annotation a= cast(Annotation) e.next(); + if (isIncluded(a)) { + Position p= model.getPosition(a); + if (p !is null && p.overlapsWith(hoverRegion.getOffset(), hoverRegion.getLength())) { + String msg= a.getText(); + if (msg !is null && msg.trim().length() > 0) + return msg; + } + } + } + + return null; + } + + /* + * @see dwtx.jface.text.ITextHover#getHoverRegion(dwtx.jface.text.ITextViewer, int) + */ + public IRegion getHoverRegion(ITextViewer textViewer, int offset) { + return findWord(textViewer.getDocument(), offset); + } + + /** + * Tells whether the annotation should be included in + * the computation. + * + * @param annotation the annotation to test + * @return true if the annotation is included in the computation + */ + protected bool isIncluded(Annotation annotation) { + return true; + } + + private IAnnotationModel getAnnotationModel(ISourceViewer viewer) { + if (cast(ISourceViewerExtension2)viewer ) { + ISourceViewerExtension2 extension= cast(ISourceViewerExtension2) viewer; + return extension.getVisualAnnotationModel(); + } + return viewer.getAnnotationModel(); + } + + private IRegion findWord(IDocument document, int offset) { + int start= -2; + int end= -1; + +implMissing(__FILE__,__LINE__); +// DWT FIXME: unicode +/+ + try { + int pos= offset; + wchar c; + + while (pos >= 0) { + c= document.getChar(pos); + if (!Character.isUnicodeIdentifierPart(c)) + break; + --pos; + } + + start= pos; + + pos= offset; + int length= document.getLength(); + + while (pos < length) { + c= document.getChar(pos); + if (!Character.isUnicodeIdentifierPart(c)) + break; + ++pos; + } + + end= pos; + + } catch (BadLocationException x) { + } + + if (start >= -1 && end > -1) { + if (start is offset && end is offset) + return new Region(offset, 0); + else if (start is offset) + return new Region(start, end - start); + else + return new Region(start + 1, end - start - 1); + } ++/ + return null; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/DefaultUndoManager.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/DefaultUndoManager.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,1482 @@ +/******************************************************************************* + * 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 + * 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.text.DefaultUndoManager; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + + +import dwtx.dwtxhelper.Collection; + + +import dwt.DWT; +import dwt.custom.StyledText; +import dwt.events.KeyEvent; +import dwt.events.KeyListener; +import dwt.events.MouseEvent; +import dwt.events.MouseListener; +import dwt.widgets.Event; +import dwt.widgets.Display; +import dwt.widgets.Shell; +import dwtx.core.commands.ExecutionException; +import dwtx.core.commands.operations.AbstractOperation; +import dwtx.core.commands.operations.IOperationHistory; +import dwtx.core.commands.operations.IOperationHistoryListener; +import dwtx.core.commands.operations.IUndoContext; +import dwtx.core.commands.operations.IUndoableOperation; +import dwtx.core.commands.operations.ObjectUndoContext; +import dwtx.core.commands.operations.OperationHistoryEvent; +import dwtx.core.commands.operations.OperationHistoryFactory; +import dwtx.core.runtime.IAdaptable; +import dwtx.core.runtime.IProgressMonitor; +import dwtx.core.runtime.IStatus; +import dwtx.core.runtime.Status; +import dwtx.jface.dialogs.MessageDialog; + + +/** + * Standard implementation of {@link dwtx.jface.text.IUndoManager}. + *

                + * It registers with the connected text viewer as text input listener and + * document listener and logs all changes. It also monitors mouse and keyboard + * activities in order to partition the stream of text changes into undo-able + * edit commands. + *

                + *

                + * Since 3.1 this undo manager is a facade to the global operation history. + *

                + *

                + * The usage of {@link dwtx.core.runtime.IAdaptable} in the JFace + * layer has been approved by Platform UI, see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=87669#c9 + *

                + *

                + * This class is not intended to be subclassed. + *

                + * + * @see dwtx.jface.text.ITextViewer + * @see dwtx.jface.text.ITextInputListener + * @see dwtx.jface.text.IDocumentListener + * @see dwtx.core.commands.operations.IUndoableOperation + * @see dwtx.core.commands.operations.IOperationHistory + * @see MouseListener + * @see KeyListener + * @deprecated As of 3.2, replaced by {@link TextViewerUndoManager} + * @noextend This class is not intended to be subclassed by clients. + */ +public class DefaultUndoManager : IUndoManager, IUndoManagerExtension { + + /** + * Represents an undo-able edit command. + *

                + * Since 3.1 this implements the interface for IUndoableOperation. + *

                + */ + class TextCommand : AbstractOperation { + + /** The start index of the replaced text. */ + protected int fStart= -1; + /** The end index of the replaced text. */ + protected int fEnd= -1; + /** The newly inserted text. */ + protected String fText; + /** The replaced text. */ + protected String fPreservedText; + + /** The undo modification stamp. */ + protected long fUndoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; + /** The redo modification stamp. */ + protected long fRedoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; + + /** + * Creates a new text command. + * + * @param context the undo context for this command + * @since 3.1 + */ + this(IUndoContext context) { + super(JFaceTextMessages.getString("DefaultUndoManager.operationLabel")); //$NON-NLS-1$ + addContext(context); + } + + /** + * Re-initializes this text command. + */ + protected void reinitialize() { + fStart= fEnd= -1; + fText= fPreservedText= null; + fUndoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; + fRedoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; + } + + /** + * Sets the start and the end index of this command. + * + * @param start the start index + * @param end the end index + */ + protected void set(int start, int end) { + fStart= start; + fEnd= end; + fText= null; + fPreservedText= null; + } + + /* + * @see dwtx.core.commands.operations.IUndoableOperation#dispose() + * @since 3.1 + */ + public void dispose() { + reinitialize(); + } + + /** + * Undo the change described by this command. + * + * @since 2.0 + */ + protected void undoTextChange() { + try { + IDocument document= fTextViewer.getDocument(); + if ( cast(IDocumentExtension4)document ) + (cast(IDocumentExtension4)document).replace(fStart, fText.length(), fPreservedText, fUndoModificationStamp); + else + document.replace(fStart, fText.length(), fPreservedText); + } catch (BadLocationException x) { + } + } + + /* + * @see dwtx.core.commands.operations.IUndoableOperation#canUndo() + * @since 3.1 + */ + public bool canUndo() { + + if (isConnected() && isValid()) { + IDocument doc= fTextViewer.getDocument(); + if ( cast(IDocumentExtension4)doc ) { + long docStamp= (cast(IDocumentExtension4)doc).getModificationStamp(); + + // Normal case: an undo is valid if its redo will restore document + // to its current modification stamp + bool canUndo= docStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP || + docStamp is getRedoModificationStamp(); + + /* Special case to check if the answer is false. + * If the last document change was empty, then the document's + * modification stamp was incremented but nothing was committed. + * The operation being queried has an older stamp. In this case only, + * the comparison is different. A sequence of document changes that + * include an empty change is handled correctly when a valid commit + * follows the empty change, but when #canUndo() is queried just after + * an empty change, we must special case the check. The check is very + * specific to prevent false positives. + * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=98245 + */ + if (!canUndo && + this is fHistory.getUndoOperation(fUndoContext) && // this is the latest operation + this !is fCurrent && // there is a more current operation not on the stack + !fCurrent.isValid() && // the current operation is not a valid document modification + fCurrent.fUndoModificationStamp !is // the invalid current operation has a document stamp + IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP) { + canUndo= fCurrent.fRedoModificationStamp is docStamp; + } + /* + * When the composite is the current command, it may hold the timestamp + * of a no-op change. We check this here rather than in an override of + * canUndo() in CompoundTextCommand simply to keep all the special case checks + * in one place. + */ + if (!canUndo && + this is fHistory.getUndoOperation(fUndoContext) && // this is the latest operation + null !is cast(CompoundTextCommand)this && + this is fCurrent && // this is the current operation + this.fStart is -1 && // the current operation text is not valid + fCurrent.fRedoModificationStamp !is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP) { // but it has a redo stamp + canUndo= fCurrent.fRedoModificationStamp is docStamp; + } + + } + // if there is no timestamp to check, simply return true per the 3.0.1 behavior + return true; + } + return false; + } + + /* + * @see dwtx.core.commands.operations.IUndoableOperation#canRedo() + * @since 3.1 + */ + public bool canRedo() { + if (isConnected() && isValid()) { + IDocument doc= fTextViewer.getDocument(); + if ( cast(IDocumentExtension4)doc ) { + long docStamp= (cast(IDocumentExtension4)doc).getModificationStamp(); + return docStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP || + docStamp is getUndoModificationStamp(); + } + // if there is no timestamp to check, simply return true per the 3.0.1 behavior + return true; + } + return false; + } + + /* + * @see dwtx.core.commands.operations.IUndoableOperation#canExecute() + * @since 3.1 + */ + public bool canExecute() { + return isConnected(); + } + + /* + * @see dwtx.core.commands.operations.IUndoableOperation#execute(dwtx.core.runtime.IProgressMonitor, dwtx.core.runtime.IAdaptable) + * @since 3.1 + */ + public IStatus execute(IProgressMonitor monitor, IAdaptable uiInfo) { + // Text commands execute as they are typed, so executing one has no effect. + return Status.OK_STATUS; + } + + /* + * Undo the change described by this command. Also selects and + * reveals the change. + */ + + /** + * Undo the change described by this command. Also selects and + * reveals the change. + * + * @param monitor the progress monitor to use if necessary + * @param uiInfo an adaptable that can provide UI info if needed + * @return the status + */ + public IStatus undo(IProgressMonitor monitor, IAdaptable uiInfo) { + if (isValid()) { + undoTextChange(); + selectAndReveal(fStart, fPreservedText is null ? 0 : fPreservedText.length()); + resetProcessChangeSate(); + return Status.OK_STATUS; + } + return IOperationHistory.OPERATION_INVALID_STATUS; + } + + /** + * Re-applies the change described by this command. + * + * @since 2.0 + */ + protected void redoTextChange() { + try { + IDocument document= fTextViewer.getDocument(); + if ( cast(IDocumentExtension4)document ) + (cast(IDocumentExtension4)document).replace(fStart, fEnd - fStart, fText, fRedoModificationStamp); + else + fTextViewer.getDocument().replace(fStart, fEnd - fStart, fText); + } catch (BadLocationException x) { + } + } + + /** + * Re-applies the change described by this command that previously been + * rolled back. Also selects and reveals the change. + * + * @param monitor the progress monitor to use if necessary + * @param uiInfo an adaptable that can provide UI info if needed + * @return the status + */ + public IStatus redo(IProgressMonitor monitor, IAdaptable uiInfo) { + if (isValid()) { + redoTextChange(); + resetProcessChangeSate(); + selectAndReveal(fStart, fText is null ? 0 : fText.length()); + return Status.OK_STATUS; + } + return IOperationHistory.OPERATION_INVALID_STATUS; + } + + /** + * Update the command in response to a commit. + * + * @since 3.1 + */ + + protected void updateCommand() { + fText= fTextBuffer.toString(); + fTextBuffer.truncate(0); + fPreservedText= fPreservedTextBuffer.toString(); + fPreservedTextBuffer.truncate(0); + } + + /** + * Creates a new uncommitted text command depending on whether + * a compound change is currently being executed. + * + * @return a new, uncommitted text command or a compound text command + */ + protected TextCommand createCurrent() { + return fFoldingIntoCompoundChange ? new CompoundTextCommand(fUndoContext) : new TextCommand(fUndoContext); + } + + /** + * Commits the current change into this command. + */ + protected void commit() { + if (fStart < 0) { + if (fFoldingIntoCompoundChange) { + fCurrent= createCurrent(); + } else { + reinitialize(); + } + } else { + updateCommand(); + fCurrent= createCurrent(); + } + resetProcessChangeSate(); + } + + /** + * Updates the text from the buffers without resetting + * the buffers or adding anything to the stack. + * + * @since 3.1 + */ + protected void pretendCommit() { + if (fStart > -1) { + fText= fTextBuffer.toString(); + fPreservedText= fPreservedTextBuffer.toString(); + } + } + + /** + * Attempt a commit of this command and answer true if a new + * fCurrent was created as a result of the commit. + * + * @return true if the command was committed and created a + * new fCurrent, false if not. + * @since 3.1 + */ + protected bool attemptCommit() { + pretendCommit(); + if (isValid()) { + this.outer.commit(); + return true; + } + return false; + } + + /** + * Checks whether this text command is valid for undo or redo. + * + * @return true if the command is valid for undo or redo + * @since 3.1 + */ + protected bool isValid() { + return fStart > -1 && + fEnd > -1 && + fText !is null; + } + + /* + * @see java.lang.Object#toString() + * @since 3.1 + */ + public override String toString() { + String delimiter= ", "; //$NON-NLS-1$ + StringBuffer text= new StringBuffer(super.toString()); + text.append("\n"); //$NON-NLS-1$ + text.append(this.classinfo.name); + text.append(" undo modification stamp: "); //$NON-NLS-1$ + text.append(fUndoModificationStamp); + text.append(" redo modification stamp: "); //$NON-NLS-1$ + text.append(fRedoModificationStamp); + text.append(" start: "); //$NON-NLS-1$ + text.append(fStart); + text.append(delimiter); + text.append("end: "); //$NON-NLS-1$ + text.append(fEnd); + text.append(delimiter); + text.append("text: '"); //$NON-NLS-1$ + text.append(fText); + text.append('\''); + text.append(delimiter); + text.append("preservedText: '"); //$NON-NLS-1$ + text.append(fPreservedText); + text.append('\''); + return text.toString(); + } + + /** + * Return the undo modification stamp + * + * @return the undo modification stamp for this command + * @since 3.1 + */ + protected long getUndoModificationStamp() { + return fUndoModificationStamp; + } + + /** + * Return the redo modification stamp + * + * @return the redo modification stamp for this command + * @since 3.1 + */ + protected long getRedoModificationStamp() { + return fRedoModificationStamp; + } + } + + /** + * Represents an undo-able edit command consisting of several + * individual edit commands. + */ + class CompoundTextCommand : TextCommand { + + /** The list of individual commands */ + private List fCommands; + + /** + * Creates a new compound text command. + * + * @param context the undo context for this command + * @since 3.1 + */ + this(IUndoContext context) { + super(context); + fCommands= new ArrayList(); + } + + /** + * Adds a new individual command to this compound command. + * + * @param command the command to be added + */ + protected void add(TextCommand command) { + fCommands.add(command); + } + + /* + * @see dwtx.jface.text.DefaultUndoManager.TextCommand#undo() + */ + public IStatus undo(IProgressMonitor monitor, IAdaptable uiInfo) { + resetProcessChangeSate(); + + int size= fCommands.size(); + if (size > 0) { + + TextCommand c; + + for (int i= size -1; i > 0; --i) { + c= cast(TextCommand) fCommands.get(i); + c.undoTextChange(); + } + + c= cast(TextCommand) fCommands.get(0); + c.undo(monitor, uiInfo); + } + + return Status.OK_STATUS; + } + + /* + * @see dwtx.jface.text.DefaultUndoManager.TextCommand#redo() + */ + public IStatus redo(IProgressMonitor monitor, IAdaptable uiInfo) { + resetProcessChangeSate(); + + int size= fCommands.size(); + if (size > 0) { + + TextCommand c; + + for (int i= 0; i < size -1; ++i) { + c= cast(TextCommand) fCommands.get(i); + c.redoTextChange(); + } + + c= cast(TextCommand) fCommands.get(size -1); + c.redo(monitor, uiInfo); + } + return Status.OK_STATUS; + } + + /* + * @see TextCommand#updateCommand + + */ + + protected void updateCommand() { + // first gather the data from the buffers + super.updateCommand(); + + // the result of the command update is stored as a child command + TextCommand c= new TextCommand(fUndoContext); + c.fStart= fStart; + c.fEnd= fEnd; + c.fText= fText; + c.fPreservedText= fPreservedText; + c.fUndoModificationStamp= fUndoModificationStamp; + c.fRedoModificationStamp= fRedoModificationStamp; + add(c); + + // clear out all indexes now that the child is added + reinitialize(); + } + + /* + * @see TextCommand#createCurrent + */ + protected TextCommand createCurrent() { + + if (!fFoldingIntoCompoundChange) + return new TextCommand(fUndoContext); + + reinitialize(); + return this; + } + + /* + * @see dwtx.jface.text.DefaultUndoManager.TextCommand#commit() + */ + protected void commit() { + // if there is pending data, update the command + if (fStart > -1) + updateCommand(); + fCurrent= createCurrent(); + resetProcessChangeSate(); + } + + /** + * Checks whether the command is valid for undo or redo. + * + * @return true if the command is valid. + * @since 3.1 + */ + protected bool isValid() { + if (isConnected()) + return (fStart > -1 || fCommands.size() > 0); + return false; + } + + /** + * Returns the undo modification stamp. + * + * @return the undo modification stamp + * @since 3.1 + */ + protected long getUndoModificationStamp() { + if (fStart > -1) + return super.getUndoModificationStamp(); + else if (fCommands.size() > 0) + return (cast(TextCommand)fCommands.get(0)).getUndoModificationStamp(); + + return fUndoModificationStamp; + } + + /** + * Returns the redo modification stamp. + * + * @return the redo modification stamp + * @since 3.1 + */ + protected long getRedoModificationStamp() { + if (fStart > -1) + return super.getRedoModificationStamp(); + else if (fCommands.size() > 0) + return (cast(TextCommand)fCommands.get(fCommands.size()-1)).getRedoModificationStamp(); + + return fRedoModificationStamp; + } + } + + /** + * Internal listener to mouse and key events. + */ + class KeyAndMouseListener : MouseListener, KeyListener { + + /* + * @see MouseListener#mouseDoubleClick + */ + public void mouseDoubleClick(MouseEvent e) { + } + + /* + * If the right mouse button is pressed, the current editing command is closed + * @see MouseListener#mouseDown + */ + public void mouseDown(MouseEvent e) { + if (e.button is 1) + commit(); + } + + /* + * @see MouseListener#mouseUp + */ + public void mouseUp(MouseEvent e) { + } + + /* + * @see KeyListener#keyPressed + */ + public void keyReleased(KeyEvent e) { + } + + /* + * On cursor keys, the current editing command is closed + * @see KeyListener#keyPressed + */ + public void keyPressed(KeyEvent e) { + switch (e.keyCode) { + case DWT.ARROW_UP: + case DWT.ARROW_DOWN: + case DWT.ARROW_LEFT: + case DWT.ARROW_RIGHT: + commit(); + break; + } + } + } + + /** + * Internal listener to document changes. + */ + class DocumentListener : IDocumentListener { + + private String fReplacedText; + + /* + * @see dwtx.jface.text.IDocumentListener#documentAboutToBeChanged(dwtx.jface.text.DocumentEvent) + */ + public void documentAboutToBeChanged(DocumentEvent event) { + try { + fReplacedText= event.getDocument().get(event.getOffset(), event.getLength()); + fPreservedUndoModificationStamp= event.getModificationStamp(); + } catch (BadLocationException x) { + fReplacedText= null; + } + } + + /* + * @see dwtx.jface.text.IDocumentListener#documentChanged(dwtx.jface.text.DocumentEvent) + */ + public void documentChanged(DocumentEvent event) { + fPreservedRedoModificationStamp= event.getModificationStamp(); + + // record the current valid state for the top operation in case it remains the + // top operation but changes state. + IUndoableOperation op= fHistory.getUndoOperation(fUndoContext); + bool wasValid= false; + if (op !is null) + wasValid= op.canUndo(); + // Process the change, providing the before and after timestamps + processChange(event.getOffset(), event.getOffset() + event.getLength(), event.getText(), fReplacedText, fPreservedUndoModificationStamp, fPreservedRedoModificationStamp); + + // now update fCurrent with the latest buffers from the document change. + fCurrent.pretendCommit(); + + if (op is fCurrent) { + // if the document change did not cause a new fCurrent to be created, then we should + // notify the history that the current operation changed if its validity has changed. + if (wasValid !is fCurrent.isValid()) + fHistory.operationChanged(op); + } + else { + // if the change created a new fCurrent that we did not yet add to the + // stack, do so if it's valid and we are not in the middle of a compound change. + if (fCurrent !is fLastAddedCommand && fCurrent.isValid()) { + addToCommandStack(fCurrent); + } + } + } + } + + /** + * Internal text input listener. + */ + class TextInputListener : ITextInputListener { + + /* + * @see dwtx.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument) + */ + public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { + if (oldInput !is null && fDocumentListener !is null) { + oldInput.removeDocumentListener(fDocumentListener); + commit(); + } + } + + /* + * @see dwtx.jface.text.ITextInputListener#inputDocumentChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument) + */ + public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { + if (newInput !is null) { + if (fDocumentListener is null) + fDocumentListener= new DocumentListener(); + newInput.addDocumentListener(fDocumentListener); + } + } + + } + + /* + * @see IOperationHistoryListener + * @since 3.1 + */ + class HistoryListener : IOperationHistoryListener { + private IUndoableOperation fOperation; + + public void historyNotification(OperationHistoryEvent event) { + int type= event.getEventType(); + switch (type) { + case OperationHistoryEvent.ABOUT_TO_UNDO: + case OperationHistoryEvent.ABOUT_TO_REDO: + // if this is one of our operations + if (event.getOperation().hasContext(fUndoContext)) { + fTextViewer.getTextWidget().getDisplay().syncExec(dgRunnable((OperationHistoryEvent event_, int type_ ) { + // if we are undoing/redoing a command we generated, then ignore + // the document changes associated with this undo or redo. + if (event_.getOperation() ) { + if ( cast(TextViewer)fTextViewer ) + (cast(TextViewer)fTextViewer).ignoreAutoEditStrategies_package(true); + listenToTextChanges(false); + + // in the undo case only, make sure compounds are closed + if (type_ is OperationHistoryEvent.ABOUT_TO_UNDO) { + if (fFoldingIntoCompoundChange) { + endCompoundChange(); + } + } + } else { + // the undo or redo has our context, but it is not one of + // our commands. We will listen to the changes, but will + // reset the state that tracks the undo/redo history. + commit(); + fLastAddedCommand= null; + } + }, event, type )); + fOperation= event.getOperation(); + } + break; + case OperationHistoryEvent.UNDONE: + case OperationHistoryEvent.REDONE: + case OperationHistoryEvent.OPERATION_NOT_OK: + if (event.getOperation() is fOperation) { + fTextViewer.getTextWidget().getDisplay().syncExec(new class() Runnable { + public void run() { + listenToTextChanges(true); + fOperation= null; + if ( cast(TextViewer)fTextViewer ) + (cast(TextViewer)fTextViewer).ignoreAutoEditStrategies_package(false); + } + }); + } + break; + } + } + + } + + /** Text buffer to collect text which is inserted into the viewer */ + private StringBuffer fTextBuffer; + /** Text buffer to collect viewer content which has been replaced */ + private StringBuffer fPreservedTextBuffer; + /** The document modification stamp for undo. */ + protected long fPreservedUndoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; + /** The document modification stamp for redo. */ + protected long fPreservedRedoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; + /** The internal key and mouse event listener */ + private KeyAndMouseListener fKeyAndMouseListener; + /** The internal document listener */ + private DocumentListener fDocumentListener; + /** The internal text input listener */ + private TextInputListener fTextInputListener; + + + /** Indicates inserting state */ + private bool fInserting= false; + /** Indicates overwriting state */ + private bool fOverwriting= false; + /** Indicates whether the current change belongs to a compound change */ + private bool fFoldingIntoCompoundChange= false; + + /** The text viewer the undo manager is connected to */ + private ITextViewer fTextViewer; + + /** Supported undo level */ + private int fUndoLevel; + /** The currently constructed edit command */ + private TextCommand fCurrent; + /** The last delete edit command */ + private TextCommand fPreviousDelete; + + /** + * The undo context. + * @since 3.1 + */ + private IOperationHistory fHistory; + /** + * The operation history. + * @since 3.1 + */ + private IUndoContext fUndoContext; + /** + * The operation history listener used for managing undo and redo before + * and after the individual commands are performed. + * @since 3.1 + */ + private IOperationHistoryListener fHistoryListener; + + /** + * The command last added to the operation history. This must be tracked + * internally instead of asking the history, since outside parties may be placing + * items on our undo/redo history. + */ + private TextCommand fLastAddedCommand= null; + + /** + * Creates a new undo manager who remembers the specified number of edit commands. + * + * @param undoLevel the length of this manager's history + */ + public this(int undoLevel) { + fTextBuffer= new StringBuffer(); + fPreservedTextBuffer= new StringBuffer(); + + fHistoryListener= new HistoryListener(); + fHistory= OperationHistoryFactory.getOperationHistory(); + setMaximalUndoLevel(undoLevel); + } + + /** + * Returns whether this undo manager is connected to a text viewer. + * + * @return true if connected, false otherwise + * @since 3.1 + */ + private bool isConnected() { + return fTextViewer !is null; + } + + /* + * @see IUndoManager#beginCompoundChange + */ + public void beginCompoundChange() { + if (isConnected()) { + fFoldingIntoCompoundChange= true; + commit(); + } + } + + + /* + * @see IUndoManager#endCompoundChange + */ + public void endCompoundChange() { + if (isConnected()) { + fFoldingIntoCompoundChange= false; + commit(); + } + } + + /** + * Registers all necessary listeners with the text viewer. + */ + private void addListeners() { + StyledText text= fTextViewer.getTextWidget(); + if (text !is null) { + fKeyAndMouseListener= new KeyAndMouseListener(); + text.addMouseListener(fKeyAndMouseListener); + text.addKeyListener(fKeyAndMouseListener); + fTextInputListener= new TextInputListener(); + fTextViewer.addTextInputListener(fTextInputListener); + fHistory.addOperationHistoryListener(fHistoryListener); + listenToTextChanges(true); + } + } + + /** + * Unregister all previously installed listeners from the text viewer. + */ + private void removeListeners() { + StyledText text= fTextViewer.getTextWidget(); + if (text !is null) { + if (fKeyAndMouseListener !is null) { + text.removeMouseListener(fKeyAndMouseListener); + text.removeKeyListener(fKeyAndMouseListener); + fKeyAndMouseListener= null; + } + if (fTextInputListener !is null) { + fTextViewer.removeTextInputListener(fTextInputListener); + fTextInputListener= null; + } + listenToTextChanges(false); + fHistory.removeOperationHistoryListener(fHistoryListener); + } + } + + /** + * Adds the given command to the operation history if it is not part of + * a compound change. + * + * @param command the command to be added + * @since 3.1 + */ + private void addToCommandStack(TextCommand command){ + if (!fFoldingIntoCompoundChange || cast(CompoundTextCommand)command ) { + fHistory.add(command); + fLastAddedCommand= command; + } + } + + /** + * Disposes the command stack. + * + * @since 3.1 + */ + private void disposeCommandStack() { + fHistory.dispose(fUndoContext, true, true, true); + } + + /** + * Initializes the command stack. + * + * @since 3.1 + */ + private void initializeCommandStack() { + if (fHistory !is null && fUndoContext !is null) + fHistory.dispose(fUndoContext, true, true, false); + + } + + /** + * Switches the state of whether there is a text listener or not. + * + * @param listen the state which should be established + */ + private void listenToTextChanges(bool listen) { + if (listen) { + if (fDocumentListener is null && fTextViewer.getDocument() !is null) { + fDocumentListener= new DocumentListener(); + fTextViewer.getDocument().addDocumentListener(fDocumentListener); + } + } else if (!listen) { + if (fDocumentListener !is null && fTextViewer.getDocument() !is null) { + fTextViewer.getDocument().removeDocumentListener(fDocumentListener); + fDocumentListener= null; + } + } + } + + /** + * Closes the current editing command and opens a new one. + */ + private void commit() { + // if fCurrent has never been placed on the command stack, do so now. + // this can happen when there are multiple programmatically commits in a single + // document change. + if (fLastAddedCommand !is fCurrent) { + fCurrent.pretendCommit(); + if (fCurrent.isValid()) + addToCommandStack(fCurrent); + } + fCurrent.commit(); + } + + /** + * Reset processChange state. + * + * @since 3.2 + */ + private void resetProcessChangeSate() { + fInserting= false; + fOverwriting= false; + fPreviousDelete.reinitialize(); + } + + /** + * Checks whether the given text starts with a line delimiter and + * subsequently contains a white space only. + * + * @param text the text to check + * @return true if the text is a line delimiter followed by whitespace, false otherwise + */ + private bool isWhitespaceText(String text) { + + if (text is null || text.length() is 0) + return false; + + String[] delimiters= fTextViewer.getDocument().getLegalLineDelimiters(); + int index= TextUtilities.startsWith(delimiters, text); + if (index > -1) { + char c; + int length= text.length(); + for (int i= delimiters[index].length; i < length; i++) { + c= text.charAt(i); + if (c !is ' ' && c !is '\t') + return false; + } + return true; + } + + return false; + } + + private void processChange(int modelStart, int modelEnd, String insertedText, String replacedText, long beforeChangeModificationStamp, long afterChangeModificationStamp) { + + if (insertedText is null) + insertedText= ""; //$NON-NLS-1$ + + if (replacedText is null) + replacedText= ""; //$NON-NLS-1$ + + int length= insertedText.length(); + int diff= modelEnd - modelStart; + + if (fCurrent.fUndoModificationStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP) + fCurrent.fUndoModificationStamp= beforeChangeModificationStamp; + + // normalize + if (diff < 0) { + int tmp= modelEnd; + modelEnd= modelStart; + modelStart= tmp; + } + + if (modelStart is modelEnd) { + // text will be inserted + if ((length is 1) || isWhitespaceText(insertedText)) { + // by typing or whitespace + if (!fInserting || (modelStart !is fCurrent.fStart + fTextBuffer.length())) { + fCurrent.fRedoModificationStamp= beforeChangeModificationStamp; + if (fCurrent.attemptCommit()) + fCurrent.fUndoModificationStamp= beforeChangeModificationStamp; + + fInserting= true; + } + if (fCurrent.fStart < 0) + fCurrent.fStart= fCurrent.fEnd= modelStart; + if (length > 0) + fTextBuffer.append(insertedText); + } else if (length >= 0) { + // by pasting or model manipulation + fCurrent.fRedoModificationStamp= beforeChangeModificationStamp; + if (fCurrent.attemptCommit()) + fCurrent.fUndoModificationStamp= beforeChangeModificationStamp; + + fCurrent.fStart= fCurrent.fEnd= modelStart; + fTextBuffer.append(insertedText); + fCurrent.fRedoModificationStamp= afterChangeModificationStamp; + if (fCurrent.attemptCommit()) + fCurrent.fUndoModificationStamp= afterChangeModificationStamp; + + } + } else { + if (length is 0) { + // text will be deleted by backspace or DEL key or empty clipboard + length= replacedText.length; + String[] delimiters= fTextViewer.getDocument().getLegalLineDelimiters(); + + if ((length is 1) || TextUtilities.equals(delimiters, replacedText) > -1) { + + // whereby selection is empty + + if (fPreviousDelete.fStart is modelStart && fPreviousDelete.fEnd is modelEnd) { + // repeated DEL + + // correct wrong settings of fCurrent + if (fCurrent.fStart is modelEnd && fCurrent.fEnd is modelStart) { + fCurrent.fStart= modelStart; + fCurrent.fEnd= modelEnd; + } + // append to buffer && extend command range + fPreservedTextBuffer.append(replacedText); + ++fCurrent.fEnd; + + } else if (fPreviousDelete.fStart is modelEnd) { + // repeated backspace + + // insert in buffer and extend command range + fPreservedTextBuffer.select(0, 0); + fPreservedTextBuffer.replace(replacedText); + fCurrent.fStart= modelStart; + + } else { + // either DEL or backspace for the first time + + fCurrent.fRedoModificationStamp= beforeChangeModificationStamp; + if (fCurrent.attemptCommit()) + fCurrent.fUndoModificationStamp= beforeChangeModificationStamp; + + // as we can not decide whether it was DEL or backspace we initialize for backspace + fPreservedTextBuffer.append(replacedText); + fCurrent.fStart= modelStart; + fCurrent.fEnd= modelEnd; + } + + fPreviousDelete.set(modelStart, modelEnd); + + } else if (length > 0) { + // whereby selection is not empty + fCurrent.fRedoModificationStamp= beforeChangeModificationStamp; + if (fCurrent.attemptCommit()) + fCurrent.fUndoModificationStamp= beforeChangeModificationStamp; + + fCurrent.fStart= modelStart; + fCurrent.fEnd= modelEnd; + fPreservedTextBuffer.append(replacedText); + } + } else { + // text will be replaced + + if (length is 1) { + length= replacedText.length; + String[] delimiters= fTextViewer.getDocument().getLegalLineDelimiters(); + + if ((length is 1) || TextUtilities.equals(delimiters, replacedText) > -1) { + // because of overwrite mode or model manipulation + if (!fOverwriting || (modelStart !is fCurrent.fStart + fTextBuffer.length())) { + fCurrent.fRedoModificationStamp= beforeChangeModificationStamp; + if (fCurrent.attemptCommit()) + fCurrent.fUndoModificationStamp= beforeChangeModificationStamp; + + fOverwriting= true; + } + + if (fCurrent.fStart < 0) + fCurrent.fStart= modelStart; + + fCurrent.fEnd= modelEnd; + fTextBuffer.append(insertedText); + fPreservedTextBuffer.append(replacedText); + fCurrent.fRedoModificationStamp= afterChangeModificationStamp; + return; + } + } + // because of typing or pasting whereby selection is not empty + fCurrent.fRedoModificationStamp= beforeChangeModificationStamp; + if (fCurrent.attemptCommit()) + fCurrent.fUndoModificationStamp= beforeChangeModificationStamp; + + fCurrent.fStart= modelStart; + fCurrent.fEnd= modelEnd; + fTextBuffer.append(insertedText); + fPreservedTextBuffer.append(replacedText); + } + } + // in all cases, the redo modification stamp is updated on the open command + fCurrent.fRedoModificationStamp= afterChangeModificationStamp; + } + + /** + * Shows the given exception in an error dialog. + * + * @param title the dialog title + * @param ex the exception + * @since 3.1 + */ + private void openErrorDialog(String title, Exception ex) { + Shell shell= null; + if (isConnected()) { + StyledText st= fTextViewer.getTextWidget(); + if (st !is null && !st.isDisposed()) + shell= st.getShell(); + } + if (Display.getCurrent() !is null) + MessageDialog.openError(shell, title, ex.msg/+getLocalizedMessage()+/); + else { + Display display; + Shell finalShell= shell; + if (finalShell !is null) + display= finalShell.getDisplay(); + else + display= Display.getDefault(); + display.syncExec(dgRunnable( { + MessageDialog.openError(finalShell, title, ex.msg/+getLocalizedMessage()+/); + })); + } + } + + /* + * @see dwtx.jface.text.IUndoManager#setMaximalUndoLevel(int) + */ + public void setMaximalUndoLevel(int undoLevel) { + fUndoLevel= Math.max(0, undoLevel); + if (isConnected()) { + fHistory.setLimit(fUndoContext, fUndoLevel); + } + } + + /* + * @see dwtx.jface.text.IUndoManager#connect(dwtx.jface.text.ITextViewer) + */ + public void connect(ITextViewer textViewer) { + if (!isConnected() && textViewer !is null) { + fTextViewer= textViewer; + if (fUndoContext is null) + fUndoContext= new ObjectUndoContext(this); + + fHistory.setLimit(fUndoContext, fUndoLevel); + + initializeCommandStack(); + + // open up the current command + fCurrent= new TextCommand(fUndoContext); + + fPreviousDelete= new TextCommand(fUndoContext); + addListeners(); + } + } + + /* + * @see dwtx.jface.text.IUndoManager#disconnect() + */ + public void disconnect() { + if (isConnected()) { + + removeListeners(); + + fCurrent= null; + fTextViewer= null; + disposeCommandStack(); + fTextBuffer.clear(); + fPreservedTextBuffer.clear(); + fUndoContext= null; + } + } + + /* + * @see dwtx.jface.text.IUndoManager#reset() + */ + public void reset() { + if (isConnected()) { + initializeCommandStack(); + fCurrent= new TextCommand(fUndoContext); + fFoldingIntoCompoundChange= false; + fInserting= false; + fOverwriting= false; + fTextBuffer.truncate(0); + fPreservedTextBuffer.truncate(0); + fPreservedUndoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; + fPreservedRedoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; + } + } + + /* + * @see dwtx.jface.text.IUndoManager#redoable() + */ + public bool redoable() { + return fHistory.canRedo(fUndoContext); + } + + /* + * @see dwtx.jface.text.IUndoManager#undoable() + */ + public bool undoable() { + return fHistory.canUndo(fUndoContext); + } + + /* + * @see dwtx.jface.text.IUndoManager#redo() + */ + public void redo() { + if (isConnected() && redoable()) { + try { + fHistory.redo(fUndoContext, null, null); + } catch (ExecutionException ex) { + openErrorDialog(JFaceTextMessages.getString("DefaultUndoManager.error.redoFailed.title"), ex); //$NON-NLS-1$ + } + } + } + + /* + * @see dwtx.jface.text.IUndoManager#undo() + */ + public void undo() { + if (isConnected() && undoable()) { + try { + fHistory.undo(fUndoContext, null, null); + } catch (ExecutionException ex) { + openErrorDialog(JFaceTextMessages.getString("DefaultUndoManager.error.undoFailed.title"), ex); //$NON-NLS-1$ + } + } + } + + /** + * Selects and reveals the specified range. + * + * @param offset the offset of the range + * @param length the length of the range + * @since 3.0 + */ + protected void selectAndReveal(int offset, int length) { + if ( cast(ITextViewerExtension5)fTextViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) fTextViewer; + extension.exposeModelRange(new Region(offset, length)); + } else if (!fTextViewer.overlapsWithVisibleRegion(offset, length)) + fTextViewer.resetVisibleRegion(); + + fTextViewer.setSelectedRange(offset, length); + fTextViewer.revealRange(offset, length); + } + + /* + * @see dwtx.jface.text.IUndoManagerExtension#getUndoContext() + * @since 3.1 + */ + public IUndoContext getUndoContext() { + return fUndoContext; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/Document.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/Document.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,267 @@ +/******************************************************************************* + * 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.text.Document; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Default document implementation. Uses a {@link dwtx.jface.text.GapTextStore} wrapped + * inside a {@link dwtx.jface.text.CopyOnWriteTextStore} as text store. + *

                + * The used line tracker considers the following strings as line delimiters: "\n", "\r", "\r\n". + *

                + *

                + * The document is ready to use. It has a default position category for which a default position + * updater is installed. + *

                + *

                + * Performance: The implementation should perform reasonably well for typical + * source code documents. It is not designed for very large documents of a size of several + * megabytes. Space-saving implementations are initially used for both the text store and the line + * tracker; the first modification after a {@link #set(String) set} incurs the cost to transform the + * document structures to efficiently handle updates. + *

                + *

                + * See {@link GapTextStore} and TreeLineTracker for algorithmic behavior of the used + * document structures. + *

                + * + * @see dwtx.jface.text.GapTextStore + * @see dwtx.jface.text.CopyOnWriteTextStore + */ +public class Document : AbstractDocument { + /** + * Creates a new empty document. + */ + public this() { + super(); + setTextStore(new CopyOnWriteTextStore(new GapTextStore())); + setLineTracker(new DefaultLineTracker()); + completeInitialization(); + } + + /** + * Creates a new document with the given initial content. + * + * @param initialContent the document's initial content + */ + public this(String initialContent) { + super(); + setTextStore(new CopyOnWriteTextStore(new GapTextStore())); + setLineTracker(new DefaultLineTracker()); + getStore().set(initialContent); + getTracker().set(initialContent); + completeInitialization(); + } + + /* + * @see dwtx.jface.text.IRepairableDocumentExtension#isLineInformationRepairNeeded(int, int, java.lang.String) + * @since 3.4 + */ + public bool isLineInformationRepairNeeded(int offset, int length, String text) { + if ((0 > offset) || (0 > length) || (offset + length > getLength())) + throw new BadLocationException(); + + return isLineInformationRepairNeeded(text) || isLineInformationRepairNeeded(get(offset, length)); + } + + /** + * Checks whether the line information needs to be repaired. + * + * @param text the text to check + * @return true if the line information must be repaired + * @since 3.4 + */ + private bool isLineInformationRepairNeeded(String text) { + if (text is null) + return false; + + int length= text.length(); + if (length is 0) + return false; + + int rIndex= text.indexOf('\r'); + int nIndex= text.indexOf('\n'); + if (rIndex is -1 && nIndex is -1) + return false; + + if (rIndex > 0 && rIndex < length-1 && nIndex > 1 && rIndex < length-2) + return false; + + String defaultLD= null; + try { + defaultLD= getLineDelimiter(0); + } catch (BadLocationException x) { + return true; + } + + if (defaultLD is null) + return false; + + defaultLD= getDefaultLineDelimiter(); + + if (defaultLD.length is 1) { + if (rIndex !is -1 && !"\r".equals(defaultLD)) //$NON-NLS-1$ + return true; + if (nIndex !is -1 && !"\n".equals(defaultLD)) //$NON-NLS-1$ + return true; + } else if (defaultLD.length is 2) + return rIndex is -1 || nIndex - rIndex !is 1; + + return false; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/DocumentClone.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/DocumentClone.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,232 @@ +/******************************************************************************* + * 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 + * 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.text.DocumentClone; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.core.runtime.Assert; + + +/** + * An {@link dwtx.jface.text.IDocument} that is a read-only clone of another document. + * + * @since 3.0 + */ +class DocumentClone : AbstractDocument { + + private static class StringTextStore : ITextStore { + + private String fContent; + + /** + * Creates a new string text store with the given content. + * + * @param content the content + */ + public this(String content) { + //Assert.isNotNull(content); + fContent= content; + } + + /* + * @see dwtx.jface.text.ITextStore#get(int) + */ + public char get(int offset) { + return fContent.charAt(offset); + } + + /* + * @see dwtx.jface.text.ITextStore#get(int, int) + */ + public String get(int offset, int length) { + return fContent.substring(offset, offset + length); + } + + /* + * @see dwtx.jface.text.ITextStore#getLength() + */ + public int getLength() { + return fContent.length(); + } + + /* + * @see dwtx.jface.text.ITextStore#replace(int, int, java.lang.String) + */ + public void replace(int offset, int length, String text) { + } + + /* + * @see dwtx.jface.text.ITextStore#set(java.lang.String) + */ + public void set(String text) { + } + + } + + /** + * Creates a new document clone with the given content. + * + * @param content the content + * @param lineDelimiters the line delimiters + */ + public this(String content, String[] lineDelimiters) { + super(); + setTextStore(new StringTextStore(content)); + ConfigurableLineTracker tracker= new ConfigurableLineTracker(lineDelimiters); + setLineTracker(tracker); + getTracker().set(content); + completeInitialization(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/DocumentCommand.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/DocumentCommand.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,478 @@ +/******************************************************************************* + * 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.text.DocumentCommand; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; +import tango.core.Exception; + +import dwt.events.VerifyEvent; +import dwtx.core.runtime.Assert; + + +/** + * Represents a text modification as a document replace command. The text + * modification is given as a {@link dwt.events.VerifyEvent} and + * translated into a document replace command relative to a given offset. A + * document command can also be used to initialize a given + * VerifyEvent. + *

                + * A document command can also represent a list of related changes.

                + */ +public class DocumentCommand { + + /** + * A command which is added to document commands. + * @since 2.1 + */ + private static class Command : Comparable { + /** The offset of the range to be replaced */ + private const int fOffset; + /** The length of the range to be replaced. */ + private const int fLength; + /** The replacement text */ + private const String fText; + /** The listener who owns this command */ + private const IDocumentListener fOwner; + + /** + * Creates a new command with the given specification. + * + * @param offset the offset of the replace command + * @param length the length of the replace command + * @param text the text to replace with, may be null + * @param owner the document command owner, may be null + * @since 3.0 + */ + public this(int offset, int length, String text, IDocumentListener owner) { + if (offset < 0 || length < 0) + throw new IllegalArgumentException(null); + fOffset= offset; + fLength= length; + fText= text; + fOwner= owner; + } + + /** + * Returns the length delta for this command. + * + * @return the length delta for this command + */ + public int getDeltaLength() { + return (fText is null ? 0 : fText.length) - fLength; + } + + /** + * Executes the document command on the specified document. + * + * @param document the document on which to execute the command. + * @throws BadLocationException in case this commands cannot be executed + */ + public void execute(IDocument document) { + + if (fLength is 0 && fText is null) + return; + + if (fOwner !is null) + document.removeDocumentListener(fOwner); + + document.replace(fOffset, fLength, fText); + + if (fOwner !is null) + document.addDocumentListener(fOwner); + } + + /* + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + public int compareTo(Object object) { + if (isEqual(object)) + return 0; + + final Command command= cast(Command) object; + + // diff middle points if not intersecting + if (fOffset + fLength <= command.fOffset || command.fOffset + command.fLength <= fOffset) { + int value= (2 * fOffset + fLength) - (2 * command.fOffset + command.fLength); + if (value !is 0) + return value; + } + // the answer + return 42; + } + + private bool isEqual(Object object) { + if (object is this) + return true; + if (!( cast(Command)object )) + return false; + final Command command= cast(Command) object; + return command.fOffset is fOffset && command.fLength is fLength; + } + } + + /** + * An iterator, which iterates in reverse over a list. + */ + private static class ReverseListIterator : Iterator { + + /** The list iterator. */ + private const ListIterator fListIterator; + + /** + * Creates a reverse list iterator. + * @param listIterator the iterator that this reverse iterator is based upon + */ + public this(ListIterator listIterator) { + if (listIterator is null) + throw new IllegalArgumentException(null); + fListIterator= listIterator; + } + + /* + * @see java.util.Iterator#hasNext() + */ + public bool hasNext() { + return fListIterator.hasPrevious(); + } + + /* + * @see java.util.Iterator#next() + */ + public Object next() { + return fListIterator.previous(); + } + + /* + * @see java.util.Iterator#remove() + */ + public void remove() { + throw new UnsupportedOperationException(); + } + } + + /** + * A command iterator. + */ + private static class CommandIterator : Iterator { + + /** The command iterator. */ + private const Iterator fIterator; + + /** The original command. */ + private Command fCommand; + + /** A flag indicating the direction of iteration. */ + private bool fForward; + + /** + * Creates a command iterator. + * + * @param commands an ascending ordered list of commands + * @param command the original command + * @param forward the direction + */ + public this(List commands, Command command, bool forward) { + if (commands is null || command is null) + throw new IllegalArgumentException(null); + fIterator= forward ? commands.iterator() : new ReverseListIterator(commands.listIterator(commands.size())); + fCommand= command; + fForward= forward; + } + + /* + * @see java.util.Iterator#hasNext() + */ + public bool hasNext() { + return fCommand !is null || fIterator.hasNext(); + } + + /* + * @see java.util.Iterator#next() + */ + public Object next() { + + if (!hasNext()) + throw new NoSuchElementException(null); + + if (fCommand is null) + return fIterator.next(); + + if (!fIterator.hasNext()) { + final Command tempCommand= fCommand; + fCommand= null; + return tempCommand; + } + + final Command command= cast(Command) fIterator.next(); + final int compareValue= command.compareTo(fCommand); + + if ((compareValue < 0) ^ !fForward) { + return command; + + } else if ((compareValue > 0) ^ !fForward) { + final Command tempCommand= fCommand; + fCommand= command; + return tempCommand; + + } else { + throw new IllegalArgumentException(null); + } + } + + /* + * @see java.util.Iterator#remove() + */ + public void remove() { + throw new UnsupportedOperationException(); + } + } + + /** Must the command be updated */ + public bool doit= false; + /** The offset of the command. */ + public int offset; + /** The length of the command */ + public int length; + /** The text to be inserted */ + public String text; + /** + * The owner of the document command which will not be notified. + * @since 2.1 + */ + public IDocumentListener owner; + /** + * The caret offset with respect to the document before the document command is executed. + * @since 2.1 + */ + public int caretOffset; + /** + * Additional document commands. + * @since 2.1 + */ + private const List fCommands; + /** + * Indicates whether the caret should be shifted by this command. + * @since 3.0 + */ + public bool shiftsCaret; + + + /** + * Creates a new document command. + */ + /+protected+/ this() { + fCommands= new ArrayList(); + } + + /** + * Translates a verify event into a document replace command using the given offset. + * + * @param event the event to be translated + * @param modelRange the event range as model range + */ + void setEvent(VerifyEvent event, IRegion modelRange) { + + doit= true; + text= event.text; + + offset= modelRange.getOffset(); + length= modelRange.getLength(); + + owner= null; + caretOffset= -1; + shiftsCaret= true; + fCommands.clear(); + } + + /** + * Fills the given verify event with the replace text and the doit + * flag of this document command. Returns whether the document command + * covers the same range as the verify event considering the given offset. + * + * @param event the event to be changed + * @param modelRange to be considered for range comparison + * @return true if this command and the event cover the same range + */ + bool fillEvent(VerifyEvent event, IRegion modelRange) { + event.text= text; + event.doit= (offset is modelRange.getOffset() && length is modelRange.getLength() && doit && caretOffset is -1); + return event.doit; + } + + /** + * Adds an additional replace command. The added replace command must not overlap + * with existing ones. If the document command owner is not null, it will not + * get document change notifications for the particular command. + * + * @param commandOffset the offset of the region to replace + * @param commandLength the length of the region to replace + * @param commandText the text to replace with, may be null + * @param commandOwner the command owner, may be null + * @throws BadLocationException if the added command intersects with an existing one + * @since 2.1 + */ + public void addCommand(int commandOffset, int commandLength, String commandText, IDocumentListener commandOwner) { + final Command command= new Command(commandOffset, commandLength, commandText, commandOwner); + + if (intersects(command)) + throw new BadLocationException(); + + final int index= Collections.binarySearch(fCommands, command); + + // a command with exactly the same ranges exists already + if (index >= 0) + throw new BadLocationException(); + + // binary search result is defined as (-(insertionIndex) - 1) + final int insertionIndex= -(index + 1); + + // overlaps to the right? + if (insertionIndex !is fCommands.size() && intersects(cast(Command) fCommands.get(insertionIndex), command)) + throw new BadLocationException(); + + // overlaps to the left? + if (insertionIndex !is 0 && intersects(cast(Command) fCommands.get(insertionIndex - 1), command)) + throw new BadLocationException(); + + fCommands.add(insertionIndex, command); + } + + /** + * Returns an iterator over the commands in ascending position order. + * The iterator includes the original document command. + * Commands cannot be removed. + * + * @return returns the command iterator + */ + public Iterator getCommandIterator() { + Command command= new Command(offset, length, text, owner); + return new CommandIterator(fCommands, command, true); + } + + /** + * Returns the number of commands including the original document command. + * + * @return returns the number of commands + * @since 2.1 + */ + public int getCommandCount() { + return 1 + fCommands.size(); + } + + /** + * Returns whether the two given commands intersect. + * + * @param command0 the first command + * @param command1 the second command + * @return true if the commands intersect + * @since 2.1 + */ + private bool intersects(Command command0, Command command1) { + // diff middle points if not intersecting + if (command0.fOffset + command0.fLength <= command1.fOffset || command1.fOffset + command1.fLength <= command0.fOffset) + return (2 * command0.fOffset + command0.fLength) - (2 * command1.fOffset + command1.fLength) is 0; + return true; + } + + /** + * Returns whether the given command intersects with this command. + * + * @param command the command + * @return true if the command intersects with this command + * @since 2.1 + */ + private bool intersects(Command command) { + // diff middle points if not intersecting + if (offset + length <= command.fOffset || command.fOffset + command.fLength <= offset) + return (2 * offset + length) - (2 * command.fOffset + command.fLength) is 0; + return true; + } + + /** + * Executes the document commands on a document. + * + * @param document the document on which to execute the commands + * @throws BadLocationException in case access to the given document fails + * @since 2.1 + */ + void execute(IDocument document) { + + if (length is 0 && text is null && fCommands.size() is 0) + return; + + DefaultPositionUpdater updater= new DefaultPositionUpdater(getCategory()); + Position caretPosition= null; + try { + if (updateCaret()) { + document.addPositionCategory(getCategory()); + document.addPositionUpdater(updater); + caretPosition= new Position(caretOffset); + document.addPosition(getCategory(), caretPosition); + } + + final Command originalCommand= new Command(offset, length, text, owner); + for (final Iterator iterator= new CommandIterator(fCommands, originalCommand, false); iterator.hasNext(); ) + (cast(Command) iterator.next()).execute(document); + + } catch (BadLocationException e) { + // ignore + } catch (BadPositionCategoryException e) { + // ignore + } finally { + delegate(){ + if (updateCaret()) { + document.removePositionUpdater(updater); + try { + document.removePositionCategory(getCategory()); + } catch (BadPositionCategoryException e) { + Assert.isTrue(false); + } + caretOffset= caretPosition.getOffset(); + } + }(); + } + } + + /** + * Returns true if the caret offset should be updated, false otherwise. + * + * @return true if the caret offset should be updated, false otherwise + * @since 3.0 + */ + private bool updateCaret() { + return shiftsCaret && caretOffset !is -1; + } + + /** + * Returns the position category for the caret offset position. + * + * @return the position category for the caret offset position + * @since 3.0 + */ + private String getCategory() { + return toString(); + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/DocumentEvent.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/DocumentEvent.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,303 @@ +/******************************************************************************* + * 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 + * 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.text.DocumentEvent; + +// import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +// import dwtx.jface.text.DefaultTextHover; // packageimport +// import dwtx.jface.text.AbstractInformationControl; // packageimport +// import dwtx.jface.text.TextUtilities; // packageimport +// import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +// import dwtx.jface.text.AbstractInformationControlManager; // packageimport +// import dwtx.jface.text.ITextViewerExtension2; // packageimport +// import dwtx.jface.text.IDocumentPartitioner; // packageimport +// import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +// import dwtx.jface.text.ITextSelection; // packageimport +// import dwtx.jface.text.Document; // packageimport +// import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +// import dwtx.jface.text.ITextListener; // packageimport +// import dwtx.jface.text.BadPartitioningException; // packageimport +// import dwtx.jface.text.ITextViewerExtension5; // packageimport +// import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +// import dwtx.jface.text.IUndoManager; // packageimport +// import dwtx.jface.text.ITextHoverExtension2; // packageimport +// import dwtx.jface.text.IRepairableDocument; // packageimport +// import dwtx.jface.text.IRewriteTarget; // packageimport +// import dwtx.jface.text.DefaultPositionUpdater; // packageimport +// import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +// import dwtx.jface.text.TextViewerHoverManager; // packageimport +// import dwtx.jface.text.DocumentRewriteSession; // packageimport +// import dwtx.jface.text.TextViewer; // packageimport +// import dwtx.jface.text.ITextViewerExtension8; // packageimport +// import dwtx.jface.text.RegExMessages; // packageimport +// import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +// import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +// import dwtx.jface.text.IWidgetTokenOwner; // packageimport +// import dwtx.jface.text.IViewportListener; // packageimport +// import dwtx.jface.text.GapTextStore; // packageimport +// import dwtx.jface.text.MarkSelection; // packageimport +// import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +// import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +// import dwtx.jface.text.IInformationControlExtension; // packageimport +// import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +// import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +// import dwtx.jface.text.ITextViewerExtension3; // packageimport +// import dwtx.jface.text.IInformationControlCreator; // packageimport +// import dwtx.jface.text.TypedRegion; // packageimport +// import dwtx.jface.text.ISynchronizable; // packageimport +// import dwtx.jface.text.IMarkRegionTarget; // packageimport +// import dwtx.jface.text.TextViewerUndoManager; // packageimport +// import dwtx.jface.text.IRegion; // packageimport +// import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +// import dwtx.jface.text.IDocumentExtension2; // packageimport +// import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +// import dwtx.jface.text.Assert; // packageimport +// import dwtx.jface.text.DefaultInformationControl; // packageimport +// import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +// import dwtx.jface.text.DocumentClone; // packageimport +// import dwtx.jface.text.DefaultUndoManager; // packageimport +// import dwtx.jface.text.IFindReplaceTarget; // packageimport +// import dwtx.jface.text.IAutoEditStrategy; // packageimport +// import dwtx.jface.text.ILineTrackerExtension; // packageimport +// import dwtx.jface.text.IUndoManagerExtension; // packageimport +// import dwtx.jface.text.TextSelection; // packageimport +// import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +// import dwtx.jface.text.IAutoIndentStrategy; // packageimport +// import dwtx.jface.text.IPainter; // packageimport +// import dwtx.jface.text.IInformationControl; // packageimport +// import dwtx.jface.text.IInformationControlExtension3; // packageimport +// import dwtx.jface.text.ITextViewerExtension6; // packageimport +// import dwtx.jface.text.IInformationControlExtension4; // packageimport +// import dwtx.jface.text.DefaultLineTracker; // packageimport +// import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +// import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +// import dwtx.jface.text.ITextHover; // packageimport +// import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +// import dwtx.jface.text.ILineTracker; // packageimport +// import dwtx.jface.text.Line; // packageimport +// import dwtx.jface.text.ITextViewerExtension; // packageimport +// import dwtx.jface.text.IDocumentAdapter; // packageimport +// import dwtx.jface.text.TextEvent; // packageimport +// import dwtx.jface.text.BadLocationException; // packageimport +// import dwtx.jface.text.AbstractDocument; // packageimport +// import dwtx.jface.text.AbstractLineTracker; // packageimport +// import dwtx.jface.text.TreeLineTracker; // packageimport +// import dwtx.jface.text.ITextPresentationListener; // packageimport +// import dwtx.jface.text.Region; // packageimport +// import dwtx.jface.text.ITextViewer; // packageimport +// import dwtx.jface.text.IDocumentInformationMapping; // packageimport +// import dwtx.jface.text.MarginPainter; // packageimport +// import dwtx.jface.text.IPaintPositionManager; // packageimport +// import dwtx.jface.text.TextPresentation; // packageimport +// import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +// import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +// import dwtx.jface.text.ISelectionValidator; // packageimport +// import dwtx.jface.text.IDocumentExtension; // packageimport +// import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +// import dwtx.jface.text.ConfigurableLineTracker; // packageimport +// import dwtx.jface.text.SlaveDocumentEvent; // packageimport +// import dwtx.jface.text.IDocumentListener; // packageimport +// import dwtx.jface.text.PaintManager; // packageimport +// import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +// import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +// import dwtx.jface.text.IDocumentExtension3; // packageimport +// import dwtx.jface.text.Position; // packageimport +// import dwtx.jface.text.TextMessages; // packageimport +// import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +// import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +// import dwtx.jface.text.IPositionUpdater; // packageimport +// import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +// import dwtx.jface.text.ListLineTracker; // packageimport +// import dwtx.jface.text.ITextInputListener; // packageimport +// import dwtx.jface.text.BadPositionCategoryException; // packageimport +// import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +// import dwtx.jface.text.IInputChangedListener; // packageimport +// import dwtx.jface.text.ITextOperationTarget; // packageimport +// import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +// import dwtx.jface.text.ITextViewerExtension7; // packageimport +// import dwtx.jface.text.IInformationControlExtension5; // packageimport +// import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +// import dwtx.jface.text.JFaceTextUtil; // packageimport +// import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +// import dwtx.jface.text.TabsToSpacesConverter; // packageimport +// import dwtx.jface.text.CursorLinePainter; // packageimport +// import dwtx.jface.text.ITextHoverExtension; // packageimport +// import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +// import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +// import dwtx.jface.text.DocumentCommand; // packageimport +// import dwtx.jface.text.TypedPosition; // packageimport +// import dwtx.jface.text.IEditingSupportRegistry; // packageimport +// import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +// import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +// import dwtx.jface.text.IEditingSupport; // packageimport +// import dwtx.jface.text.IMarkSelection; // packageimport +// import dwtx.jface.text.ISlaveDocumentManager; // packageimport +// import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +// import dwtx.jface.text.ITextStore; // packageimport +// import dwtx.jface.text.JFaceTextMessages; // packageimport +// import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +// import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +// import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +// import dwtx.jface.text.TextAttribute; // packageimport +// import dwtx.jface.text.ITextViewerExtension4; // packageimport +// import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + +import dwtx.core.runtime.Assert; + + +/** + * Specification of changes applied to documents. All changes are represented as + * replace commands, i.e. specifying a document range whose text gets replaced + * with different text. In addition to this information, the event also contains + * the changed document. + * + * @see dwtx.jface.text.IDocument + */ +public class DocumentEvent { + + /** + * Debug option for asserting that text is not null. + * If the dwtx.text/debug/DocumentEvent/assertTextNotNull + * system property is true + * + * @since 3.3 + */ + private static bool ASSERT_TEXT_NOT_NULL_init = false; + private static bool ASSERT_TEXT_NOT_NULL_; + private static bool ASSERT_TEXT_NOT_NULL(){ + if( !ASSERT_TEXT_NOT_NULL_init ){ + ASSERT_TEXT_NOT_NULL_init = true; + ASSERT_TEXT_NOT_NULL_= Boolean.getBoolean("dwtx.text/debug/DocumentEvent/assertTextNotNull"); //$NON-NLS-1$ + } + return ASSERT_TEXT_NOT_NULL_; + } + + /** The changed document */ + public IDocument fDocument; + /** The document offset */ + public int fOffset; + /** Length of the replaced document text */ + public int fLength; + /** Text inserted into the document */ + public String fText= ""; //$NON-NLS-1$ + /** + * The modification stamp of the document when firing this event. + * @since 3.1 and public since 3.3 + */ + public long fModificationStamp; + + /** + * Creates a new document event. + * + * @param doc the changed document + * @param offset the offset of the replaced text + * @param length the length of the replaced text + * @param text the substitution text + */ + public this(IDocument doc, int offset, int length, String text) { + + Assert.isNotNull(cast(Object)doc); + Assert.isTrue(offset >= 0); + Assert.isTrue(length >= 0); + + if (ASSERT_TEXT_NOT_NULL) + Assert.isNotNull(text); + + fDocument= doc; + fOffset= offset; + fLength= length; + fText= text; + + if ( cast(IDocumentExtension4)fDocument ) + fModificationStamp= (cast(IDocumentExtension4)fDocument).getModificationStamp(); + else + fModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; + } + + /** + * Creates a new, not initialized document event. + */ + public this() { + } + + /** + * Returns the changed document. + * + * @return the changed document + */ + public IDocument getDocument() { + return fDocument; + } + + /** + * Returns the offset of the change. + * + * @return the offset of the change + */ + public int getOffset() { + return fOffset; + } + + /** + * Returns the length of the replaced text. + * + * @return the length of the replaced text + */ + public int getLength() { + return fLength; + } + + /** + * Returns the text that has been inserted. + * + * @return the text that has been inserted + */ + public String getText() { + return fText; + } + + /** + * Returns the document's modification stamp at the + * time when this event was sent. + * + * @return the modification stamp or {@link IDocumentExtension4#UNKNOWN_MODIFICATION_STAMP}. + * @see IDocumentExtension4#getModificationStamp() + * @since 3.1 + */ + public long getModificationStamp() { + return fModificationStamp; + } + + /* + * @see java.lang.Object#toString() + * @since 3.4 + */ + public override String toString() { + StringBuffer buffer= new StringBuffer(); + buffer.append("offset: " ); //$NON-NLS-1$ + buffer.append(fOffset); + buffer.append(", length: " ); //$NON-NLS-1$ + buffer.append(fLength); + buffer.append(", timestamp: " ); //$NON-NLS-1$ + buffer.append(fModificationStamp); + buffer.append("\ntext:>" ); //$NON-NLS-1$ + buffer.append(fText); + buffer.append("<\n" ); //$NON-NLS-1$ + return buffer.toString(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/DocumentPartitioningChangedEvent.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/DocumentPartitioningChangedEvent.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,267 @@ +/******************************************************************************* + * 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 + * 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.text.DocumentPartitioningChangedEvent; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + +import dwtx.core.runtime.Assert; + +/** + * Event describing the change of document partitionings. + * + * @see dwtx.jface.text.IDocumentExtension3 + * @since 3.0 + */ +public class DocumentPartitioningChangedEvent { + + /** The document whose partitionings changed */ + private const IDocument fDocument; + /** The map of partitionings to changed regions. */ + private const Map fMap; + + + /** + * Creates a new document partitioning changed event for the given document. + * Initially this event is empty, i.e. does not describe any change. + * + * @param document the changed document + */ + public this(IDocument document) { + fMap= new HashMap(); + fDocument= document; + } + + /** + * Returns the changed document. + * + * @return the changed document + */ + public IDocument getDocument() { + return fDocument; + } + + /** + * Returns the changed region of the given partitioning or null + * if the given partitioning did not change. + * + * @param partitioning the partitioning + * @return the changed region of the given partitioning or null + */ + public IRegion getChangedRegion(String partitioning) { + return cast(IRegion) fMap.get(partitioning); + } + + /** + * Returns the set of changed partitionings. + * + * @return the set of changed partitionings + */ + public String[] getChangedPartitionings() { + return stringcast(fMap.keySet().toArray()); + } + + /** + * Sets the specified range as changed region for the given partitioning. + * + * @param partitioning the partitioning + * @param offset the region offset + * @param length the region length + */ + public void setPartitionChange(String partitioning, int offset, int length) { + //Assert.isNotNull(partitioning); + fMap.put(partitioning, new Region(offset, length)); + } + + /** + * Returns true if the set of changed partitionings is empty, + * false otherwise. + * + * @return true if the set of changed partitionings is empty + */ + public bool isEmpty() { + return fMap.isEmpty(); + } + + /** + * Returns the coverage of this event. This is the minimal region that + * contains all changed regions of all changed partitionings. + * + * @return the coverage of this event + */ + public IRegion getCoverage() { + if (fMap.isEmpty()) + return new Region(0, 0); + + int offset= -1; + int endOffset= -1; + Iterator e= fMap.values().iterator(); + while (e.hasNext()) { + IRegion r= cast(IRegion) e.next(); + + if (offset < 0 || r.getOffset() < offset) + offset= r.getOffset(); + + int end= r.getOffset() + r.getLength(); + if (end > endOffset) + endOffset= end; + } + + return new Region(offset, endOffset - offset); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/DocumentRewriteSession.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/DocumentRewriteSession.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,197 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.DocumentRewriteSession; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * A document rewrite session. + * + * @see dwtx.jface.text.IDocument + * @see dwtx.jface.text.IDocumentExtension4 + * @see dwtx.jface.text.IDocumentRewriteSessionListener + * @since 3.1 + */ +public class DocumentRewriteSession { + + private DocumentRewriteSessionType fSessionType; + + /** + * Prohibit package external object creation. + * + * @param sessionType the type of this session + */ + /+protected+/ this(DocumentRewriteSessionType sessionType) { + fSessionType= sessionType; + } + + /** + * Returns the type of this session. + * + * @return the type of this session + */ + public DocumentRewriteSessionType getSessionType() { + return fSessionType; + } + + /* + * @see java.lang.Object#toString() + */ + public override String toString() { + static assert( hash_t.sizeof is 4 ); + return (new StringBuffer()).append(Integer.toString(toHash())).toString(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/DocumentRewriteSessionEvent.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/DocumentRewriteSessionEvent.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,247 @@ +/******************************************************************************* + * 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 + * 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.text.DocumentRewriteSessionEvent; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.core.runtime.Assert; + + +/** + * Description of the state of document rewrite sessions. + * + * @see dwtx.jface.text.IDocument + * @see dwtx.jface.text.IDocumentExtension4 + * @see dwtx.jface.text.IDocumentRewriteSessionListener + * @since 3.1 + */ +public class DocumentRewriteSessionEvent { + + private static Object SESSION_START_; + public static Object SESSION_START(){ + if( SESSION_START_ is null ){ + synchronized(DocumentRewriteSessionEvent.classinfo){ + if( SESSION_START_ is null ){ + SESSION_START_ = new Object(); + } + } + } + return SESSION_START_; + } + private static Object SESSION_STOP_; + public static Object SESSION_STOP(){ + if( SESSION_STOP_ is null ){ + synchronized(DocumentRewriteSessionEvent.classinfo){ + if( SESSION_STOP_ is null ){ + SESSION_STOP_ = new Object(); + } + } + } + return SESSION_STOP_; + } + + /** The changed document */ + public IDocument fDocument; + /** The session */ + public DocumentRewriteSession fSession; + /** The change type */ + public Object fChangeType; + + /** + * Creates a new document event. + * + * @param doc the changed document + * @param session the session + * @param changeType the change type. This is either + * {@link DocumentRewriteSessionEvent#SESSION_START} or + * {@link DocumentRewriteSessionEvent#SESSION_STOP}. + */ + public this(IDocument doc, DocumentRewriteSession session, Object changeType) { + Assert.isNotNull(cast(Object)doc); + Assert.isNotNull(session); + + fDocument= doc; + fSession= session; + fChangeType= changeType; + } + + /** + * Returns the changed document. + * + * @return the changed document + */ + public IDocument getDocument() { + return fDocument; + } + + /** + * Returns the change type of this event. This is either + * {@link DocumentRewriteSessionEvent#SESSION_START}or + * {@link DocumentRewriteSessionEvent#SESSION_STOP}. + * + * @return the change type of this event + */ + public Object getChangeType() { + return fChangeType; + } + + /** + * Returns the rewrite session. + * + * @return the rewrite session + */ + public DocumentRewriteSession getSession() { + return fSession; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/DocumentRewriteSessionType.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/DocumentRewriteSessionType.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,73 @@ +/******************************************************************************* + * 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 + * 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.text.DocumentRewriteSessionType; + +import dwt.dwthelper.utils; + +/** + * A document rewrite session type. + *

                + * Allowed values are: + *

                  + *
                • {@link DocumentRewriteSessionType#UNRESTRICTED}
                • + *
                • {@link DocumentRewriteSessionType#UNRESTRICTED_SMALL} (since 3.3)
                • + *
                • {@link DocumentRewriteSessionType#SEQUENTIAL}
                • + *
                • {@link DocumentRewriteSessionType#STRICTLY_SEQUENTIAL}
                • + *
                + *

                + * + * @see dwtx.jface.text.IDocument + * @see dwtx.jface.text.IDocumentExtension4 + * @see dwtx.jface.text.IDocumentRewriteSessionListener + * @since 3.1 + */ +public class DocumentRewriteSessionType { + + static this(){ + UNRESTRICTED= new DocumentRewriteSessionType(); + UNRESTRICTED_SMALL= new DocumentRewriteSessionType(); + SEQUENTIAL= new DocumentRewriteSessionType(); + STRICTLY_SEQUENTIAL= new DocumentRewriteSessionType(); + } + + /** + * An unrestricted rewrite session is a sequence of unrestricted replace operations. This + * session type should only be used for large operations that touch more than about + * fifty lines. Use {@link #UNRESTRICTED_SMALL} for small operations. + */ + public const static DocumentRewriteSessionType UNRESTRICTED; + /** + * An small unrestricted rewrite session is a short sequence of unrestricted replace operations. + * This should be used for changes that touch less than about fifty lines. + * + * @since 3.3 + */ + public const static DocumentRewriteSessionType UNRESTRICTED_SMALL; + /** + * A sequential rewrite session is a sequence of non-overlapping replace + * operations starting at an arbitrary document offset. + */ + public const static DocumentRewriteSessionType SEQUENTIAL; + /** + * A strictly sequential rewrite session is a sequence of non-overlapping + * replace operations from the start of the document to its end. + */ + public const static DocumentRewriteSessionType STRICTLY_SEQUENTIAL; + + + /** + * Prohibit external object creation. + */ + private this() { + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/FindReplaceDocumentAdapter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/FindReplaceDocumentAdapter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,822 @@ +/******************************************************************************* + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Cagatay Calli - [find/replace] retain caps when replacing - https://bugs.eclipse.org/bugs/show_bug.cgi?id=28949 + * Cagatay Calli - [find/replace] define & fix behavior of retain caps with other escapes and text before \C - https://bugs.eclipse.org/bugs/show_bug.cgi?id=217061 + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.text.FindReplaceDocumentAdapter; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.regex; + +import dwtx.core.runtime.Assert; + + +/** + * Provides search and replace operations on + * {@link dwtx.jface.text.IDocument}. + *

                + * Replaces + * {@link dwtx.jface.text.IDocument#search(int, String, bool, bool, bool)}. + * + * @since 3.0 + */ +public class FindReplaceDocumentAdapter : CharSequence { + + /** + * Internal type for operation codes. + */ + private static class FindReplaceOperationCode { + } + + // Find/replace operation codes. + private static FindReplaceOperationCode FIND_FIRST_; + private static FindReplaceOperationCode FIND_FIRST(){ + if( FIND_FIRST_ is null ){ + synchronized( FindReplaceDocumentAdapter.classinfo ){ + if( FIND_FIRST_ is null ){ + FIND_FIRST_ = new FindReplaceOperationCode(); + } + } + } + return FIND_FIRST_; + } + + private static FindReplaceOperationCode FIND_NEXT_; + private static FindReplaceOperationCode FIND_NEXT(){ + if( FIND_NEXT_ is null ){ + synchronized( FindReplaceDocumentAdapter.classinfo ){ + if( FIND_NEXT_ is null ){ + FIND_NEXT_ = new FindReplaceOperationCode(); + } + } + } + return FIND_NEXT_; + } + private static FindReplaceOperationCode REPLACE_; + private static FindReplaceOperationCode REPLACE(){ + if( REPLACE_ is null ){ + synchronized( FindReplaceDocumentAdapter.classinfo ){ + if( REPLACE_ is null ){ + REPLACE_ = new FindReplaceOperationCode(); + } + } + } + return REPLACE_; + } + private static FindReplaceOperationCode REPLACE_FIND_NEXT_; + private static FindReplaceOperationCode REPLACE_FIND_NEXT(){ + if( REPLACE_FIND_NEXT_ is null ){ + synchronized( FindReplaceDocumentAdapter.classinfo ){ + if( REPLACE_FIND_NEXT_ is null ){ + REPLACE_FIND_NEXT_ = new FindReplaceOperationCode(); + } + } + } + return REPLACE_FIND_NEXT_; + } + + /** + * Retain case mode constants. + * @since 3.4 + */ + private static const int RC_MIXED= 0; + private static const int RC_UPPER= 1; + private static const int RC_LOWER= 2; + private static const int RC_FIRSTUPPER= 3; + + + /** + * The adapted document. + */ + private IDocument fDocument; + + /** + * State for findReplace. + */ + private FindReplaceOperationCode fFindReplaceState= null; + + /** + * The matcher used in findReplace. + */ + private Matcher fFindReplaceMatcher; + + /** + * The match offset from the last findReplace call. + */ + private int fFindReplaceMatchOffset; + + /** + * Retain case mode + */ + private int fRetainCaseMode; + + /** + * Constructs a new find replace document adapter. + * + * @param document the adapted document + */ + public this(IDocument document) { + Assert.isNotNull(cast(Object)document); + fDocument= document; + } + + /** + * Returns the location of a given string in this adapter's document based on a set of search criteria. + * + * @param startOffset document offset at which search starts + * @param findString the string to find + * @param forwardSearch the search direction + * @param caseSensitive indicates whether lower and upper case should be distinguished + * @param wholeWord indicates whether the findString should be limited by white spaces as + * defined by Character.isWhiteSpace. Must not be used in combination with regExSearch. + * @param regExSearch if true findString represents a regular expression + * Must not be used in combination with wholeWord. + * @return the find or replace region or null if there was no match + * @throws BadLocationException if startOffset is an invalid document offset + * @throws PatternSyntaxException if a regular expression has invalid syntax + */ + public IRegion find(int startOffset, String findString, bool forwardSearch, bool caseSensitive, bool wholeWord, bool regExSearch) { + Assert.isTrue(!(regExSearch && wholeWord)); + + // Adjust offset to special meaning of -1 + if (startOffset is -1 && forwardSearch) + startOffset= 0; + if (startOffset is -1 && !forwardSearch) + startOffset= length() - 1; + + return findReplace(FIND_FIRST, startOffset, findString, null, forwardSearch, caseSensitive, wholeWord, regExSearch); + } + + /** + * Stateful findReplace executes a FIND, REPLACE, REPLACE_FIND or FIND_FIRST operation. + * In case of REPLACE and REPLACE_FIND it sends a DocumentEvent to all + * registered IDocumentListener. + * + * @param startOffset document offset at which search starts + * this value is only used in the FIND_FIRST operation and otherwise ignored + * @param findString the string to find + * this value is only used in the FIND_FIRST operation and otherwise ignored + * @param replaceText the string to replace the current match + * this value is only used in the REPLACE and REPLACE_FIND operations and otherwise ignored + * @param forwardSearch the search direction + * @param caseSensitive indicates whether lower and upper case should be distinguished + * @param wholeWord indicates whether the findString should be limited by white spaces as + * defined by Character.isWhiteSpace. Must not be used in combination with regExSearch. + * @param regExSearch if true this operation represents a regular expression + * Must not be used in combination with wholeWord. + * @param operationCode specifies what kind of operation is executed + * @return the find or replace region or null if there was no match + * @throws BadLocationException if startOffset is an invalid document offset + * @throws IllegalStateException if a REPLACE or REPLACE_FIND operation is not preceded by a successful FIND operation + * @throws PatternSyntaxException if a regular expression has invalid syntax + */ + private IRegion findReplace(FindReplaceOperationCode operationCode, int startOffset, String findString, String replaceText, bool forwardSearch, bool caseSensitive, bool wholeWord, bool regExSearch) { + + // Validate option combinations + Assert.isTrue(!(regExSearch && wholeWord)); + + // Validate state + if ((operationCode is REPLACE || operationCode is REPLACE_FIND_NEXT) && (fFindReplaceState !is FIND_FIRST && fFindReplaceState !is FIND_NEXT)) + throw new IllegalStateException("illegal findReplace state: cannot replace without preceding find"); //$NON-NLS-1$ + + if (operationCode is FIND_FIRST) { + // Reset + + if (findString is null || findString.length is 0) + return null; + + // Validate start offset + if (startOffset < 0 || startOffset >= length()) + throw new BadLocationException(); + + int patternFlags= 0; + + if (regExSearch) { + patternFlags |= Pattern.MULTILINE; + findString= substituteLinebreak(findString); + } + + if (!caseSensitive) + patternFlags |= Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE; + + if (wholeWord) + findString= "\\b" ~ findString ~ "\\b"; //$NON-NLS-1$ //$NON-NLS-2$ + + if (!regExSearch && !wholeWord) + findString= asRegPattern(findString); + + fFindReplaceMatchOffset= startOffset; + if (fFindReplaceMatcher !is null && fFindReplaceMatcher.pattern().pattern().equals(findString) && fFindReplaceMatcher.pattern().flags() is patternFlags) { + /* + * Commented out for optimization: + * The call is not needed since FIND_FIRST uses find(int) which resets the matcher + */ + // fFindReplaceMatcher.reset(); + } else { + Pattern pattern= Pattern.compile(findString, patternFlags); + fFindReplaceMatcher= pattern.matcher(this); + } + } + + // Set state + fFindReplaceState= operationCode; + + if (operationCode is REPLACE || operationCode is REPLACE_FIND_NEXT) { + if (regExSearch) { + Pattern pattern= fFindReplaceMatcher.pattern(); + String prevMatch= fFindReplaceMatcher.group(); + try { + replaceText= interpretReplaceEscapes(replaceText, prevMatch); + Matcher replaceTextMatcher= pattern.matcher(prevMatch); + replaceText= replaceTextMatcher.replaceFirst(replaceText); + } catch (IndexOutOfBoundsException ex) { + throw new PatternSyntaxException(ex.msg/+getLocalizedMessage()+/, replaceText, -1); + } + } + + int offset= fFindReplaceMatcher.start(); + int length= fFindReplaceMatcher.group().length; + + if (cast(IRepairableDocumentExtension)fDocument + && (cast(IRepairableDocumentExtension)fDocument).isLineInformationRepairNeeded(offset, length, replaceText)) { + String message= TextMessages.getString("FindReplaceDocumentAdapter.incompatibleLineDelimiter"); //$NON-NLS-1$ + throw new PatternSyntaxException(message, replaceText, offset); + } + + fDocument.replace(offset, length, replaceText); + + if (operationCode is REPLACE) { + return new Region(offset, replaceText.length); + } + } + + if (operationCode !is REPLACE) { + if (forwardSearch) { + + bool found= false; + if (operationCode is FIND_FIRST) + found= fFindReplaceMatcher.find(startOffset); + else + found= fFindReplaceMatcher.find(); + + if (operationCode is REPLACE_FIND_NEXT) + fFindReplaceState= FIND_NEXT; + + if (found && fFindReplaceMatcher.group().length > 0) + return new Region(fFindReplaceMatcher.start(), fFindReplaceMatcher.group().length); + return null; + } + + // backward search + bool found= fFindReplaceMatcher.find(0); + int index= -1; + int length= -1; + while (found && fFindReplaceMatcher.start() + fFindReplaceMatcher.group().length <= fFindReplaceMatchOffset + 1) { + index= fFindReplaceMatcher.start(); + length= fFindReplaceMatcher.group().length; + found= fFindReplaceMatcher.find(index + 1); + } + fFindReplaceMatchOffset= index; + if (index > -1) { + // must set matcher to correct position + fFindReplaceMatcher.find(index); + return new Region(index, length); + } + return null; + } + + return null; + } + + /** + * Substitutes \R in a regex find pattern with (?>\r\n?|\n) + * + * @param findString the original find pattern + * @return the transformed find pattern + * @throws PatternSyntaxException if \R is added at an illegal position (e.g. in a character set) + * @since 3.4 + */ + private String substituteLinebreak(String findString) { + int length= findString.length; + StringBuffer buf= new StringBuffer(length); + + int inCharGroup= 0; + int inBraces= 0; + bool inQuote= false; + for (int i= 0; i < length; i++) { + char ch= .charAt(findString, i); + switch (ch) { + case '[': + buf.append(ch); + if (! inQuote) + inCharGroup++; + break; + + case ']': + buf.append(ch); + if (! inQuote) + inCharGroup--; + break; + + case '{': + buf.append(ch); + if (! inQuote && inCharGroup is 0) + inBraces++; + break; + + case '}': + buf.append(ch); + if (! inQuote && inCharGroup is 0) + inBraces--; + break; + + case '\\': + if (i + 1 < length) { + char ch1= .charAt(findString, i + 1); + if (inQuote) { + if (ch1 is 'E') + inQuote= false; + buf.append(ch).append(ch1); + i++; + + } else if (ch1 is 'R') { + if (inCharGroup > 0 || inBraces > 0) { + String msg= TextMessages.getString("FindReplaceDocumentAdapter.illegalLinebreak"); //$NON-NLS-1$ + throw new PatternSyntaxException(msg, findString, i); + } + buf.append("(?>\\r\\n?|\\n)"); //$NON-NLS-1$ + i++; + + } else { + if (ch1 is 'Q') { + inQuote= true; + } + buf.append(ch).append(ch1); + i++; + } + } else { + buf.append(ch); + } + break; + + default: + buf.append(ch); + break; + } + + } + return buf.toString(); + } + + /** + * Interprets current Retain Case mode (all upper-case,all lower-case,capitalized or mixed) + * and appends the character ch to buf after processing. + * + * @param buf the output buffer + * @param ch the character to process + * @since 3.4 + */ + private void interpretRetainCase(StringBuffer buf, dchar ch) { + if (fRetainCaseMode is RC_UPPER) + buf.append(dcharToString(Character.toUpperCase(ch))); + else if (fRetainCaseMode is RC_LOWER) + buf.append(dcharToString(Character.toLowerCase(ch))); + else if (fRetainCaseMode is RC_FIRSTUPPER) { + buf.append(dcharToString(Character.toUpperCase(ch))); + fRetainCaseMode= RC_MIXED; + } else + buf.append(dcharToString(ch)); + } + + /** + * Interprets escaped characters in the given replace pattern. + * + * @param replaceText the replace pattern + * @param foundText the found pattern to be replaced + * @return a replace pattern with escaped characters substituted by the respective characters + * @since 3.4 + */ + private String interpretReplaceEscapes(String replaceText, String foundText) { + int length= replaceText.length; + bool inEscape= false; + StringBuffer buf= new StringBuffer(length); + + /* every string we did not check looks mixed at first + * so initialize retain case mode with RC_MIXED + */ + fRetainCaseMode= RC_MIXED; + + for (int i= 0; i < length; i++) { + char ch= .charAt(replaceText, i); + if (inEscape) { + i= interpretReplaceEscape(ch, i, buf, replaceText, foundText); + inEscape= false; + + } else if (ch is '\\') { + inEscape= true; + + } else if (ch is '$') { + buf.append(ch); + + /* + * Feature in java.util.regex.Matcher#replaceFirst(String): + * $00, $000, etc. are interpreted as $0 and + * $01, $001, etc. are interpreted as $1, etc. . + * If we support \0 as replacement pattern for capturing group 0, + * it would not be possible any more to write a replacement pattern + * that appends 0 to a capturing group (like $0\0). + * The fix is to interpret \00 and $00 as $0\0, and + * \01 and $01 as $0\1, etc. + */ + if (i + 2 < length) { + char ch1= .charAt(replaceText, i + 1); + char ch2= .charAt(replaceText, i + 2); + if (ch1 is '0' && '0' <= ch2 && ch2 <= '9') { + buf.append("0\\"); //$NON-NLS-1$ + i++; // consume the 0 + } + } + } else { + interpretRetainCase(buf, ch); + } + } + + if (inEscape) { + // '\' as last character is invalid, but we still add it to get an error message + buf.append('\\'); + } + return buf.toString(); + } + + /** + * Interprets the escaped character ch at offset i + * of the replaceText and appends the interpretation to buf. + * + * @param ch the escaped character + * @param i the offset + * @param buf the output buffer + * @param replaceText the original replace pattern + * @param foundText the found pattern to be replaced + * @return the new offset + * @since 3.4 + */ + private int interpretReplaceEscape(char ch, int i, StringBuffer buf, String replaceText, String foundText) { + int length= replaceText.length; + switch (ch) { + case 'r': + buf.append('\r'); + break; + case 'n': + buf.append('\n'); + break; + case 't': + buf.append('\t'); + break; + case 'f': + buf.append('\f'); + break; + case 'a': + buf.append("\u0007"c); + break; + case 'e': + buf.append("\u001B"c); + break; + case 'R': //see http://www.unicode.org/unicode/reports/tr18/#Line_Boundaries + buf.append(TextUtilities.getDefaultLineDelimiter(fDocument)); + break; + /* + * \0 for octal is not supported in replace string, since it + * would conflict with capturing group \0, etc. + */ + case '0': + buf.append('$').append(ch); + /* + * See explanation in "Feature in java.util.regex.Matcher#replaceFirst(String)" + * in interpretReplaceEscape(String) above. + */ + if (i + 1 < length) { + char ch1= .charAt(replaceText, i + 1); + if ('0' <= ch1 && ch1 <= '9') { + buf.append('\\'); + } + } + break; + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + buf.append('$').append(ch); + break; + + case 'c': + if (i + 1 < length) { + char ch1= .charAt(replaceText, i + 1); + interpretRetainCase(buf, cast(wchar)(ch1 ^ 64)); + i++; + } else { + String msg= TextMessages.getFormattedString("FindReplaceDocumentAdapter.illegalControlEscape", stringcast("\\c")); //$NON-NLS-1$ //$NON-NLS-2$ + throw new PatternSyntaxException(msg, replaceText, i); + } + break; + + case 'x': + if (i + 2 < length) { + int parsedInt; + try { + parsedInt= Integer.parseInt(replaceText.substring(i + 1, i + 3), 16); + if (parsedInt < 0) + throw new NumberFormatException(""); + } catch (NumberFormatException e) { + String msg= TextMessages.getFormattedString("FindReplaceDocumentAdapter.illegalHexEscape", stringcast(replaceText.substring(i - 1, i + 3))); //$NON-NLS-1$ + throw new PatternSyntaxException(msg, replaceText, i); + } + interpretRetainCase(buf, cast(wchar) parsedInt); + i+= 2; + } else { + String msg= TextMessages.getFormattedString("FindReplaceDocumentAdapter.illegalHexEscape", stringcast(replaceText.substring(i - 1, length))); //$NON-NLS-1$ + throw new PatternSyntaxException(msg, replaceText, i); + } + break; + + case 'u': + if (i + 4 < length) { + int parsedInt; + try { + parsedInt= Integer.parseInt(replaceText.substring(i + 1, i + 5), 16); + if (parsedInt < 0) + throw new NumberFormatException(""); + } catch (NumberFormatException e) { + String msg= TextMessages.getFormattedString("FindReplaceDocumentAdapter.illegalUnicodeEscape", stringcast(replaceText.substring(i - 1, i + 5))); //$NON-NLS-1$ + throw new PatternSyntaxException(msg, replaceText, i); + } + interpretRetainCase(buf, cast(wchar) parsedInt); + i+= 4; + } else { + String msg= TextMessages.getFormattedString("FindReplaceDocumentAdapter.illegalUnicodeEscape", stringcast(replaceText.substring(i - 1, length))); //$NON-NLS-1$ + throw new PatternSyntaxException(msg, replaceText, i); + } + break; + + case 'C': + if(foundText.toUpperCase().equals(foundText)) // is whole match upper-case? + fRetainCaseMode= RC_UPPER; + else if (foundText.toLowerCase().equals(foundText)) // is whole match lower-case? + fRetainCaseMode= RC_LOWER; + else if(Character.isUpperCase(.charAt(foundText,0))) // is first character upper-case? + fRetainCaseMode= RC_FIRSTUPPER; + else + fRetainCaseMode= RC_MIXED; + break; + + default: + // unknown escape k: append uninterpreted \k + buf.append('\\').append(ch); + break; + } + return i; + } + + /** + * Converts a non-regex string to a pattern + * that can be used with the regex search engine. + * + * @param string the non-regex pattern + * @return the string converted to a regex pattern + */ + private String asRegPattern(String string) { + StringBuffer out_= new StringBuffer(string.length); + bool quoting= false; + + for (int i= 0, length= string.length; i < length; i++) { + char ch= .charAt(string, i); + if (ch is '\\') { + if (quoting) { + out_.append("\\E"); //$NON-NLS-1$ + quoting= false; + } + out_.append("\\\\"); //$NON-NLS-1$ + continue; + } + if (!quoting) { + out_.append("\\Q"); //$NON-NLS-1$ + quoting= true; + } + out_.append(ch); + } + if (quoting) + out_.append("\\E"); //$NON-NLS-1$ + + return out_.toString(); + } + + /** + * Substitutes the previous match with the given text. + * Sends a DocumentEvent to all registered IDocumentListener. + * + * @param text the substitution text + * @param regExReplace if true text represents a regular expression + * @return the replace region or null if there was no match + * @throws BadLocationException if startOffset is an invalid document offset + * @throws IllegalStateException if a REPLACE or REPLACE_FIND operation is not preceded by a successful FIND operation + * @throws PatternSyntaxException if a regular expression has invalid syntax + * + * @see DocumentEvent + * @see IDocumentListener + */ + public IRegion replace(String text, bool regExReplace) { + return findReplace(REPLACE, -1, null, text, false, false, false, regExReplace); + } + + // ---------- CharSequence implementation ---------- + + /* + * @see java.lang.CharSequence#length() + */ + public int length() { + return fDocument.getLength(); + } + + /* + * @see java.lang.CharSequence#charAt(int) + */ + public override char charAt(int index) { + try { + return fDocument.getChar(index); + } catch (BadLocationException e) { + throw new IndexOutOfBoundsException(); + } + } + + /* + * @see java.lang.CharSequence#subSequence(int, int) + */ + public CharSequence subSequence(int start, int end) { + try { + return new StringCharSequence(fDocument.get(start, end - start)); + } catch (BadLocationException e) { + throw new IndexOutOfBoundsException(); + } + } + + /* + * @see java.lang.Object#toString() + */ + public override String toString() { + return fDocument.get(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/FindReplaceDocumentAdapterContentProposalProvider.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/FindReplaceDocumentAdapterContentProposalProvider.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,523 @@ +/******************************************************************************* + * 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 + * Cagatay Calli - [find/replace] retain caps when replacing - https://bugs.eclipse.org/bugs/show_bug.cgi?id=28949 + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + +import dwtx.jface.fieldassist.IContentProposal; +import dwtx.jface.fieldassist.IContentProposalProvider; + + +/** + * Content assist proposal provider for the {@link FindReplaceDocumentAdapter}. + *

                + * Clients can subclass to provide additional proposals in case they are supported + * by their own find/replace mechanism. + *

                + *

                + * Note: Clients must not make any assumptions about the returned + * proposals. This can change from release to release to adapt to + * changes made in {@link FindReplaceDocumentAdapter}. + *

                + * + * @since 3.4 + */ +public class FindReplaceDocumentAdapterContentProposalProvider : IContentProposalProvider { + + + /** + * Proposal computer. + */ + private static class ProposalComputer { + + private static class Proposal : IContentProposal { + + private String fContent; + private String fLabel; + private String fDescription; + private int fCursorPosition; + + this(String content, String label, String description, int cursorPosition) { + fContent= content; + fLabel= label; + fDescription= description; + fCursorPosition= cursorPosition; + } + + public String getContent() { + return fContent; + } + + public String getLabel() { + return fLabel; + } + + public String getDescription() { + return fDescription; + } + + public int getCursorPosition() { + return fCursorPosition; + } + } + + + /** + * The whole regular expression. + */ + private const String fExpression; + /** + * The document offset. + */ + private const int fDocumentOffset; + /** + * The high-priority proposals. + */ + private const ArrayList fPriorityProposals; + /** + * The low-priority proposals. + */ + private const ArrayList fProposals; + /** + * true iff fExpression ends with an open escape. + */ + private const bool fIsEscape; + + /** + * Creates a new Proposal Computer. + * @param contents the contents of the subject control + * @param position the cursor position + */ + public this(String contents, int position) { + fExpression= contents; + fDocumentOffset= position; + fPriorityProposals= new ArrayList(); + fProposals= new ArrayList(); + + bool isEscape= false; + esc: for (int i= position - 1; i >= 0; i--) { + if (fExpression.charAt(i) is '\\') + isEscape= !isEscape; + else + break esc; + } + fIsEscape= isEscape; + } + + /** + * Computes applicable proposals for the find field. + * @return the proposals + */ + public IContentProposal[] computeFindProposals() { + //characters + addBsProposal("\\\\", RegExMessages.getString("displayString_bs_bs"), RegExMessages.getString("additionalInfo_bs_bs")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBracketProposal("\\0", 2, RegExMessages.getString("displayString_bs_0"), RegExMessages.getString("additionalInfo_bs_0")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBracketProposal("\\x", 2, RegExMessages.getString("displayString_bs_x"), RegExMessages.getString("additionalInfo_bs_x")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBracketProposal("\\u", 2, RegExMessages.getString("displayString_bs_u"), RegExMessages.getString("additionalInfo_bs_u")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\t", RegExMessages.getString("displayString_bs_t"), RegExMessages.getString("additionalInfo_bs_t")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\R", RegExMessages.getString("displayString_bs_R"), RegExMessages.getString("additionalInfo_bs_R")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\n", RegExMessages.getString("displayString_bs_n"), RegExMessages.getString("additionalInfo_bs_n")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\r", RegExMessages.getString("displayString_bs_r"), RegExMessages.getString("additionalInfo_bs_r")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\f", RegExMessages.getString("displayString_bs_f"), RegExMessages.getString("additionalInfo_bs_f")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\a", RegExMessages.getString("displayString_bs_a"), RegExMessages.getString("additionalInfo_bs_a")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\e", RegExMessages.getString("displayString_bs_e"), RegExMessages.getString("additionalInfo_bs_e")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBracketProposal("\\c", 2, RegExMessages.getString("displayString_bs_c"), RegExMessages.getString("additionalInfo_bs_c")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + if (! fIsEscape) + addBracketProposal(".", 1, RegExMessages.getString("displayString_dot"), RegExMessages.getString("additionalInfo_dot")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\d", RegExMessages.getString("displayString_bs_d"), RegExMessages.getString("additionalInfo_bs_d")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\D", RegExMessages.getString("displayString_bs_D"), RegExMessages.getString("additionalInfo_bs_D")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\s", RegExMessages.getString("displayString_bs_s"), RegExMessages.getString("additionalInfo_bs_s")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\S", RegExMessages.getString("displayString_bs_S"), RegExMessages.getString("additionalInfo_bs_S")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\w", RegExMessages.getString("displayString_bs_w"), RegExMessages.getString("additionalInfo_bs_w")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\W", RegExMessages.getString("displayString_bs_W"), RegExMessages.getString("additionalInfo_bs_W")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + // back reference + addBsProposal("\\", RegExMessages.getString("displayString_bs_i"), RegExMessages.getString("additionalInfo_bs_i")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + //quoting + addBsProposal("\\", RegExMessages.getString("displayString_bs"), RegExMessages.getString("additionalInfo_bs")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\Q", RegExMessages.getString("displayString_bs_Q"), RegExMessages.getString("additionalInfo_bs_Q")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\E", RegExMessages.getString("displayString_bs_E"), RegExMessages.getString("additionalInfo_bs_E")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + //character sets + if (! fIsEscape) { + addBracketProposal("[]", 1, RegExMessages.getString("displayString_set"), RegExMessages.getString("additionalInfo_set")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBracketProposal("[^]", 2, RegExMessages.getString("displayString_setExcl"), RegExMessages.getString("additionalInfo_setExcl")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBracketProposal("[-]", 1, RegExMessages.getString("displayString_setRange"), RegExMessages.getString("additionalInfo_setRange")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addProposal("&&", RegExMessages.getString("displayString_setInter"), RegExMessages.getString("additionalInfo_setInter")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + if (! fIsEscape && fDocumentOffset > 0 && fExpression.charAt(fDocumentOffset - 1) is '\\') { + addProposal("\\p{}", 3, RegExMessages.getString("displayString_posix"), RegExMessages.getString("additionalInfo_posix")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addProposal("\\P{}", 3, RegExMessages.getString("displayString_posixNot"), RegExMessages.getString("additionalInfo_posixNot")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } else { + addBracketProposal("\\p{}", 3, RegExMessages.getString("displayString_posix"), RegExMessages.getString("additionalInfo_posix")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBracketProposal("\\P{}", 3, RegExMessages.getString("displayString_posixNot"), RegExMessages.getString("additionalInfo_posixNot")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + //boundary matchers + if (fDocumentOffset is 0) { + addPriorityProposal("^", RegExMessages.getString("displayString_start"), RegExMessages.getString("additionalInfo_start")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } else if (fDocumentOffset is 1 && fExpression.charAt(0) is '^') { + addBracketProposal("^", 1, RegExMessages.getString("displayString_start"), RegExMessages.getString("additionalInfo_start")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + if (fDocumentOffset is fExpression.length()) { + addProposal("$", RegExMessages.getString("displayString_end"), RegExMessages.getString("additionalInfo_end")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + addBsProposal("\\b", RegExMessages.getString("displayString_bs_b"), RegExMessages.getString("additionalInfo_bs_b")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\B", RegExMessages.getString("displayString_bs_B"), RegExMessages.getString("additionalInfo_bs_B")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\A", RegExMessages.getString("displayString_bs_A"), RegExMessages.getString("additionalInfo_bs_A")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\G", RegExMessages.getString("displayString_bs_G"), RegExMessages.getString("additionalInfo_bs_G")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\Z", RegExMessages.getString("displayString_bs_Z"), RegExMessages.getString("additionalInfo_bs_Z")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\z", RegExMessages.getString("displayString_bs_z"), RegExMessages.getString("additionalInfo_bs_z")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + if (! fIsEscape) { + //capturing groups + addBracketProposal("()", 1, RegExMessages.getString("displayString_group"), RegExMessages.getString("additionalInfo_group")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + //flags + addBracketProposal("(?)", 2, RegExMessages.getString("displayString_flag"), RegExMessages.getString("additionalInfo_flag")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBracketProposal("(?:)", 3, RegExMessages.getString("displayString_flagExpr"), RegExMessages.getString("additionalInfo_flagExpr")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + //non-capturing group + addBracketProposal("(?:)", 3, RegExMessages.getString("displayString_nonCap"), RegExMessages.getString("additionalInfo_nonCap")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBracketProposal("(?>)", 3, RegExMessages.getString("displayString_atomicCap"), RegExMessages.getString("additionalInfo_atomicCap")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + //look around + addBracketProposal("(?=)", 3, RegExMessages.getString("displayString_posLookahead"), RegExMessages.getString("additionalInfo_posLookahead")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBracketProposal("(?!)", 3, RegExMessages.getString("displayString_negLookahead"), RegExMessages.getString("additionalInfo_negLookahead")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBracketProposal("(?<=)", 4, RegExMessages.getString("displayString_posLookbehind"), RegExMessages.getString("additionalInfo_posLookbehind")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBracketProposal("(? 0 && '$' is fExpression.charAt(fDocumentOffset - 1)) { + addProposal("", RegExMessages.getString("displayString_dollar"), RegExMessages.getString("additionalInfo_dollar")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } else { + if (! fIsEscape) + addProposal("$", RegExMessages.getString("displayString_dollar"), RegExMessages.getString("additionalInfo_dollar")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\", RegExMessages.getString("displayString_replace_cap"), RegExMessages.getString("additionalInfo_replace_cap")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\", RegExMessages.getString("displayString_replace_bs"), RegExMessages.getString("additionalInfo_replace_bs")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\R", RegExMessages.getString("displayString_replace_bs_R"), RegExMessages.getString("additionalInfo_replace_bs_R")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBracketProposal("\\x", 2, RegExMessages.getString("displayString_bs_x"), RegExMessages.getString("additionalInfo_bs_x")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBracketProposal("\\u", 2, RegExMessages.getString("displayString_bs_u"), RegExMessages.getString("additionalInfo_bs_u")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\t", RegExMessages.getString("displayString_bs_t"), RegExMessages.getString("additionalInfo_bs_t")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\n", RegExMessages.getString("displayString_replace_bs_n"), RegExMessages.getString("additionalInfo_replace_bs_n")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\r", RegExMessages.getString("displayString_replace_bs_r"), RegExMessages.getString("additionalInfo_replace_bs_r")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\f", RegExMessages.getString("displayString_bs_f"), RegExMessages.getString("additionalInfo_bs_f")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\a", RegExMessages.getString("displayString_bs_a"), RegExMessages.getString("additionalInfo_bs_a")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\e", RegExMessages.getString("displayString_bs_e"), RegExMessages.getString("additionalInfo_bs_e")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBracketProposal("\\c", 2, RegExMessages.getString("displayString_bs_c"), RegExMessages.getString("additionalInfo_bs_c")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + addBsProposal("\\C", RegExMessages.getString("displayString_replace_bs_C"), RegExMessages.getString("additionalInfo_replace_bs_C")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + fPriorityProposals.addAll(fProposals); + return arraycast!(IContentProposal)( fPriorityProposals.toArray()); + } + + /** + * Adds a proposal. + * + * @param proposal the string to be inserted + * @param displayString the proposal's label + * @param additionalInfo the additional information + */ + private void addProposal(String proposal, String displayString, String additionalInfo) { + fProposals.add(new Proposal(proposal, displayString, additionalInfo, proposal.length())); + } + + /** + * Adds a proposal. + * + * @param proposal the string to be inserted + * @param cursorPosition the cursor position after insertion, + * relative to the start of the proposal + * @param displayString the proposal's label + * @param additionalInfo the additional information + */ + private void addProposal(String proposal, int cursorPosition, String displayString, String additionalInfo) { + fProposals.add(new Proposal(proposal, displayString, additionalInfo, cursorPosition)); + } + + /** + * Adds a proposal to the priority proposals list. + * + * @param proposal the string to be inserted + * @param displayString the proposal's label + * @param additionalInfo the additional information + */ + private void addPriorityProposal(String proposal, String displayString, String additionalInfo) { + fPriorityProposals.add(new Proposal(proposal, displayString, additionalInfo, proposal.length())); + } + + /** + * Adds a proposal. Ensures that existing pre- and postfixes are not duplicated. + * + * @param proposal the string to be inserted + * @param cursorPosition the cursor position after insertion, + * relative to the start of the proposal + * @param displayString the proposal's label + * @param additionalInfo the additional information + */ + private void addBracketProposal(String proposal, int cursorPosition, String displayString, String additionalInfo) { + String prolog= fExpression.substring(0, fDocumentOffset); + if (! fIsEscape && prolog.endsWith("\\") && proposal.startsWith("\\")) { //$NON-NLS-1$//$NON-NLS-2$ + fProposals.add(new Proposal(proposal, displayString, additionalInfo, cursorPosition)); + return; + } + for (int i= 1; i <= cursorPosition; i++) { + String prefix= proposal.substring(0, i); + if (prolog.endsWith(prefix)) { + String postfix= proposal.substring(cursorPosition); + String epilog= fExpression.substring(fDocumentOffset); + if (epilog.startsWith(postfix)) { + fPriorityProposals.add(new Proposal(proposal.substring(i, cursorPosition), displayString, additionalInfo, cursorPosition-i)); + } else { + fPriorityProposals.add(new Proposal(proposal.substring(i), displayString, additionalInfo, cursorPosition-i)); + } + return; + } + } + fProposals.add(new Proposal(proposal, displayString, additionalInfo, cursorPosition)); + } + + /** + * Adds a proposal that starts with a backslash. + * Ensures that the backslash is not repeated if already typed. + * + * @param proposal the string to be inserted + * @param displayString the proposal's label + * @param additionalInfo the additional information + */ + private void addBsProposal(String proposal, String displayString, String additionalInfo) { + String prolog= fExpression.substring(0, fDocumentOffset); + int position= proposal.length(); + // If the string already contains the backslash, do not include in the proposal + if (prolog.endsWith("\\")) { //$NON-NLS-1$ + position--; + proposal= proposal.substring(1); + } + + if (fIsEscape) { + fPriorityProposals.add(new Proposal(proposal, displayString, additionalInfo, position)); + } else { + addProposal(proposal, position, displayString, additionalInfo); + } + } + } + + /** + * true iff the processor is for the find field. + * false iff the processor is for the replace field. + */ + private const bool fIsFind; + + + /** + * Creates a new completion proposal provider. + * + * @param isFind true if the provider is used for the 'find' field + * false if the provider is used for the 'replace' field + */ + public this(bool isFind) { + fIsFind= isFind; + } + + /* + * @see dwtx.jface.fieldassist.IContentProposalProvider#getProposals(java.lang.String, int) + */ + public IContentProposal [] getProposals(String contents, int position) { + if (fIsFind) + return (new ProposalComputer(contents, position)).computeFindProposals(); + return (new ProposalComputer(contents, position)).computeReplaceProposals(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/GapTextStore.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/GapTextStore.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,536 @@ +/******************************************************************************* + * 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 + * 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.text.GapTextStore; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.core.runtime.Assert; + + +/** + * Implements a gap managing text store. The gap text store relies on the assumption that + * consecutive changes to a document are co-located. The start of the gap is always moved to the + * location of the last change. + *

                + * Performance: Typing-style changes perform in constant time unless re-allocation + * becomes necessary. Generally, a change that does not cause re-allocation will cause at most one + * {@linkplain System#arraycopy(Object, int, Object, int, int) arraycopy} operation of a length of + * about d, where d is the distance from the previous change. Let a(x) + * be the algorithmic performance of an arraycopy operation of the length x, + * then such a change then performs in O(a(x)), + * {@linkplain #get(int, int) get(int, length)} performs in O(a(length)), + * {@link #get(int)} in O(1). + *

                + * How frequently the array needs re-allocation is controlled by the constructor parameters. + *

                + *

                + * This class is not intended to be subclassed. + *

                + * + * @see CopyOnWriteTextStore for a copy-on-write text store wrapper + * @noextend This class is not intended to be subclassed by clients. + */ +public class GapTextStore : ITextStore { + /** + * The minimum gap size allocated when re-allocation occurs. + * @since 3.3 + */ + private const int fMinGapSize; + /** + * The maximum gap size allocated when re-allocation occurs. + * @since 3.3 + */ + private const int fMaxGapSize; + /** + * The multiplier to compute the array size from the content length + * (1 <= fSizeMultiplier <= 2). + * + * @since 3.3 + */ + private const float fSizeMultiplier; + + /** The store's content */ + private char[] fContent; + /** Starting index of the gap */ + private int fGapStart= 0; + /** End index of the gap */ + private int fGapEnd= 0; + /** + * The current high water mark. If a change would cause the gap to grow larger than this, the + * array is re-allocated. + * @since 3.3 + */ + private int fThreshold= 0; + + /** + * Creates a new empty text store using the specified low and high watermarks. + * + * @param lowWatermark unused - at the lower bound, the array is only resized when the content + * does not fit + * @param highWatermark if the gap is ever larger than this, it will automatically be shrunken + * (>= 0) + * @deprecated use {@link GapTextStore#GapTextStore(int, int, float)} instead + */ + public this(int lowWatermark, int highWatermark) { + /* + * Legacy constructor. The API contract states that highWatermark is the upper bound for the + * gap size. Albeit this contract was not previously adhered to, it is now: The allocated + * gap size is fixed at half the highWatermark. Since the threshold is always twice the + * allocated gap size, the gap will never grow larger than highWatermark. Previously, the + * gap size was initialized to highWatermark, causing re-allocation if the content length + * shrunk right after allocation. The fixed gap size is now only half of the previous value, + * circumventing that problem (there was no API contract specifying the initial gap size). + * + * The previous implementation did not allow the gap size to become smaller than + * lowWatermark, which doesn't make any sense: that area of the gap was simply never ever + * used. + */ + this(highWatermark / 2, highWatermark / 2, 0f); + } + + /** + * Equivalent to + * {@linkplain GapTextStore#GapTextStore(int, int, float) new GapTextStore(256, 4096, 0.1f)}. + * + * @since 3.3 + */ + public this() { + this(256, 4096, 0.1f); + } + + /** + * Creates an empty text store that uses re-allocation thresholds relative to the content + * length. Re-allocation is controlled by the gap factor, which is the quotient of + * the gap size and the array size. Re-allocation occurs if a change causes the gap factor to go + * outside [0, maxGapFactor]. When re-allocation occurs, the array is sized + * such that the gap factor is 0.5 * maxGapFactor. The gap size computed in this + * manner is bounded by the minSize and maxSize parameters. + *

                + * A maxGapFactor of 0 creates a text store that never has a gap + * at all (if minSize is 0); a maxGapFactor of 1 + * creates a text store that doubles its size with every re-allocation and that never shrinks. + *

                + *

                + * The minSize and maxSize parameters are absolute bounds to the + * allocated gap size. Use minSize to avoid frequent re-allocation for small + * documents. Use maxSize to avoid a huge gap being allocated for large + * documents. + *

                + * + * @param minSize the minimum gap size to allocate (>= 0; use 0 for no minimum) + * @param maxSize the maximum gap size to allocate (>= minSize; use + * {@link Integer#MAX_VALUE} for no maximum) + * @param maxGapFactor is the maximum fraction of the array that is occupied by the gap (0 <= maxGapFactor <= 1) + * @since 3.3 + */ + public this(int minSize, int maxSize, float maxGapFactor) { + Assert.isLegal(0f <= maxGapFactor && maxGapFactor <= 1f); + Assert.isLegal(0 <= minSize && minSize <= maxSize); + fMinGapSize= minSize; + fMaxGapSize= maxSize; + fSizeMultiplier= 1 / (1 - maxGapFactor / 2); + } + + /* + * @see dwtx.jface.text.ITextStore#get(int) + */ + public final char get(int offset) { + if (offset < fGapStart) + return fContent[offset]; + + return fContent[offset + gapSize()]; + } + + /* + * @see dwtx.jface.text.ITextStore#get(int, int) + */ + public final String get(int offset, int length) { + if (fGapStart <= offset) + return new_String(fContent, offset + gapSize() , length); + + final int end= offset + length; + + if (end <= fGapStart) + return new_String(fContent, offset, length); + + StringBuffer buf= new StringBuffer(length); + buf.append(fContent[ offset .. fGapStart ]); + buf.append(fContent[ fGapEnd .. end - fGapStart + fGapEnd ]); + return buf.toString(); + } + + /* + * @see dwtx.jface.text.ITextStore#getLength() + */ + public final int getLength() { + return fContent.length - gapSize(); + } + + /* + * @see dwtx.jface.text.ITextStore#set(java.lang.String) + */ + public final void set(String text) { + /* + * Moves the gap to the end of the content. There is no sensible prediction of where the + * next change will occur, but at least the next change will not trigger re-allocation. This + * is especially important when using the GapTextStore within a CopyOnWriteTextStore, where + * the GTS is only initialized right before a modification. + */ + replace(0, getLength(), text); + } + + /* + * @see dwtx.jface.text.ITextStore#replace(int, int, java.lang.String) + */ + public final void replace(int offset, int length, String text) { + if (text is null) { + adjustGap(offset, length, 0); + } else { + int textLength= text.length; + adjustGap(offset, length, textLength); + if (textLength !is 0) + text.getChars(0, textLength, fContent, offset); + } + } + + /** + * Moves the gap to offset + add, moving any content after + * offset + remove behind the gap. The gap size is kept between 0 and + * {@link #fThreshold}, leading to re-allocation if needed. The content between + * offset and offset + add is undefined after this operation. + * + * @param offset the offset at which a change happens + * @param remove the number of character which are removed or overwritten at offset + * @param add the number of character which are inserted or overwriting at offset + */ + private void adjustGap(int offset, int remove, int add) { + final int oldGapSize= gapSize(); + final int newGapSize= oldGapSize - add + remove; + final bool reuseArray= 0 <= newGapSize && newGapSize <= fThreshold; + + final int newGapStart= offset + add; + int newGapEnd; + + if (reuseArray) + newGapEnd= moveGap(offset, remove, oldGapSize, newGapSize, newGapStart); + else + newGapEnd= reallocate(offset, remove, oldGapSize, newGapSize, newGapStart); + + fGapStart= newGapStart; + fGapEnd= newGapEnd; + } + + /** + * Moves the gap to newGapStart. + * + * @param offset the change offset + * @param remove the number of removed / overwritten characters + * @param oldGapSize the old gap size + * @param newGapSize the gap size after the change + * @param newGapStart the offset in the array to move the gap to + * @return the new gap end + * @since 3.3 + */ + private int moveGap(int offset, int remove, int oldGapSize, int newGapSize, int newGapStart) { + /* + * No re-allocation necessary. The area between the change offset and gap can be copied + * in at most one operation. Don't copy parts that will be overwritten anyway. + */ + final int newGapEnd= newGapStart + newGapSize; + if (offset < fGapStart) { + int afterRemove= offset + remove; + if (afterRemove < fGapStart) { + final int betweenSize= fGapStart - afterRemove; + arrayCopy(afterRemove, fContent, newGapEnd, betweenSize); + } + // otherwise, only the gap gets enlarged + } else { + final int offsetShifted= offset + oldGapSize; + final int betweenSize= offsetShifted - fGapEnd; // in the typing case, betweenSize is 0 + arrayCopy(fGapEnd, fContent, fGapStart, betweenSize); + } + return newGapEnd; + } + + /** + * Reallocates a new array and copies the data from the previous one. + * + * @param offset the change offset + * @param remove the number of removed / overwritten characters + * @param oldGapSize the old gap size + * @param newGapSize the gap size after the change if no re-allocation would occur (can be negative) + * @param newGapStart the offset in the array to move the gap to + * @return the new gap end + * @since 3.3 + */ + private int reallocate(int offset, int remove, int oldGapSize, int newGapSize, int newGapStart) { + // the new content length (without any gap) + final int newLength= fContent.length - newGapSize; + // the new array size based on the gap factor + int newArraySize= cast(int) (newLength * fSizeMultiplier); + newGapSize= newArraySize - newLength; + + // bound the gap size within min/max + if (newGapSize < fMinGapSize) { + newGapSize= fMinGapSize; + newArraySize= newLength + newGapSize; + } else if (newGapSize > fMaxGapSize) { + newGapSize= fMaxGapSize; + newArraySize= newLength + newGapSize; + } + + // the upper threshold is always twice the gapsize + fThreshold= newGapSize * 2; + final char[] newContent= allocate(newArraySize); + final int newGapEnd= newGapStart + newGapSize; + + /* + * Re-allocation: The old content can be copied in at most 3 operations to the newly allocated + * array. Either one of change offset and the gap may come first. + * - unchanged area before the change offset / gap + * - area between the change offset and the gap (either one may be first) + * - rest area after the change offset / after the gap + */ + if (offset < fGapStart) { + // change comes before gap + arrayCopy(0, newContent, 0, offset); + int afterRemove= offset + remove; + if (afterRemove < fGapStart) { + // removal is completely before the gap + final int betweenSize= fGapStart - afterRemove; + arrayCopy(afterRemove, newContent, newGapEnd, betweenSize); + final int restSize= fContent.length - fGapEnd; + arrayCopy(fGapEnd, newContent, newGapEnd + betweenSize, restSize); + } else { + // removal encompasses the gap + afterRemove += oldGapSize; + final int restSize= fContent.length - afterRemove; + arrayCopy(afterRemove, newContent, newGapEnd, restSize); + } + } else { + // gap comes before change + arrayCopy(0, newContent, 0, fGapStart); + final int offsetShifted= offset + oldGapSize; + final int betweenSize= offsetShifted - fGapEnd; + arrayCopy(fGapEnd, newContent, fGapStart, betweenSize); + final int afterRemove= offsetShifted + remove; + final int restSize= fContent.length - afterRemove; + arrayCopy(afterRemove, newContent, newGapEnd, restSize); + } + + fContent= newContent; + return newGapEnd; + } + + /** + * Allocates a new char[size]. + * + * @param size the length of the new array. + * @return a newly allocated char array + * @since 3.3 + */ + private char[] allocate(int size) { + return new char[size]; + } + + /* + * Executes System.arraycopy if length !is 0. A length < 0 cannot happen -> don't hide coding + * errors by checking for negative lengths. + * @since 3.3 + */ + private void arrayCopy(int srcPos, char[] dest, int destPos, int length) { + if (length !is 0) + System.arraycopy(fContent, srcPos, dest, destPos, length); + } + + /** + * Returns the gap size. + * + * @return the gap size + * @since 3.3 + */ + private int gapSize() { + return fGapEnd - fGapStart; + } + + /** + * Returns a copy of the content of this text store. + * For internal use only. + * + * @return a copy of the content of this text store + */ + protected String getContentAsString() { + return new_String(fContent); + } + + /** + * Returns the start index of the gap managed by this text store. + * For internal use only. + * + * @return the start index of the gap managed by this text store + */ + protected int getGapStartIndex() { + return fGapStart; + } + + /** + * Returns the end index of the gap managed by this text store. + * For internal use only. + * + * @return the end index of the gap managed by this text store + */ + protected int getGapEndIndex() { + return fGapEnd; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IAutoEditStrategy.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IAutoEditStrategy.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IAutoEditStrategy; + +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.IDocument; // packageimport + +import dwt.dwthelper.utils; + + +/** + * An auto edit strategy can adapt changes that will be applied to + * a text viewer's document. The strategy is informed by the text viewer + * about each upcoming change in form of a document command. By manipulating + * this document command, the strategy can influence in which way the text + * viewer's document is changed. Clients may implement this interface. + * + * @since 2.1 + */ +public interface IAutoEditStrategy { + + /** + * Allows the strategy to manipulate the document command. + * + * @param document the document that will be changed + * @param command the document command describing the change + */ + void customizeDocumentCommand(IDocument document, DocumentCommand command); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IAutoIndentStrategy.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IAutoIndentStrategy.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IAutoIndentStrategy; + +import dwtx.jface.text.IAutoEditStrategy; // packageimport + +import dwt.dwthelper.utils; + +/** + * Exists for backward compatibility. + * + * @deprecated since 3.0, use IAutoEditStrategy directly + */ +public interface IAutoIndentStrategy : IAutoEditStrategy { +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDelayedInputChangeProvider.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDelayedInputChangeProvider.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,179 @@ +/******************************************************************************* + * 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.text.IDelayedInputChangeProvider; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * A delayed input change provider notifies the registered + * {@link IInputChangedListener} about input changes that occur after the normal + * operation of the provider. + *

                + * Clients can implement that interface and its extension interfaces.

                + * + * @since 3.4 + */ +public interface IDelayedInputChangeProvider { + + /** + * Sets or clears the delayed input change listener. + * + * @param inputChangeListener the new delayed input change listener, or + * null if none + * @since 3.4 + */ + void setDelayedInputChangeListener(IInputChangedListener inputChangeListener); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDocument.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDocument.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,663 @@ +/******************************************************************************* + * 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.text.IDocument; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + + +/** + * An IDocument represents text providing support for + *
                  + *
                • text manipulation + *
                • positions + *
                • partitions + *
                • line information + *
                • document change listeners + *
                • document partition change listeners + *
                + * + * A document allows to set its content and to manipulate it. For manipulation + * a document provides the replace method which substitutes a given + * string for a specified text range in the document. On each document change, all + * registered document listeners are informed exactly once. + *

                + * Positions are stickers to the document's text that are updated when the + * document is changed. Positions are updated by {@link dwtx.jface.text.IPositionUpdater}s. Position + * updaters are managed as a list. The list defines the sequence in which position + * updaters are invoked. This way, position updaters may rely on each other. + * Positions are grouped into categories. A category is a ordered list of positions. + * the document defines the order of position in a category based on the position's offset + * based on the implementation of the method computeIndexInCategory. + * Each document must support a default position category whose name is specified by this + * interface.

                + *

                + * A document can be considered consisting of a sequence of not overlapping partitions. + * A partition is defined by its offset, its length, and its type. Partitions are + * updated on every document manipulation and ensured to be up-to-date when the document + * listeners are informed. A document uses an IDocumentPartitioner to + * manage its partitions. A document may be unpartitioned which happens when there is no + * partitioner. In this case, the document is considered as one single partition of a + * default type. The default type is specified by this interface. If a document change + * changes the document's partitioning all registered partitioning listeners are + * informed exactly once. The extension interface {@link dwtx.jface.text.IDocumentExtension3} + * introduced in version 3.0 extends the concept of partitions and allows a document to + * not only manage one but multiple partitioning. Each partitioning has an id which must + * be used to refer to a particular partitioning.

                + *

                + * An IDocument provides methods to map line numbers and character + * positions onto each other based on the document's line delimiters. When moving text + * between documents using different line delimiters, the text must be converted to + * use the target document's line delimiters.

                + *

                + * An IDocument does not care about mixed line delimiters. Clients who + * want to ensure a single line delimiter in their document should use the line + * delimiter returned by {@link dwtx.jface.text.TextUtilities#getDefaultLineDelimiter(IDocument)}.

                + *

                + * IDocument throws BadLocationException if the parameters of + * queries or manipulation requests are not inside the bounds of the document. The purpose + * of this style of exception handling is + *

                  + *
                • prepare document for multi-thread access + *
                • allow clients to implement backtracking recovery methods + *
                • prevent clients from up-front contract checking when dealing with documents. + *

                + *

                + * A document support for searching has deprecated since version 3.0. The recommended way + * for searching is to use a {@link dwtx.jface.text.FindReplaceDocumentAdapter}.

                + *

                + * In order to provide backward compatibility for clients of IDocument, extension + * interfaces are used to provide a means of evolution. The following extension interfaces + * exist: + *

                  + *
                • {@link dwtx.jface.text.IDocumentExtension} since version 2.0 introducing the concept + * of post notification replaces in order to allow document listeners to manipulate the document + * while receiving a document change notification
                • + *
                • {@link dwtx.jface.text.IDocumentExtension2} since version 2.1 introducing configuration + * methods for post notification replaces and document change notification.
                • + *
                • {@link dwtx.jface.text.IDocumentExtension3} since version 3.0 replacing the original + * partitioning concept by allowing multiple partitionings at the same time and introducing zero- + * length partitions in conjunction with the distinction between open and closed partitions.
                • + *
                • {@link dwtx.jface.text.IDocumentExtension4} since version 3.1 introducing the + * concept of rewrite sessions. A rewrite session is a sequence of document replace operations + * that form a semantic unit. It also introduces a modification stamp and the ability to + * set the initial line delimiter and to query the default line delimiter.
                • + *

                + *

                + * Clients may implement this interface and its extension interfaces or use the default + * implementation provided by AbstractDocument and Document.

                + * + * @see dwtx.jface.text.IDocumentExtension + * @see dwtx.jface.text.IDocumentExtension2 + * @see dwtx.jface.text.IDocumentExtension3 + * @see dwtx.jface.text.IDocumentExtension4 + * @see dwtx.jface.text.Position + * @see dwtx.jface.text.IPositionUpdater + * @see dwtx.jface.text.IDocumentPartitioner + * @see dwtx.jface.text.ILineTracker + * @see dwtx.jface.text.IDocumentListener + * @see dwtx.jface.text.IDocumentPartitioningListener + */ +public interface IDocument { + + + /** + * The identifier of the default position category. + */ + final static String DEFAULT_CATEGORY= "__dflt_position_category"; //$NON-NLS-1$ + + /** + * The identifier of the default partition content type. + */ + final static String DEFAULT_CONTENT_TYPE= "__dftl_partition_content_type"; //$NON-NLS-1$ + + + + + /* --------------- text access and manipulation --------------------------- */ + + /** + * Returns the character at the given document offset in this document. + * + * @param offset a document offset + * @return the character at the offset + * @exception BadLocationException if the offset is invalid in this document + */ + char getChar(int offset) ; + + /** + * Returns the number of characters in this document. + * + * @return the number of characters in this document + */ + int getLength(); + + /** + * Returns this document's complete text. + * + * @return the document's complete text + */ + String get(); + + /** + * Returns this document's text for the specified range. + * + * @param offset the document offset + * @param length the length of the specified range + * @return the document's text for the specified range + * @exception BadLocationException if the range is invalid in this document + */ + String get(int offset, int length) ; + + /** + * Replaces the content of the document with the given text. + * Sends a DocumentEvent to all registered IDocumentListener. + * This method is a convenience method for replace(0, getLength(), text). + * + * @param text the new content of the document + * + * @see DocumentEvent + * @see IDocumentListener + */ + void set(String text); + + /** + * Substitutes the given text for the specified document range. + * Sends a DocumentEvent to all registered IDocumentListener. + * + * @param offset the document offset + * @param length the length of the specified range + * @param text the substitution text + * @exception BadLocationException if the offset is invalid in this document + * + * @see DocumentEvent + * @see IDocumentListener + */ + void replace(int offset, int length, String text) ; + + /** + * Registers the document listener with the document. After registration + * the IDocumentListener is informed about each change of this document. + * If the listener is already registered nothing happens.

                + * An IDocumentListener may call back to this method + * when being inside a document notification. + * + * @param listener the listener to be registered + */ + void addDocumentListener(IDocumentListener listener); + + /** + * Removes the listener from the document's list of document listeners. + * If the listener is not registered with the document nothing happens.

                + * An IDocumentListener may call back to this method + * when being inside a document notification. + * + * @param listener the listener to be removed + */ + void removeDocumentListener(IDocumentListener listener); + + /** + * Adds the given document listener as one which is notified before + * those document listeners added with addDocumentListener + * are notified. If the given listener is also registered using + * addDocumentListener it will be notified twice. + * If the listener is already registered nothing happens.

                + * + * This method is not for public use. + * + * @param documentAdapter the listener to be added as pre-notified document listener + * + * @see #removePrenotifiedDocumentListener(IDocumentListener) + */ + void addPrenotifiedDocumentListener(IDocumentListener documentAdapter); + + /** + * Removes the given document listener from the document's list of + * pre-notified document listeners. If the listener is not registered + * with the document nothing happens.

                + * + * This method is not for public use. + * + * @param documentAdapter the listener to be removed + * + * @see #addPrenotifiedDocumentListener(IDocumentListener) + */ + void removePrenotifiedDocumentListener(IDocumentListener documentAdapter); + + + + /* -------------------------- positions ----------------------------------- */ + + /** + * Adds a new position category to the document. If the position category + * already exists nothing happens. + * + * @param category the category to be added + */ + void addPositionCategory(String category); + + /** + * Deletes the position category from the document. All positions + * in this category are thus deleted as well. + * + * @param category the category to be removed + * @exception BadPositionCategoryException if category is undefined in this document + */ + void removePositionCategory(String category) ; + + /** + * Returns all position categories of this document. This + * includes the default position category. + * + * @return the document's position categories + */ + String[] getPositionCategories(); + + /** + * Checks the presence of the specified position category. + * + * @param category the category to check + * @return true if category is defined + */ + bool containsPositionCategory(String category); + + /** + * Adds the position to the document's default position category. + * This is a convenience method for addPosition(DEFAULT_CATEGORY, position). + * + * @param position the position to be added + * @exception BadLocationException if position describes an invalid range in this document + */ + void addPosition(Position position) ; + + /** + * Removes the given position from the document's default position category. + * This is a convenience method for removePosition(DEFAULT_CATEGORY, position). + * + * @param position the position to be removed + */ + void removePosition(Position position); + + /** + * Adds the position to the specified position category of the document. + * Positions may be added multiple times. The order of the category is + * maintained. + *

                + * Note: The position is only updated on each change + * applied to the document if a {@link IPositionUpdater} has been + * registered that handles the given category. + *

                + * + * @param category the category to which to add + * @param position the position to be added + * @throws BadLocationException if position describes an invalid range in this document + * @throws BadPositionCategoryException if the category is undefined in this document + */ + void addPosition(String category, Position position); + + /** + * Removes the given position from the specified position category. + * If the position is not part of the specified category nothing happens. + * If the position has been added multiple times, only the first occurrence is deleted. + * + * @param category the category from which to delete + * @param position the position to be deleted + * @exception BadPositionCategoryException if category is undefined in this document + */ + void removePosition(String category, Position position) ; + + /** + * Returns all positions of the given position category. + * The positions are ordered according to the category's order. + * Manipulating this list does not affect the document, but manipulating the + * position does affect the document. + * + * @param category the category + * @return the list of all positions + * @exception BadPositionCategoryException if category is undefined in this document + */ + Position[] getPositions(String category) ; + + /** + * Determines whether a position described by the parameters is managed by this document. + * + * @param category the category to check + * @param offset the offset of the position to find + * @param length the length of the position to find + * @return true if position is found + */ + bool containsPosition(String category, int offset, int length); + + /** + * Computes the index at which a Position with the + * specified offset would be inserted into the given category. As the + * ordering inside a category only depends on the offset, the index must be + * chosen to be the first of all positions with the same offset. + * + * @param category the category in which would be added + * @param offset the position offset to be considered + * @return the index into the category + * @exception BadLocationException if offset is invalid in this document + * @exception BadPositionCategoryException if category is undefined in this document + */ + int computeIndexInCategory(String category, int offset); + + /** + * Appends a new position updater to the document's list of position updaters. + * Position updaters may be added multiple times.

                + * An IPositionUpdater may call back to this method + * when being inside a document notification. + * + * @param updater the updater to be added + */ + void addPositionUpdater(IPositionUpdater updater); + + /** + * Removes the position updater from the document's list of position updaters. + * If the position updater has multiple occurrences only the first occurrence is + * removed. If the position updater is not registered with this document, nothing + * happens.

                + * An IPositionUpdater may call back to this method + * when being inside a document notification. + * + * @param updater the updater to be removed + */ + void removePositionUpdater(IPositionUpdater updater); + + /** + * Inserts the position updater at the specified index in the document's + * list of position updaters. Positions updaters may be inserted multiple times.

                + * An IPositionUpdater may call back to this method + * when being inside a document notification. + * + * @param updater the updater to be inserted + * @param index the index in the document's updater list + */ + void insertPositionUpdater(IPositionUpdater updater, int index); + + /** + * Returns the list of position updaters attached to the document. + * + * @return the list of position updaters + */ + IPositionUpdater[] getPositionUpdaters(); + + + + + /* -------------------------- partitions ---------------------------------- */ + + /** + * Returns the set of legal content types of document partitions. + * This set can be empty. The set can contain more content types than + * contained by the result of getPartitioning(0, getLength()). + *

                + * Use {@link IDocumentExtension3#getLegalContentTypes(String)} when the document + * supports multiple partitionings. In that case this method is equivalent to: + *

                +     *    IDocumentExtension3 extension= cast(IDocumentExtension3) document;
                +     *    return extension.getLegalContentTypes(IDocumentExtension3.DEFAULT_PARTITIONING);
                +     * 
                + * + * @return the set of legal content types + */ + String[] getLegalContentTypes(); + + /** + * Returns the type of the document partition containing the given offset. + * This is a convenience method for getPartition(offset).getType(). + *

                + * Use {@link IDocumentExtension3#getContentType(String, int, bool)} when + * the document supports multiple partitionings. In that case this method is + * equivalent to: + *

                +     *    IDocumentExtension3 extension= cast(IDocumentExtension3) document;
                +     *    return extension.getContentType(IDocumentExtension3.DEFAULT_PARTITIONING, offset, false);
                +     * 
                + * + * @param offset the document offset + * @return the partition type + * @exception BadLocationException if offset is invalid in this document + */ + String getContentType(int offset) ; + + /** + * Returns the document partition in which the position is located. + *

                + * Use {@link IDocumentExtension3#getPartition(String, int, bool)} when + * the document supports multiple partitionings. In that case this method is + * equivalent: + *

                +     *    IDocumentExtension3 extension= cast(IDocumentExtension3) document;
                +     *    return extension.getPartition(IDocumentExtension3.DEFAULT_PARTITIONING, offset, false);
                +     * 
                + * + * @param offset the document offset + * @return a specification of the partition + * @exception BadLocationException if offset is invalid in this document + */ + ITypedRegion getPartition(int offset) ; + + /** + * Computes the partitioning of the given document range using the + * document's partitioner. + *

                + * Use {@link IDocumentExtension3#computePartitioning(String, int, int, bool)} when + * the document supports multiple partitionings. In that case this method is + * equivalent: + *

                +     *    IDocumentExtension3 extension= cast(IDocumentExtension3) document;
                +     *    return extension.computePartitioning(IDocumentExtension3.DEFAULT_PARTITIONING, offset, length, false);
                +     * 
                + * + * @param offset the document offset at which the range starts + * @param length the length of the document range + * @return a specification of the range's partitioning + * @exception BadLocationException if the range is invalid in this document + */ + ITypedRegion[] computePartitioning(int offset, int length) ; + + /** + * Registers the document partitioning listener with the document. After registration + * the document partitioning listener is informed about each partition change + * cause by a document manipulation or by changing the document's partitioner. + * If a document partitioning listener is also + * a document listener, the following notification sequence is guaranteed if a + * document manipulation changes the document partitioning: + *
                  + *
                • listener.documentAboutToBeChanged(DocumentEvent); + *
                • listener.documentPartitioningChanged(); + *
                • listener.documentChanged(DocumentEvent); + *
                + * If the listener is already registered nothing happens.

                + * An IDocumentPartitioningListener may call back to this method + * when being inside a document notification. + * + * @param listener the listener to be added + */ + void addDocumentPartitioningListener(IDocumentPartitioningListener listener); + + /** + * Removes the listener from this document's list of document partitioning + * listeners. If the listener is not registered with the document nothing + * happens.

                + * An IDocumentPartitioningListener may call back to this method + * when being inside a document notification. + * + * @param listener the listener to be removed + */ + void removeDocumentPartitioningListener(IDocumentPartitioningListener listener); + + /** + * Sets this document's partitioner. The caller of this method is responsible for + * disconnecting the document's old partitioner from the document and to + * connect the new partitioner to the document. Informs all document partitioning + * listeners about this change. + *

                + * Use {@link IDocumentExtension3#setDocumentPartitioner(String, IDocumentPartitioner)} when + * the document supports multiple partitionings. In that case this method is equivalent to: + *

                +     *    IDocumentExtension3 extension= cast(IDocumentExtension3) document;
                +     *    extension.setDocumentPartitioner(IDocumentExtension3.DEFAULT_PARTITIONING, partitioner);
                +     * 
                + * + * @param partitioner the document's new partitioner + * + * @see IDocumentPartitioningListener + */ + void setDocumentPartitioner(IDocumentPartitioner partitioner); + + /** + * Returns this document's partitioner. + *

                + * Use {@link IDocumentExtension3#getDocumentPartitioner(String)} when + * the document supports multiple partitionings. In that case this method is + * equivalent to: + *

                +     *    IDocumentExtension3 extension= cast(IDocumentExtension3) document;
                +     *    return extension.getDocumentPartitioner(IDocumentExtension3.DEFAULT_PARTITIONING);
                +     * 
                + * + * @return this document's partitioner + */ + IDocumentPartitioner getDocumentPartitioner(); + + + + /* ---------------------- line information -------------------------------- */ + + /** + * Returns the length of the given line including the line's delimiter. + * + * @param line the line of interest + * @return the length of the line + * @exception BadLocationException if the line number is invalid in this document + */ + int getLineLength(int line) ; + + /** + * Returns the number of the line at which the character of the specified position is located. + * The first line has the line number 0. A new line starts directly after a line + * delimiter. (offset is document length) is a valid argument although there is no + * corresponding character. + * + * @param offset the document offset + * @return the number of the line + * @exception BadLocationException if the offset is invalid in this document + */ + int getLineOfOffset(int offset) ; + + /** + * Determines the offset of the first character of the given line. + * + * @param line the line of interest + * @return the document offset + * @exception BadLocationException if the line number is invalid in this document + */ + int getLineOffset(int line) ; + + /** + * Returns a description of the specified line. The line is described by its + * offset and its length excluding the line's delimiter. + * + * @param line the line of interest + * @return a line description + * @exception BadLocationException if the line number is invalid in this document + */ + IRegion getLineInformation(int line) ; + + /** + * Returns a description of the line at the given offset. + * The description contains the offset and the length of the line + * excluding the line's delimiter. + * + * @param offset the offset whose line should be described + * @return a region describing the line + * @exception BadLocationException if offset is invalid in this document + */ + IRegion getLineInformationOfOffset(int offset) ; + + /** + * Returns the number of lines in this document + * + * @return the number of lines in this document + */ + int getNumberOfLines(); + + /** + * Returns the number of lines which are occupied by a given text range. + * + * @param offset the offset of the specified text range + * @param length the length of the specified text range + * @return the number of lines occupied by the specified range + * @exception BadLocationException if specified range is invalid in this tracker + */ + int getNumberOfLines(int offset, int length) ; + + /** + * Computes the number of lines in the given text. For a given + * implementer of this interface this method returns the same + * result as set(text); getNumberOfLines(). + * + * @param text the text whose number of lines should be computed + * @return the number of lines in the given text + */ + int computeNumberOfLines(String text); + + + /* ------------------ line delimiter conversion --------------------------- */ + + /** + * Returns the document's legal line delimiters. + * + * @return the document's legal line delimiters + */ + String[] getLegalLineDelimiters(); + + /** + * Returns the line delimiter of that line or null if the + * line is not closed with a line delimiter. + * + * @param line the line of interest + * @return the line's delimiter or null if line does not have a delimiter + * @exception BadLocationException if the line number is invalid in this document + */ + String getLineDelimiter(int line) ; + + + /* ---------------------------- search ------------------------------------ */ + + /** + * Returns the offset of a given search string in the document based on a set of search criteria. + * + * @param startOffset document offset at which search starts + * @param findString the string to find + * @param forwardSearch the search direction + * @param caseSensitive indicates whether lower and upper case should be distinguished + * @param wholeWord indicates whether the findString should be limited by white spaces as + * defined by Character.isWhiteSpace + * @return the offset of the first occurrence of findString based on the parameters or -1 if no match is found + * @exception BadLocationException if startOffset is an invalid document offset + * @deprecated as of 3.0 search is provided by {@link FindReplaceDocumentAdapter} + */ + int search(int startOffset, String findString, bool forwardSearch, bool caseSensitive, bool wholeWord) ; +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDocumentAdapter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDocumentAdapter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,193 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IDocumentAdapter; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +import dwt.custom.StyledTextContent; + + +/** + * Adapts an {@link dwtx.jface.text.IDocument}to the + * {@link dwt.custom.StyledTextContent} interface. The document + * adapter is used by {@link dwtx.jface.text.TextViewer} to translate + * document changes into styled text content changes and vice versa. + *

                + * Clients may implement this interface and override + * TextViewer.createDocumentAdapter if they want to intercept the + * communication between the viewer's text widget and the viewer's document. + *

                + * In order to provide backward compatibility for clients of + * IDocumentAdapter, extension interfaces are used as a means of + * evolution. The following extension interfaces exist: + *

                  + *
                • {@link dwtx.jface.text.IDocumentAdapterExtension} since version + * 2.0 introducing a way of batching a sequence of document changes into a + * single styled text content notification
                • + *
                + * + * @see dwtx.jface.text.IDocumentAdapterExtension + * @see dwtx.jface.text.IDocument + */ +public interface IDocumentAdapter : StyledTextContent { + + /** + * Sets the adapters document. + * + * @param document the document to be adapted + */ + void setDocument(IDocument document); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDocumentAdapterExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDocumentAdapterExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IDocumentAdapterExtension; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + +/** + * Extension interface for {@link dwtx.jface.text.IDocumentAdapter}. + *

                + * Introduces the concepts of batching a series of document changes into a + * single styled text content change notification. Batching start when a client + * calls stopForwardingDocumentChanges. After that call this + * document adapter does not send out styled text content change notifications + * until resumeForwardingDocumentChanges is called. On + * resumeForwardingDocumentChanges, it sends out one styled text + * content change notification that covers all changes that have been applied to + * the document since calling stopForwardingDocumentChanges. + * + * @since 2.0 + */ +public interface IDocumentAdapterExtension { + + /** + * Stops forwarding document changes to the styled text. + */ + void stopForwardingDocumentChanges(); + + /** + * Resumes forwarding document changes to the styled text. + * Also forces the styled text to catch up with all the changes + * that have been applied since stopForwardingDocumentChanges + * has been called. + */ + void resumeForwardingDocumentChanges(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDocumentExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDocumentExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,235 @@ +/******************************************************************************* + * 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 + * 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.text.IDocumentExtension; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + +/** + * Extension interface for {@link dwtx.jface.text.IDocument}.

                + * + * It introduces the notion of sequentially rewriting a document. This is to tell a + * document that a sequence of non-overlapping replace operation is about to be + * performed. Implementers can use this knowledge for internal optimization.

                + * + * Is also introduces the concept of post notification replaces. This is, a document + * listener who is informed about a document change can cause a derived document + * change. As the listener is not allowed to directly modify the document, it can + * register a replace operation that is performed directly after all document listeners + * have been notified. + * + * @since 2.0 + */ +public interface IDocumentExtension { + + /** + * Interface for a post notification replace operation. + */ + public interface IReplace { + + /** + * Executes the replace operation on the given document. + * + * @param document the document to be changed + * @param owner the owner of this replace operation + */ + void perform(IDocument document, IDocumentListener owner); + } + + /** + * Callback for document listeners to be used inside documentChanged + * to register a post notification replace operation on the document notifying them. + * + * @param owner the owner of the replace operation + * @param replace the replace operation to be executed + * @exception UnsupportedOperationException if registerPostNotificationReplace + * is not supported by this document + */ + void registerPostNotificationReplace(IDocumentListener owner, IReplace replace) ; + + /** + * Stops the processing of registered post notification replace operations until + * resumePostNotificationProcessing is called. + */ + void stopPostNotificationProcessing(); + + /** + * Resumes the processing of post notification replace operations. If the queue of registered + * IDocumentExtension.IReplace objects is not empty, they are immediately processed if the + * document is not inside a replace operation. If the document is inside a replace operation, + * they are processed directly after the replace operation has finished. + */ + void resumePostNotificationProcessing(); + + /** + * Tells the document that it is about to be sequentially rewritten. That is a + * sequence of non-overlapping replace operations will be performed on it. The + * normalize flag indicates whether the rewrite is performed from + * the start of the document to its end or from an arbitrary start offset.

                + * + * The document is considered being in sequential rewrite mode as long as + * stopSequentialRewrite has not been called. + * + * @param normalize true if performed from the start to the end of the document + * @deprecated since 3.1. Use {@link IDocumentExtension4#startRewriteSession(DocumentRewriteSessionType)} instead. + */ + void startSequentialRewrite(bool normalize); + + /** + * Tells the document that the sequential rewrite has been finished. This method + * has only any effect if startSequentialRewrite has been called before. + * @deprecated since 3.1. Use {@link IDocumentExtension4#stopRewriteSession(DocumentRewriteSession)} instead. + */ + void stopSequentialRewrite(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDocumentExtension2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDocumentExtension2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,200 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IDocumentExtension2; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + +/** + * Extension interface for {@link dwtx.jface.text.IDocument}.

                + * + * It adds configuration methods to post notification replaces and document + * listener notification. + * + * @since 2.1 + */ +public interface IDocumentExtension2 { + + /** + * Tells the receiver to ignore calls to + * registerPostNotificationReplace until + * acceptPostNotificationReplaces is called. + */ + void ignorePostNotificationReplaces(); + + /** + * Tells the receiver to accept calls to + * registerPostNotificationReplace until + * ignorePostNotificationReplaces is called. + */ + void acceptPostNotificationReplaces(); + + /** + * Can be called prior to a replace operation. After the + * replace resumeListenerNotification must be + * called. The affect of these calls is that no document listener is notified + * until resumeListenerNotification is called. This allows clients + * to update structure before any listener is informed about the change.

                + * Listener notification can only be stopped for a single replace operation. + * Otherwise, document change notifications will be lost. + */ + void stopListenerNotification(); + + /** + * Resumes the notification of document listeners which must previously + * have been stopped by a call to stopListenerNotification. + */ + void resumeListenerNotification(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDocumentExtension3.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDocumentExtension3.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,302 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IDocumentExtension3; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Extension interface for {@link dwtx.jface.text.IDocument}. + *

                + * Adds the concept of multiple partitionings and the concept of zero-length + * partitions in conjunction with open and delimited partitions. A delimited + * partition has a well defined start delimiter and a well defined end + * delimiter. Between two delimited partitions there may be an open partition of + * length zero. + *

                + * + * In order to fulfill the contract of this interface, the document must be + * configured with a document partitioner implementing + * {@link dwtx.jface.text.IDocumentPartitionerExtension2}. + * + * @see dwtx.jface.text.IDocumentPartitionerExtension2 + * @since 3.0 + */ +public interface IDocumentExtension3 { + + /** + * The identifier of the default partitioning. + */ + final static String DEFAULT_PARTITIONING= "__dftl_partitioning"; //$NON-NLS-1$ + + + /** + * Returns the existing partitionings for this document. This includes + * the default partitioning. + * + * @return the existing partitionings for this document + */ + String[] getPartitionings(); + + /** + * Returns the set of legal content types of document partitions for the given partitioning + * This set can be empty. The set can contain more content types than contained by the + * result of getPartitioning(partitioning, 0, getLength()). + * + * @param partitioning the partitioning for which to return the legal content types + * @return the set of legal content types + * @exception BadPartitioningException if partitioning is invalid for this document + */ + String[] getLegalContentTypes(String partitioning) ; + + + /** + * Returns the type of the document partition containing the given offset + * for the given partitioning. This is a convenience method for + * getPartition(partitioning, offset, bool).getType(). + *

                + * If preferOpenPartitions is true, + * precedence is given to an open partition ending at offset + * over a delimited partition starting at offset. If it is + * false, precedence is given to the partition that does not + * end at offset. + *

                + * This is only supported if the connected IDocumentPartitioner + * supports it, i.e. implements IDocumentPartitionerExtension2. + * Otherwise, preferOpenPartitions is ignored. + *

                + * + * @param partitioning the partitioning + * @param offset the document offset + * @param preferOpenPartitions true if precedence should be + * given to a open partition ending at offset over a + * closed partition starting at offset + * @return the partition type + * @exception BadLocationException if offset is invalid in this document + * @exception BadPartitioningException if partitioning is invalid for this document + */ + String getContentType(String partitioning, int offset, bool preferOpenPartitions); + + /** + * Returns the document partition of the given partitioning in which the + * given offset is located. + *

                + * If preferOpenPartitions is true, + * precedence is given to an open partition ending at offset + * over a delimited partition starting at offset. If it is + * false, precedence is given to the partition that does not + * end at offset. + *

                + * This is only supported if the connected IDocumentPartitioner + * supports it, i.e. implements IDocumentPartitionerExtension2. + * Otherwise, preferOpenPartitions is ignored. + *

                + * + * @param partitioning the partitioning + * @param offset the document offset + * @param preferOpenPartitions true if precedence should be + * given to a open partition ending at offset over a + * closed partition starting at offset + * @return a specification of the partition + * @exception BadLocationException if offset is invalid in this document + * @exception BadPartitioningException if partitioning is invalid for this document + */ + ITypedRegion getPartition(String partitioning, int offset, bool preferOpenPartitions); + + /** + * Computes the partitioning of the given document range based on the given + * partitioning type. + *

                + * If includeZeroLengthPartitions is true, a + * zero-length partition of an open partition type (usually the default + * partition) is included between two closed partitions. If it is + * false, no zero-length partitions are included. + *

                + * This is only supported if the connected IDocumentPartitioner + * supports it, i.e. implements IDocumentPartitionerExtension2. + * Otherwise, includeZeroLengthPartitions is ignored. + *

                + * + * @param partitioning the document's partitioning type + * @param offset the document offset at which the range starts + * @param length the length of the document range + * @param includeZeroLengthPartitions true if zero-length + * partitions should be returned as part of the computed partitioning + * @return a specification of the range's partitioning + * @exception BadLocationException if the range is invalid in this document$ + * @exception BadPartitioningException if partitioning is invalid for this document + */ + ITypedRegion[] computePartitioning(String partitioning, int offset, int length, bool includeZeroLengthPartitions); + + /** + * Sets this document's partitioner. The caller of this method is responsible for + * disconnecting the document's old partitioner from the document and to + * connect the new partitioner to the document. Informs all document partitioning + * listeners about this change. + * + * @param partitioning the partitioning for which to set the partitioner + * @param partitioner the document's new partitioner + * @see IDocumentPartitioningListener + */ + void setDocumentPartitioner(String partitioning, IDocumentPartitioner partitioner); + + /** + * Returns the partitioner for the given partitioning or null if + * no partitioner is registered. + * + * @param partitioning the partitioning for which to set the partitioner + * @return the partitioner for the given partitioning + */ + IDocumentPartitioner getDocumentPartitioner(String partitioning); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDocumentExtension4.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDocumentExtension4.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,299 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IDocumentExtension4; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Extension interface for {@link dwtx.jface.text.IDocument}. It adds the + * following concepts: + *
                  + *
                • Rewrite sessions. A rewrite session is a sequence of replace operations + * that form a semantic unit.
                • + *
                • A modification stamp on the document
                • + *
                • The ability to set the initial line delimiter and to query the default + * line delimiter
                • + *
                + * + * @since 3.1 + */ +public interface IDocumentExtension4 { + + /** + * Tells the document that it is about to be rewritten. That is, a sequence + * of replace operations that form a semantic unit will be performed on this + * document. A specification of the nature of the operation sequence is + * given in form of the session type. + *

                + * The document is considered being in rewrite mode as long as + * stopRewriteSession has not been called. + * + * @param sessionType the session type + * @return the started rewrite session + * @throws IllegalStateException in case there is already an active rewrite session + */ + DocumentRewriteSession startRewriteSession(DocumentRewriteSessionType sessionType) ; + + /** + * Tells the document to stop the rewrite session. This method has only any + * effect if startRewriteSession has been called before. + *

                + * This method does not have any effect if the given session is not the + * active rewrite session. + * + * @param session the session to stop + */ + void stopRewriteSession(DocumentRewriteSession session); + + /** + * Returns the active rewrite session of this document or null. + * + * @return the active rewrite session or null + */ + DocumentRewriteSession getActiveRewriteSession(); + + /** + * Registers the document rewrite session listener with the document. After + * registration the IDocumentRewriteSessionListener is + * informed about each state change of rewrite sessions performed on this + * document. + *

                + * If the listener is already registered nothing happens. + *

                + * An IRewriteSessionDocumentListener may call back to this + * document when being inside a document notification. + * + * @param listener the listener to be registered + */ + void addDocumentRewriteSessionListener(IDocumentRewriteSessionListener listener); + + /** + * Removes the listener from the document's list of document rewrite session + * listeners. If the listener is not registered with the document nothing + * happens. + *

                + * An IDocumentRewriteSessionListener may call back to this + * document when being inside a document notification. + * + * @param listener the listener to be removed + */ + void removeDocumentRewriteSessionListener(IDocumentRewriteSessionListener listener); + + /** + * Substitutes the given text for the specified document range. + * Sends a DocumentEvent to all registered IDocumentListener. + * + * @param offset the document offset + * @param length the length of the specified range + * @param text the substitution text + * @param modificationStamp of the document after replacing + * @exception BadLocationException if the offset is invalid in this document + * + * @see DocumentEvent + * @see IDocumentListener + */ + void replace(int offset, int length, String text, long modificationStamp) ; + + /** + * Replaces the content of the document with the given text. + * Sends a DocumentEvent to all registered IDocumentListener. + * This method is a convenience method for replace(0, getLength(), text). + * + * @param text the new content of the document + * @param modificationStamp of the document after setting the content + * + * @see DocumentEvent + * @see IDocumentListener + */ + void set(String text, long modificationStamp); + + /** + * The unknown modification stamp. + */ + static const long UNKNOWN_MODIFICATION_STAMP= -1; + + /** + * Returns the modification stamp of this document. The modification stamp + * is updated each time a modifying operation is called on this document. If + * two modification stamps of the same document are identical then the document + * content is too, however, same content does not imply same modification stamp. + *

                + * The magnitude or sign of the numerical difference between two modification stamps + * is not significant. + *

                + * + * @return the modification stamp of this document or UNKNOWN_MODIFICATION_STAMP + */ + long getModificationStamp(); + + /** + * Returns this document's default line delimiter. + *

                + * This default line delimiter should be used by clients who + * want unique delimiters (e.g. 'CR's) in the document.

                + * + * @return the default line delimiter or null if none + */ + String getDefaultLineDelimiter(); + + /** + * Sets this document's initial line delimiter i.e. the one + * which is returned by getDefaultLineDelimiter + * if the document does not yet contain any line delimiter. + * + * @param lineDelimiter the default line delimiter + */ + void setInitialLineDelimiter(String lineDelimiter); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDocumentInformationMapping.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDocumentInformationMapping.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,269 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IDocumentInformationMapping; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * A IDocumentInformationMapping represents a mapping between the coordinates of two + * IDocument objects: the original and the image. The document information mapping + * can translate document information such as line numbers or character ranges given for the original into + * the corresponding information of the image and vice versa. + * + * In order to provided backward compatibility for clients of IDocumentInformationMapping, extension + * interfaces are used to provide a means of evolution. The following extension interfaces + * exist: + *
                  + *
                • {@link dwtx.jface.text.IDocumentInformationMappingExtension} since version 3.0 extending the + * degree of detail of the mapping information.
                • + *
                • {@link dwtx.jface.text.IDocumentInformationMappingExtension2} since version 3.1, adding lenient + * image region computation.
                • + *
                + * + * @since 2.1 + */ +public interface IDocumentInformationMapping { + + /** + * Returns the minimal region of the original document that completely comprises all of the image document + * or null if there is no such region. + * + * @return the minimal region of the original document comprising the image document or null + */ + IRegion getCoverage(); + + /** + * Returns the offset in the original document that corresponds to the given offset in the image document + * or -1 if there is no such offset + * + * @param imageOffset the offset in the image document + * @return the corresponding offset in the original document or -1 + * @throws BadLocationException if imageOffset is not a valid offset in the image document + */ + int toOriginOffset(int imageOffset) ; + + /** + * Returns the minimal region of the original document that completely comprises the given region of the + * image document or null if there is no such region. + * + * @param imageRegion the region of the image document + * @return the minimal region of the original document comprising the given region of the image document or null + * @throws BadLocationException if imageRegion is not a valid region of the image document + */ + IRegion toOriginRegion(IRegion imageRegion) ; + + /** + * Returns the range of lines of the original document that corresponds to the given line of the image document or + * null if there are no such lines. + * + * @param imageLine the line of the image document + * @return the corresponding lines of the original document or null + * @throws BadLocationException if imageLine is not a valid line number in the image document + */ + IRegion toOriginLines(int imageLine) ; + + /** + * Returns the line of the original document that corresponds to the given line of the image document or + * -1 if there is no such line. + * + * @param imageLine the line of the image document + * @return the corresponding line of the original document or -1 + * @throws BadLocationException if imageLine is not a valid line number in the image document + */ + int toOriginLine(int imageLine) ; + + + + /** + * Returns the offset in the image document that corresponds to the given offset in the original document + * or -1 if there is no such offset + * + * @param originOffset the offset in the original document + * @return the corresponding offset in the image document or -1 + * @throws BadLocationException if originOffset is not a valid offset in the original document + */ + int toImageOffset(int originOffset) ; + + /** + * Returns the minimal region of the image document that completely comprises the given region of the + * original document or null if there is no such region. + * + * @param originRegion the region of the original document + * @return the minimal region of the image document comprising the given region of the original document or null + * @throws BadLocationException if originRegion is not a valid region of the original document + */ + IRegion toImageRegion(IRegion originRegion) ; + + /** + * Returns the line of the image document that corresponds to the given line of the original document or + * -1 if there is no such line. + * + * @param originLine the line of the original document + * @return the corresponding line of the image document or -1 + * @throws BadLocationException if originLine is not a valid line number in the original document + */ + int toImageLine(int originLine) ; + + /** + * Returns the line of the image document whose corresponding line in the original document + * is closest to the given line in the original document. + * + * @param originLine the line in the original document + * @return the line in the image document that corresponds best to the given line in the original document + * @throws BadLocationException if originLineis not a valid line in the original document + */ + int toClosestImageLine(int originLine) ; +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDocumentInformationMappingExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDocumentInformationMappingExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,225 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IDocumentInformationMappingExtension; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Extension to {@link dwtx.jface.text.IDocumentInformationMapping}. + *

                + * Extends the information available in the mapping by providing explicit access + * to the isomorphic portion of the basically homomorphic information mapping. + * + * @see dwtx.jface.text.IDocumentInformationMapping + * @since 3.0 + */ +public interface IDocumentInformationMappingExtension { + + /** + * Adheres to + * originRegion=toOriginRegion(toExactImageRegion(originRegion)), + * if toExactImageRegion(originRegion) !is null. Returns + * null if there is no image for the given origin region. + * + * @param originRegion the origin region + * @return the exact image region or null + * @throws BadLocationException if origin region is not a valid region in + * the origin document + */ + IRegion toExactImageRegion(IRegion originRegion) ; + + /** + * Returns the segments of the image document that exactly correspond to the + * given region of the original document. Returns null if + * there are no such image regions. + * + * @param originRegion the region in the origin document + * @return the segments in the image document or null + * @throws BadLocationException in case the given origin region is not valid + * in the original document + */ + IRegion[] toExactImageRegions(IRegion originRegion) ; + + /** + * Returns the fragments of the original document that exactly correspond to + * the given region of the image document. + * + * @param imageRegion the region in the image document + * @return the fragments in the origin document + * @throws BadLocationException in case the given image region is not valid + * in the image document + */ + IRegion[] toExactOriginRegions(IRegion imageRegion) ; + + /** + * Returns the length of the image document. + * + * @return the length of the image document + */ + int getImageLength(); + + /** + * Returns the maximal sub-regions of the given origin region which are + * completely covered. I.e. each offset in a sub-region has a corresponding + * image offset. Returns null if there are no such + * sub-regions. + * + * @param originRegion the region in the origin document + * @return the sub-regions with complete coverage or null + * @throws BadLocationException in case the given origin region is not valid + * in the original document + */ + IRegion[] getExactCoverage(IRegion originRegion) ; +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDocumentInformationMappingExtension2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDocumentInformationMappingExtension2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,187 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IDocumentInformationMappingExtension2; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Extension to {@link dwtx.jface.text.IDocumentInformationMapping}. + *

                + * Extends the information available in the mapping by providing access + * to the closest image region of an origin region. + *

                + * + * @see dwtx.jface.text.IDocumentInformationMapping + * @since 3.1 + */ +public interface IDocumentInformationMappingExtension2 { + + /** + * Returns the minimal region of the image document that completely + * comprises the given region of the original document. The difference to + * {@link IDocumentInformationMapping#toImageRegion(IRegion)} is that this + * method will always return an image region for a valid origin region. If + * originRegion has no corresponding image region, the + * zero-length region at the offset between its surrounding fragments is + * returned. + * + * @param originRegion the region of the original document + * @return the minimal region of the image document comprising the given + * region of the original document + * @throws BadLocationException if originRegion is not a + * valid region of the original document + */ + IRegion toClosestImageRegion(IRegion originRegion) ; +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDocumentListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDocumentListener.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IDocumentListener; + +import dwtx.jface.text.DocumentEvent; // packageimport + +import dwt.dwthelper.utils; + + + +/** + * Interface for objects which are interested in getting informed about + * document changes. A listener is informed about document changes before + * they are applied and after they have been applied. It is ensured that + * the document event passed into the listener is the same for the two + * notifications, i.e. the two document events can be checked using object identity. + *

                + * Clients may implement this interface. + *

                + * + * @see dwtx.jface.text.IDocument + */ +public interface IDocumentListener { + + + /** + * The manipulation described by the document event will be performed. + * + * @param event the document event describing the document change + */ + void documentAboutToBeChanged(DocumentEvent event); + + /** + * The manipulation described by the document event has been performed. + * + * @param event the document event describing the document change + */ + void documentChanged(DocumentEvent event); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDocumentPartitioner.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDocumentPartitioner.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,307 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IDocumentPartitioner; + +// import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +// import dwtx.jface.text.DefaultTextHover; // packageimport +// import dwtx.jface.text.AbstractInformationControl; // packageimport +// import dwtx.jface.text.TextUtilities; // packageimport +// import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +// import dwtx.jface.text.AbstractInformationControlManager; // packageimport +// import dwtx.jface.text.ITextViewerExtension2; // packageimport +// import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +// import dwtx.jface.text.ITextSelection; // packageimport +// import dwtx.jface.text.Document; // packageimport +// import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +// import dwtx.jface.text.ITextListener; // packageimport +// import dwtx.jface.text.BadPartitioningException; // packageimport +// import dwtx.jface.text.ITextViewerExtension5; // packageimport +// import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +// import dwtx.jface.text.IUndoManager; // packageimport +// import dwtx.jface.text.ITextHoverExtension2; // packageimport +// import dwtx.jface.text.IRepairableDocument; // packageimport +// import dwtx.jface.text.IRewriteTarget; // packageimport +// import dwtx.jface.text.DefaultPositionUpdater; // packageimport +// import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +// import dwtx.jface.text.TextViewerHoverManager; // packageimport +// import dwtx.jface.text.DocumentRewriteSession; // packageimport +// import dwtx.jface.text.TextViewer; // packageimport +// import dwtx.jface.text.ITextViewerExtension8; // packageimport +// import dwtx.jface.text.RegExMessages; // packageimport +// import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +// import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +// import dwtx.jface.text.IWidgetTokenOwner; // packageimport +// import dwtx.jface.text.IViewportListener; // packageimport +// import dwtx.jface.text.GapTextStore; // packageimport +// import dwtx.jface.text.MarkSelection; // packageimport +// import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +// import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +// import dwtx.jface.text.IInformationControlExtension; // packageimport +// import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +// import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +// import dwtx.jface.text.ITextViewerExtension3; // packageimport +// import dwtx.jface.text.IInformationControlCreator; // packageimport +// import dwtx.jface.text.TypedRegion; // packageimport +// import dwtx.jface.text.ISynchronizable; // packageimport +// import dwtx.jface.text.IMarkRegionTarget; // packageimport +// import dwtx.jface.text.TextViewerUndoManager; // packageimport +// import dwtx.jface.text.IRegion; // packageimport +// import dwtx.jface.text.IInformationControlExtension2; // packageimport +// import dwtx.jface.text.IDocumentExtension4; // packageimport +// import dwtx.jface.text.IDocumentExtension2; // packageimport +// import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +// import dwtx.jface.text.Assert; // packageimport +// import dwtx.jface.text.DefaultInformationControl; // packageimport +// import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +// import dwtx.jface.text.DocumentClone; // packageimport +// import dwtx.jface.text.DefaultUndoManager; // packageimport +// import dwtx.jface.text.IFindReplaceTarget; // packageimport +// import dwtx.jface.text.IAutoEditStrategy; // packageimport +// import dwtx.jface.text.ILineTrackerExtension; // packageimport +// import dwtx.jface.text.IUndoManagerExtension; // packageimport +// import dwtx.jface.text.TextSelection; // packageimport +// import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +// import dwtx.jface.text.IAutoIndentStrategy; // packageimport +// import dwtx.jface.text.IPainter; // packageimport +// import dwtx.jface.text.IInformationControl; // packageimport +// import dwtx.jface.text.IInformationControlExtension3; // packageimport +// import dwtx.jface.text.ITextViewerExtension6; // packageimport +// import dwtx.jface.text.IInformationControlExtension4; // packageimport +// import dwtx.jface.text.DefaultLineTracker; // packageimport +// import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +// import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +// import dwtx.jface.text.ITextHover; // packageimport +// import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +// import dwtx.jface.text.ILineTracker; // packageimport +// import dwtx.jface.text.Line; // packageimport +// import dwtx.jface.text.ITextViewerExtension; // packageimport +// import dwtx.jface.text.IDocumentAdapter; // packageimport +// import dwtx.jface.text.TextEvent; // packageimport +// import dwtx.jface.text.BadLocationException; // packageimport +// import dwtx.jface.text.AbstractDocument; // packageimport +// import dwtx.jface.text.AbstractLineTracker; // packageimport +// import dwtx.jface.text.TreeLineTracker; // packageimport +// import dwtx.jface.text.ITextPresentationListener; // packageimport +// import dwtx.jface.text.Region; // packageimport +// import dwtx.jface.text.ITextViewer; // packageimport +// import dwtx.jface.text.IDocumentInformationMapping; // packageimport +// import dwtx.jface.text.MarginPainter; // packageimport +// import dwtx.jface.text.IPaintPositionManager; // packageimport +// import dwtx.jface.text.TextPresentation; // packageimport +// import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +// import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +// import dwtx.jface.text.ISelectionValidator; // packageimport +// import dwtx.jface.text.IDocumentExtension; // packageimport +// import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +// import dwtx.jface.text.ConfigurableLineTracker; // packageimport +// import dwtx.jface.text.SlaveDocumentEvent; // packageimport +// import dwtx.jface.text.IDocumentListener; // packageimport +// import dwtx.jface.text.PaintManager; // packageimport +// import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +// import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +// import dwtx.jface.text.IDocumentExtension3; // packageimport +// import dwtx.jface.text.Position; // packageimport +// import dwtx.jface.text.TextMessages; // packageimport +// import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +// import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +// import dwtx.jface.text.IPositionUpdater; // packageimport +// import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +// import dwtx.jface.text.ListLineTracker; // packageimport +// import dwtx.jface.text.ITextInputListener; // packageimport +// import dwtx.jface.text.BadPositionCategoryException; // packageimport +// import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +// import dwtx.jface.text.IInputChangedListener; // packageimport +// import dwtx.jface.text.ITextOperationTarget; // packageimport +// import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +// import dwtx.jface.text.ITextViewerExtension7; // packageimport +// import dwtx.jface.text.IInformationControlExtension5; // packageimport +// import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +// import dwtx.jface.text.JFaceTextUtil; // packageimport +// import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +// import dwtx.jface.text.TabsToSpacesConverter; // packageimport +// import dwtx.jface.text.CursorLinePainter; // packageimport +// import dwtx.jface.text.ITextHoverExtension; // packageimport +// import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +// import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +// import dwtx.jface.text.DocumentCommand; // packageimport +// import dwtx.jface.text.TypedPosition; // packageimport +// import dwtx.jface.text.IEditingSupportRegistry; // packageimport +// import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +// import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +// import dwtx.jface.text.IEditingSupport; // packageimport +// import dwtx.jface.text.IMarkSelection; // packageimport +// import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +// import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +// import dwtx.jface.text.ITextStore; // packageimport +// import dwtx.jface.text.JFaceTextMessages; // packageimport +// import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +// import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +// import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +// import dwtx.jface.text.TextAttribute; // packageimport +// import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + + +/** + * A document partitioner divides a document into a set + * of disjoint text partitions. Each partition has a content type, an + * offset, and a length. The document partitioner is connected to one document + * and informed about all changes of this document before any of the + * document's document listeners. A document partitioner can thus + * incrementally update on the receipt of a document change event.

                + * + * In order to provided backward compatibility for clients of IDocumentPartitioner, extension + * interfaces are used to provide a means of evolution. The following extension interfaces + * exist: + *

                  + *
                • {@link dwtx.jface.text.IDocumentPartitionerExtension} since version 2.0 replacing + * the documentChanged method with a new one returning the minimal document region + * comprising all partition changes.
                • + *
                • {@link dwtx.jface.text.IDocumentPartitionerExtension2} since version 3.0 + * introducing zero-length partitions in conjunction with the distinction between + * open and closed partitions. Also provides inside in the implementation of the partitioner + * by exposing the position category used for managing the partitioning information.
                • + *
                • {@link dwtx.jface.text.IDocumentPartitionerExtension3} since version 3.1 introducing + * rewrite session. It also replaces the existing {@link #connect(IDocument)} method with + * a new one: {@link dwtx.jface.text.IDocumentPartitionerExtension3#connect(IDocument, bool)}. + *
                + *

                + * Clients may implement this interface and its extension interfaces or use the standard + * implementation DefaultPartitioner. + *

                + * + * @see dwtx.jface.text.IDocumentPartitionerExtension + * @see dwtx.jface.text.IDocumentPartitionerExtension2 + * @see dwtx.jface.text.IDocument + */ +public interface IDocumentPartitioner { + + /** + * Connects the partitioner to a document. + * Connect indicates the begin of the usage of the receiver + * as partitioner of the given document. Thus, resources the partitioner + * needs to be operational for this document should be allocated.

                + * + * The caller of this method must ensure that this partitioner is + * also set as the document's document partitioner.

                + * + * This method has been replaced with {@link IDocumentPartitionerExtension3#connect(IDocument, bool)}. + * Implementers should default a call connect(document) to + * connect(document, false) in order to sustain the same semantics. + * + * @param document the document to be connected to + */ + void connect(IDocument document); + + /** + * Disconnects the partitioner from the document it is connected to. + * Disconnect indicates the end of the usage of the receiver as + * partitioner of the connected document. Thus, resources the partitioner + * needed to be operation for its connected document should be deallocated.

                + * The caller of this method should also must ensure that this partitioner is + * no longer the document's partitioner. + */ + void disconnect(); + + /** + * Informs about a forthcoming document change. Will be called by the + * connected document and is not intended to be used by clients + * other than the connected document. + * + * @param event the event describing the forthcoming change + */ + void documentAboutToBeChanged(DocumentEvent event); + + /** + * The document has been changed. The partitioner updates + * the document's partitioning and returns whether the structure of the + * document partitioning has been changed, i.e. whether partitions + * have been added or removed. Will be called by the connected document and + * is not intended to be used by clients other than the connected document.

                + * + * This method has been replaced by {@link IDocumentPartitionerExtension#documentChanged2(DocumentEvent)}. + * + * @param event the event describing the document change + * @return true if partitioning changed + */ + bool documentChanged(DocumentEvent event); + + /** + * Returns the set of all legal content types of this partitioner. + * I.e. any result delivered by this partitioner may not contain a content type + * which would not be included in this method's result. + * + * @return the set of legal content types + */ + String[] getLegalContentTypes(); + + /** + * Returns the content type of the partition containing the + * given offset in the connected document. There must be a + * document connected to this partitioner.

                + * + * Use {@link IDocumentPartitionerExtension2#getContentType(int, bool)} when + * zero-length partitions are supported. In that case this method is + * equivalent: + *

                +     *    IDocumentPartitionerExtension2 extension= cast(IDocumentPartitionerExtension2) partitioner;
                +     *    return extension.getContentType(offset, false);
                +     * 
                + * + * @param offset the offset in the connected document + * @return the content type of the offset's partition + */ + String getContentType(int offset); + + /** + * Returns the partitioning of the given range of the connected + * document. There must be a document connected to this partitioner.

                + * + * Use {@link IDocumentPartitionerExtension2#computePartitioning(int, int, bool)} when + * zero-length partitions are supported. In that case this method is + * equivalent: + *

                +     *    IDocumentPartitionerExtension2 extension= cast(IDocumentPartitionerExtension2) partitioner;
                +     *    return extension.computePartitioning(offset, length, false);
                +     * 
                + * + * @param offset the offset of the range of interest + * @param length the length of the range of interest + * @return the partitioning of the range + */ + ITypedRegion[] computePartitioning(int offset, int length); + + /** + * Returns the partition containing the given offset of + * the connected document. There must be a document connected to this + * partitioner.

                + * + * Use {@link IDocumentPartitionerExtension2#getPartition(int, bool)} when + * zero-length partitions are supported. In that case this method is + * equivalent: + *

                +     *    IDocumentPartitionerExtension2 extension= cast(IDocumentPartitionerExtension2) partitioner;
                +     *    return extension.getPartition(offset, false);
                +     * 
                + * + * @param offset the offset for which to determine the partition + * @return the partition containing the offset + */ + ITypedRegion getPartition(int offset); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDocumentPartitionerExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDocumentPartitionerExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,190 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IDocumentPartitionerExtension; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + + +/** + * Extension interface for {@link dwtx.jface.text.IDocumentPartitioner}. + *

                + * Replaces the original concept of the document partitioner by returning the + * minimal region that includes all partition changes caused by the invocation + * of the document partitioner. + * The method documentChanged2 is considered the replacement of + * {@link dwtx.jface.text.IDocumentPartitioner#documentChanged(DocumentEvent)}. + * + * @since 2.0 + */ +public interface IDocumentPartitionerExtension { + + /** + * The document has been changed. The partitioner updates the document's + * partitioning and returns the minimal region that comprises all partition + * changes caused in response to the given document event. This method + * returns null if the partitioning did not change. + *

                + * + * Will be called by the connected document and is not intended to be used + * by clients other than the connected document. + *

                + * Replaces {@link IDocumentPartitioner#documentChanged(DocumentEvent)}. + * + * @param event the event describing the document change + * @return the region of the document in which the partition type changed or null + */ + IRegion documentChanged2(DocumentEvent event); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDocumentPartitionerExtension2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDocumentPartitionerExtension2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,265 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IDocumentPartitionerExtension2; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + + +/** + * Extension interface for {@link dwtx.jface.text.IDocumentPartitioner}. + *

                + * Extends the original concept of a document partitioner to answer the position + * categories that are used to manage the partitioning information. + *

                + * This extension also introduces the concept of open and delimited partitions. + * A delimited partition has a predefined textual token delimiting its start and + * end, while an open partition can fill any space between two delimited + * partitions. + *

                + *

                + * An open partition of length zero can occur between two delimited partitions, + * thus having the same offset as the following delimited partition. The + * document start and end are considered to be delimiters of open partitions, + * i.e. there may be a zero-length partition between the document start and a + * delimited partition starting at offset 0. + *

                + * + * @since 3.0 + */ +public interface IDocumentPartitionerExtension2 { + + /** + * Returns the position categories that this partitioners uses in order to manage + * the partitioning information of the documents. Returns null if + * no position category is used. + * + * @return the position categories used to manage partitioning information or null + */ + String[] getManagingPositionCategories(); + + + /* zero-length partition support */ + + /** + * Returns the content type of the partition containing the given offset in + * the connected document. There must be a document connected to this + * partitioner. + *

                + * If preferOpenPartitions is true, + * precedence is given to an open partition ending at offset + * over a delimited partition starting at offset. + *

                + * This method replaces {@link IDocumentPartitioner#getContentType(int)}and + * behaves like it when prepreferOpenPartitions is + * false, i.e. precedence is always given to the partition + * that does not end at offset. + *

                + * + * @param offset the offset in the connected document + * @param preferOpenPartitions true if precedence should be + * given to a open partition ending at offset over + * a delimited partition starting at offset + * @return the content type of the offset's partition + */ + String getContentType(int offset, bool preferOpenPartitions); + + /** + * Returns the partition containing the given offset of the connected + * document. There must be a document connected to this partitioner. + *

                + * If preferOpenPartitions is true, + * precedence is given to an open partition ending at offset + * over a delimited partition starting at offset. + *

                + * This method replaces {@link IDocumentPartitioner#getPartition(int)}and + * behaves like it when is false + * , i.e. precedence is always given to the partition that does not + * end at offset. + *

                + * + * @param offset the offset for which to determine the partition + * @param preferOpenPartitions true if precedence should be + * given to a open partition ending at offset over + * a delimited partition starting at offset + * @return the partition containing the offset + */ + ITypedRegion getPartition(int offset, bool preferOpenPartitions); + + /** + * Returns the partitioning of the given range of the connected document. + * There must be a document connected to this partitioner. + *

                + * If includeZeroLengthPartitions is true, a + * zero-length partition of an open partition type (usually the default + * partition) is included between two delimited partitions. If it is + * false, no zero-length partitions are included. + *

                + *

                + * This method replaces + * {@link IDocumentPartitioner#computePartitioning(int, int)}and behaves + * like it when includeZeroLengthPartitions is + * false. + *

                + * + * @param offset the offset of the range of interest + * @param length the length of the range of interest + * @param includeZeroLengthPartitions true if zero-length + * partitions should be returned as part of the computed + * partitioning + * @return the partitioning of the range + */ + ITypedRegion[] computePartitioning(int offset, int length, bool includeZeroLengthPartitions); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDocumentPartitionerExtension3.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDocumentPartitionerExtension3.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,216 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IDocumentPartitionerExtension3; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + + +/** + * Extension interface for {@link dwtx.jface.text.IDocumentPartitioner}. Adds the + * concept of rewrite sessions. A rewrite session is a sequence of replace + * operations that form a semantic unit. + * + * @since 3.1 + */ +public interface IDocumentPartitionerExtension3 { + + /** + * Tells the document partitioner that a rewrite session started. A rewrite + * session is a sequence of replace operations that form a semantic unit. + * The document partitioner is allowed to use that information for internal + * optimization. + * + * @param session the rewrite session + * @throws IllegalStateException in case there is already an active rewrite session + */ + void startRewriteSession(DocumentRewriteSession session) ; + + /** + * Tells the document partitioner that the rewrite session has finished. + * This method is only called when startRewriteSession has + * been called before. + * + * @param session the rewrite session + */ + void stopRewriteSession(DocumentRewriteSession session); + + /** + * Returns the active rewrite session of this document or null. + * + * @return the active rewrite session or null + */ + DocumentRewriteSession getActiveRewriteSession(); + + /** + * Connects this partitioner to a document. Connect indicates the begin of + * the usage of the receiver as partitioner of the given document. Thus, + * resources the partitioner needs to be operational for this document + * should be allocated. + *

                + * The caller of this method must ensure that this partitioner is also set + * as the document's document partitioner. + *

                + * delayInitialization indicates whether the partitioner is + * allowed to delay it initial computation of the document's partitioning + * until it has to answer the first query. + * + * Replaces {@link IDocumentPartitioner#connect(IDocument)}. + * + * @param document the document to be connected to + * @param delayInitialization true if initialization can be delayed, false otherwise + */ + void connect(IDocument document, bool delayInitialization); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDocumentPartitioningListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDocumentPartitioningListener.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,202 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IDocumentPartitioningListener; + +// import dwtx.jface.text.DefaultTextHover; // packageimport +// import dwtx.jface.text.AbstractInformationControl; // packageimport +// import dwtx.jface.text.TextUtilities; // packageimport +// import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +// import dwtx.jface.text.AbstractInformationControlManager; // packageimport +// import dwtx.jface.text.ITextViewerExtension2; // packageimport +// import dwtx.jface.text.IDocumentPartitioner; // packageimport +// import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +// import dwtx.jface.text.ITextSelection; // packageimport +// import dwtx.jface.text.Document; // packageimport +// import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +// import dwtx.jface.text.ITextListener; // packageimport +// import dwtx.jface.text.BadPartitioningException; // packageimport +// import dwtx.jface.text.ITextViewerExtension5; // packageimport +// import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +// import dwtx.jface.text.IUndoManager; // packageimport +// import dwtx.jface.text.ITextHoverExtension2; // packageimport +// import dwtx.jface.text.IRepairableDocument; // packageimport +// import dwtx.jface.text.IRewriteTarget; // packageimport +// import dwtx.jface.text.DefaultPositionUpdater; // packageimport +// import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +// import dwtx.jface.text.TextViewerHoverManager; // packageimport +// import dwtx.jface.text.DocumentRewriteSession; // packageimport +// import dwtx.jface.text.TextViewer; // packageimport +// import dwtx.jface.text.ITextViewerExtension8; // packageimport +// import dwtx.jface.text.RegExMessages; // packageimport +// import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +// import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +// import dwtx.jface.text.IWidgetTokenOwner; // packageimport +// import dwtx.jface.text.IViewportListener; // packageimport +// import dwtx.jface.text.GapTextStore; // packageimport +// import dwtx.jface.text.MarkSelection; // packageimport +// import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +// import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +// import dwtx.jface.text.IInformationControlExtension; // packageimport +// import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +// import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +// import dwtx.jface.text.ITextViewerExtension3; // packageimport +// import dwtx.jface.text.IInformationControlCreator; // packageimport +// import dwtx.jface.text.TypedRegion; // packageimport +// import dwtx.jface.text.ISynchronizable; // packageimport +// import dwtx.jface.text.IMarkRegionTarget; // packageimport +// import dwtx.jface.text.TextViewerUndoManager; // packageimport +// import dwtx.jface.text.IRegion; // packageimport +// import dwtx.jface.text.IInformationControlExtension2; // packageimport +// import dwtx.jface.text.IDocumentExtension4; // packageimport +// import dwtx.jface.text.IDocumentExtension2; // packageimport +// import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +// import dwtx.jface.text.Assert; // packageimport +// import dwtx.jface.text.DefaultInformationControl; // packageimport +// import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +// import dwtx.jface.text.DocumentClone; // packageimport +// import dwtx.jface.text.DefaultUndoManager; // packageimport +// import dwtx.jface.text.IFindReplaceTarget; // packageimport +// import dwtx.jface.text.IAutoEditStrategy; // packageimport +// import dwtx.jface.text.ILineTrackerExtension; // packageimport +// import dwtx.jface.text.IUndoManagerExtension; // packageimport +// import dwtx.jface.text.TextSelection; // packageimport +// import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +// import dwtx.jface.text.IAutoIndentStrategy; // packageimport +// import dwtx.jface.text.IPainter; // packageimport +// import dwtx.jface.text.IInformationControl; // packageimport +// import dwtx.jface.text.IInformationControlExtension3; // packageimport +// import dwtx.jface.text.ITextViewerExtension6; // packageimport +// import dwtx.jface.text.IInformationControlExtension4; // packageimport +// import dwtx.jface.text.DefaultLineTracker; // packageimport +// import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +// import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +// import dwtx.jface.text.ITextHover; // packageimport +// import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +// import dwtx.jface.text.ILineTracker; // packageimport +// import dwtx.jface.text.Line; // packageimport +// import dwtx.jface.text.ITextViewerExtension; // packageimport +// import dwtx.jface.text.IDocumentAdapter; // packageimport +// import dwtx.jface.text.TextEvent; // packageimport +// import dwtx.jface.text.BadLocationException; // packageimport +// import dwtx.jface.text.AbstractDocument; // packageimport +// import dwtx.jface.text.AbstractLineTracker; // packageimport +// import dwtx.jface.text.TreeLineTracker; // packageimport +// import dwtx.jface.text.ITextPresentationListener; // packageimport +// import dwtx.jface.text.Region; // packageimport +// import dwtx.jface.text.ITextViewer; // packageimport +// import dwtx.jface.text.IDocumentInformationMapping; // packageimport +// import dwtx.jface.text.MarginPainter; // packageimport +// import dwtx.jface.text.IPaintPositionManager; // packageimport +// import dwtx.jface.text.TextPresentation; // packageimport +// import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +// import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +// import dwtx.jface.text.ISelectionValidator; // packageimport +// import dwtx.jface.text.IDocumentExtension; // packageimport +// import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +// import dwtx.jface.text.ConfigurableLineTracker; // packageimport +// import dwtx.jface.text.SlaveDocumentEvent; // packageimport +// import dwtx.jface.text.IDocumentListener; // packageimport +// import dwtx.jface.text.PaintManager; // packageimport +// import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +// import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +// import dwtx.jface.text.IDocumentExtension3; // packageimport +// import dwtx.jface.text.Position; // packageimport +// import dwtx.jface.text.TextMessages; // packageimport +// import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +// import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +// import dwtx.jface.text.IPositionUpdater; // packageimport +// import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +// import dwtx.jface.text.ListLineTracker; // packageimport +// import dwtx.jface.text.ITextInputListener; // packageimport +// import dwtx.jface.text.BadPositionCategoryException; // packageimport +// import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +// import dwtx.jface.text.IInputChangedListener; // packageimport +// import dwtx.jface.text.ITextOperationTarget; // packageimport +// import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +// import dwtx.jface.text.ITextViewerExtension7; // packageimport +// import dwtx.jface.text.IInformationControlExtension5; // packageimport +// import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +// import dwtx.jface.text.JFaceTextUtil; // packageimport +// import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +// import dwtx.jface.text.TabsToSpacesConverter; // packageimport +// import dwtx.jface.text.CursorLinePainter; // packageimport +// import dwtx.jface.text.ITextHoverExtension; // packageimport +// import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +// import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +// import dwtx.jface.text.DocumentCommand; // packageimport +// import dwtx.jface.text.TypedPosition; // packageimport +// import dwtx.jface.text.IEditingSupportRegistry; // packageimport +// import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +// import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +// import dwtx.jface.text.IEditingSupport; // packageimport +// import dwtx.jface.text.IMarkSelection; // packageimport +// import dwtx.jface.text.ISlaveDocumentManager; // packageimport +// import dwtx.jface.text.DocumentEvent; // packageimport +// import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +// import dwtx.jface.text.ITextStore; // packageimport +// import dwtx.jface.text.JFaceTextMessages; // packageimport +// import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +// import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +// import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +// import dwtx.jface.text.TextAttribute; // packageimport +// import dwtx.jface.text.ITextViewerExtension4; // packageimport +// import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + + +/** + * Interface of objects which are interested in getting informed + * about changes of a document's partitioning. + *

                + * Clients may implement this interface. + *

                + *

                + * In order to provided backward compatibility for clients of IDocumentPartitioningListener, extension + * interfaces are used to provide a means of evolution. The following extension interfaces + * exist: + *

                  + *
                • {@link dwtx.jface.text.IDocumentPartitioningListenerExtension} since version 2.0 replacing the original + * notification mechanism.
                • + *
                • {@link dwtx.jface.text.IDocumentPartitioningListenerExtension2} since version 3.0 replacing all previous + * notification mechanisms. Thus, implementers up-to-date with version 3.0 do not have to implement + * {@link dwtx.jface.text.IDocumentPartitioningListenerExtension}.
                • + *
                + *

                + * @see dwtx.jface.text.IDocumentPartitioningListenerExtension + * @see dwtx.jface.text.IDocumentPartitioningListenerExtension2 + * @see dwtx.jface.text.IDocument + * @see dwtx.jface.text.IDocumentPartitioner + */ +public interface IDocumentPartitioningListener { + + /** + * The partitioning of the given document changed. + *

                + * In version 2.0 this method has been replaces by + * {@link IDocumentPartitioningListenerExtension#documentPartitioningChanged(IDocument, IRegion)}. + *

                + * In version 3.0 this method has been replaces by + * {@link IDocumentPartitioningListenerExtension2#documentPartitioningChanged(DocumentPartitioningChangedEvent)}

                + * + * @param document the document whose partitioning changed + * + * @see IDocumentPartitioningListenerExtension#documentPartitioningChanged(IDocument, IRegion) + * @see IDocumentPartitioningListenerExtension2#documentPartitioningChanged(DocumentPartitioningChangedEvent) + * @see IDocument#addDocumentPartitioningListener(IDocumentPartitioningListener) + */ + void documentPartitioningChanged(IDocument document); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDocumentPartitioningListenerExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDocumentPartitioningListenerExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IDocumentPartitioningListenerExtension; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + + +/** + * Extension interface for + * {@link dwtx.jface.text.IDocumentPartitioningListener}. + *

                + * Replaces the original notification mechanism by telling the listener the + * minimal region that comprises all partitioning changes. + * + * @see dwtx.jface.text.IDocumentPartitionerExtension + * @since 2.0 + */ +public interface IDocumentPartitioningListenerExtension { + + /** + * The partitioning of the given document changed in the given region. + *

                + * In version 3.0, this method has been replaced with + * {@link IDocumentPartitioningListenerExtension2#documentPartitioningChanged(DocumentPartitioningChangedEvent)}. + * + * @param document the document whose partitioning changed + * @param region the region in which the partitioning changed + * @see IDocumentPartitioningListenerExtension2#documentPartitioningChanged(DocumentPartitioningChangedEvent) + * @see IDocument#addDocumentPartitioningListener(IDocumentPartitioningListener) + */ + void documentPartitioningChanged(IDocument document, IRegion region); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDocumentPartitioningListenerExtension2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDocumentPartitioningListenerExtension2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,184 @@ +/******************************************************************************* + * 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 + * 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.text.IDocumentPartitioningListenerExtension2; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Extension interface to + * {@link dwtx.jface.text.IDocumentPartitioningListener}. + *

                + * + * Replaces the previous notification mechanisms by introducing an explicit + * document partitioning changed event. + * + * @see dwtx.jface.text.DocumentPartitioningChangedEvent + * @since 3.0 + */ +public interface IDocumentPartitioningListenerExtension2 { + + /** + * Signals the change of document partitionings. + *

                + * This method replaces + * {@link IDocumentPartitioningListener#documentPartitioningChanged(IDocument)} + * and + * {@link IDocumentPartitioningListenerExtension#documentPartitioningChanged(IDocument, IRegion)} + * + * @param event the event describing the change + * @see IDocument#addDocumentPartitioningListener(IDocumentPartitioningListener) + */ + void documentPartitioningChanged(DocumentPartitioningChangedEvent event); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IDocumentRewriteSessionListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IDocumentRewriteSessionListener.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IDocumentRewriteSessionListener; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Interface for objects which are interested in getting informed about document + * rewrite sessions. + *

                + * Clients may implement this interface. + *

                + * + * @see dwtx.jface.text.IDocument + * @see dwtx.jface.text.IDocumentExtension4 + * @since 3.1 + */ +public interface IDocumentRewriteSessionListener { + + /** + * Signals a change in a document's rewrite session state. + * + * @param event the event describing the document rewrite session state change + */ + void documentRewriteSessionChanged(DocumentRewriteSessionEvent event); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IEditingSupport.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IEditingSupport.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,214 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IEditingSupport; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Implemented by tools supporting the editing process. + *

                + * Clients may ask an IEditingSupport whether it is currently + * displaying a shell that has focus, and whether it is the origin of a document + * event. Depending on the answers to these queries, clients may decide to react + * differently to incoming notifications about events. For example, a special + * editing mode, that usually deactivates when the main shell looses focus, may + * decide to not deactivate if the focus event was triggered by an + * IEditingSupport. + *

                + *

                + * Clients may implement this interface. + *

                + * + * @see IEditingSupportRegistry + * @since 3.1 + */ +public interface IEditingSupport { + /** + * Returns true if the receiver is the originator of a + * DocumentEvent and if that event is related + * to subjectRegion. + *

                + * The relationship between event and + * subjectRegion is not always obvious. Often, the main + * editing area being monitored by the caller will be at + * subjectRegion, when the receiver modifies the underlying + * document at a different location without wanting to interrupt the normal + * typing flow of the user. + *

                + *

                + * An example would be an editor that automatically increments the section + * number of the next section when the user typed in a new section title. In + * this example, the subject region is the current typing location, while + * the increment results in a document change further down in the text. + *

                + * + * @param event the DocumentEvent in question + * @param subjectRegion the region that the caller is interested in + * @return true if event was triggered by the + * receiver and relates to subjectRegion + */ + bool isOriginator(DocumentEvent event, IRegion subjectRegion); + + /** + * Returns true if the receiver is showing a shell which has + * focus, false if it does not have focus or the helper has + * no shell. + * + * @return true if the support's shell has focus, + * false otherwise + */ + bool ownsFocusShell(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IEditingSupportRegistry.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IEditingSupportRegistry.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,194 @@ +/******************************************************************************* + * 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 + * 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.text.IEditingSupportRegistry; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +/** + * A registry for IEditingSupports. + *

                + * This interface is not meant to be implemented outside the JFace text + * framework.

                + * + * @see IEditingSupport + * @since 3.1 + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IEditingSupportRegistry { + + /** + * Register a support with the registry. If the support is already + * registered, nothing happens. + * + * @param support an editor support + */ + public void register(IEditingSupport support); + + /** + * Deregister a support with the registry. If the support is not registered, + * or support is null, nothing happens. + * + * @param support the helper to deregister, or null + */ + public void unregister(IEditingSupport support); + + /** + * Returns the current editor helpers. + * + * @return an non- null array of currently registered editor + * helpers + */ + public IEditingSupport[] getRegisteredSupports(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IEventConsumer.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IEventConsumer.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IEventConsumer; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + + +import dwt.events.VerifyEvent; + +/** + * Implementers can register with a text viewer and receive + * VerifyEvents before the text viewer they are registered with. + * If the event consumer marks events as processed by turning their + * doit field to false the text viewer + * subsequently ignores them.

                + *

                + * Clients may implement this interface.

                + *

                + * {@link dwtx.jface.text.ITextViewerExtension2}allows clients to manage + * the {@link dwt.events.VerifyListener}s of a text viewer. This + * makes IEventConsumer obsolete.

                + * + * @see dwtx.jface.text.ITextViewer + * @see dwtx.jface.text.ITextViewerExtension2 + * @see dwt.events.VerifyEvent + */ +public interface IEventConsumer { + + /** + * Processes the given event and marks it as done if it should + * be ignored by subsequent receivers. + * + * @param event the verify event which will be investigated + */ + public void processEvent(VerifyEvent event); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IFindReplaceTarget.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IFindReplaceTarget.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,247 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IFindReplaceTarget; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +import dwt.graphics.Point; + + +/** + * Defines the target for finding and replacing strings. + *

                + * The two main methods are findAndSelect and + * replaceSelection. The target does not provide any way to + * modify the content other than replacing the selection. + *

                + * + * In order to provide backward compatibility for clients of + * IFindReplaceTarget, extension interfaces are used as a means + * of evolution. The following extension interfaces exist: + *

                  + *
                • {@link dwtx.jface.text.IFindReplaceTargetExtension} since version + * 2.0 introducing the notion of find/replace session and of a find/replace + * scope. In additions, in allows clients to replace all occurrences of a given + * find query.
                • + *
                • {@link dwtx.jface.text.IFindReplaceTargetExtension3} since + * version 3.0 allowing clients to specify search queries as regular + * expressions.
                • + *
                + *

                + * Clients of a IFindReplaceTarget that also implements the + * IFindReplaceTargetExtension have to indicate the start of a find/replace + * session before using the target and to indicate the end of the session when the + * target is no longer used. + * + * @see dwtx.jface.text.IFindReplaceTargetExtension + * @see dwtx.jface.text.IFindReplaceTargetExtension3 + */ +public interface IFindReplaceTarget { + + /** + * Returns whether a find operation can be performed. + * + * @return whether a find operation can be performed + */ + bool canPerformFind(); + + /** + * Searches for a string starting at the given widget offset and using the specified search + * directives. If a string has been found it is selected and its start offset is + * returned. + *

                + * Replaced by {@link IFindReplaceTargetExtension3#findAndSelect(int, String, bool, bool, bool, bool)}. + * + * @param widgetOffset the widget offset at which searching starts + * @param findString the string which should be found + * @param searchForward true searches forward, false backwards + * @param caseSensitive true performs a case sensitive search, false an insensitive search + * @param wholeWord if true only occurrences are reported in which the findString stands as a word by itself + * @return the position of the specified string, or -1 if the string has not been found + */ + int findAndSelect(int widgetOffset, String findString, bool searchForward, bool caseSensitive, bool wholeWord); + + /** + * Returns the currently selected range of characters as a offset and length in widget coordinates. + * + * @return the currently selected character range in widget coordinates + */ + Point getSelection(); + + /** + * Returns the currently selected characters as a string. + * + * @return the currently selected characters + */ + String getSelectionText(); + + /** + * Returns whether this target can be modified. + * + * @return true if target can be modified + */ + bool isEditable(); + + /** + * Replaces the currently selected range of characters with the given text. + * This target must be editable. Otherwise nothing happens. + *

                + * Replaced by {@link IFindReplaceTargetExtension3#replaceSelection(String, bool)}. + * + * @param text the substitution text + */ + void replaceSelection(String text); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IFindReplaceTargetExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IFindReplaceTargetExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,240 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IFindReplaceTargetExtension; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + +import dwt.graphics.Color; +import dwt.graphics.Point; + + +/** + * Extension interface for {@link dwtx.jface.text.IFindReplaceTarget}. + *

                + * Introduces the concepts of find/replace sessions, searching in a limiting + * scope and a replace-all mode. + *

                + * If a scope is set, findAndSelect is limited to the scope. + * Occurrences outside of the scope are not considered. + * + * @since 2.0 + */ +public interface IFindReplaceTargetExtension { + + /** + * Indicates that a session with the target begins. + * All calls except beginSession() and endSession() to + * IFindReplaceTarget and + * IFindReplaceTargetExtension must be embedded within calls to + * beginSession() and endSession(). + * + * @see #endSession() + */ + void beginSession(); + + /** + * Indicates that a session with the target ends. + * + * @see #beginSession() + */ + void endSession(); + + /** + * Returns the find scope of the target, null for global scope. + * + * @return returns the find scope of the target, may be null + */ + IRegion getScope(); + + /** + * Sets the find scope of the target to operate on. null + * indicates that the global scope should be used. + * + * @param scope the find scope of the target, may be null + */ + void setScope(IRegion scope_); + + /** + * Returns the currently selected range of lines as a offset and length. + * + * @return the currently selected line range + */ + Point getLineSelection(); + + /** + * Sets a selection. + * + * @param offset the offset of the selection + * @param length the length of the selection + */ + void setSelection(int offset, int length); + + /** + * Sets the scope highlight color + * + * @param color the color of the scope highlight + */ + void setScopeHighlightColor(Color color); + + + /** + * Sets the target's replace-all mode. + * + * @param replaceAll true if this target should switch into replace-all mode, + * false if it should leave the replace-all state + */ + void setReplaceAllMode(bool replaceAll); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IFindReplaceTargetExtension3.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IFindReplaceTargetExtension3.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,207 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IFindReplaceTargetExtension3; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + +/** + * Extension interface for {@link dwtx.jface.text.IFindReplaceTarget}. + *

                + * Extends the find replace target's findAndSelect and + * replaceSelection methods to allow and be aware of regular + * expression find/replace. + * + * @since 3.0 + */ +public interface IFindReplaceTargetExtension3 { + + /** + * Searches for a string starting at the given offset and using the specified search + * directives. If a string has been found it is selected and its start offset is + * returned. If regExSearch is true the findString is + * interpreted as a regular expression. + * + * @param offset the offset at which searching starts + * @param findString the specification of what should be found + * @param searchForward true searches forward, false backwards + * @param caseSensitive true performs a case sensitive search, false an insensitive search + * @param wholeWord if true only occurrences are reported in which the findString stands as a word by itself. + * Must not be used in combination with regExSearch. + * @param regExSearch if true findString represents a regular expression + * Must not be used in combination with wholeWord. + * @return the position of the specified string, or -1 if the string has not been found + * @throws java.util.regex.PatternSyntaxException if regExSearch is true and findString is an invalid regular expression + */ + int findAndSelect(int offset, String findString, bool searchForward, bool caseSensitive, bool wholeWord, bool regExSearch); + + /** + * Replaces the currently selected range of characters with the given text. + * If regExReplace is true the text is interpreted as a + * regular expression that is used to process the selected text in order to + * produce the actual replacement of the selected text. + *

                + * This target must be editable. Otherwise nothing happens. + * + * @param text the specification of the substitution text + * @param regExReplace if true text represents a regular + * expression + * @throws IllegalStateException in case of regular expressions, this call + * is not preceded by a call to findAndSelect + * @throws java.util.regex.PatternSyntaxException if regExReplace is + * true and text is an invalid regular expression + */ + void replaceSelection(String text, bool regExReplace); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IInformationControl.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IInformationControl.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,345 @@ +/******************************************************************************* + * 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 + * 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.text.IInformationControl; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + + +import dwt.DWT; +import dwt.events.DisposeListener; +import dwt.events.FocusListener; +import dwt.graphics.Color; +import dwt.graphics.Point; + + +/** + * Interface of a control presenting information. The information is given in + * the form of an input object. It can be either the content itself or a + * description of the content. The specification of what is required from an + * input object is left to the implementers of this interface. + *

                + * If this information control is used by a {@link AbstractHoverInformationControlManager} + * then that manager will own this control and override any properties that + * may have been set before by any other client.

                + *

                + * The information control must not grab focus when made visible using + * setVisible(true). + * + * In order to provide backward compatibility for clients of + * IInformationControl, extension interfaces are used as a means + * of evolution. The following extension interfaces exist: + *

                  + *
                • {@link dwtx.jface.text.IInformationControlExtension} since + * version 2.0 introducing the predicate of whether the control has anything to + * show or would be empty
                • + *
                • {@link dwtx.jface.text.IInformationControlExtension2} since + * version 2.1 replacing the original concept of textual input by general input + * objects.
                • + *
                • {@link dwtx.jface.text.IInformationControlExtension3} since + * version 3.0 providing access to the control's bounds and introducing + * the concept of persistent size and location.
                • + *
                • {@link dwtx.jface.text.IInformationControlExtension4} since + * version 3.3, adding API which allows to set this information control's status field text.
                • + *
                • {@link dwtx.jface.text.IInformationControlExtension5} since + * version 3.4, adding API to get the visibility of the control, to + * test whether another control is a child of the information control, + * to compute size constraints based on the information control's main font + * and to return a control creator for an enriched version of this information control.
                • + *
                + *

                + * Clients can implement this interface and its extension interfaces, + * subclass {@link AbstractInformationControl}, or use the (text-based) + * default implementation {@link DefaultInformationControl}. + * + * @see dwtx.jface.text.IInformationControlExtension + * @see dwtx.jface.text.IInformationControlExtension2 + * @see dwtx.jface.text.IInformationControlExtension3 + * @see dwtx.jface.text.IInformationControlExtension4 + * @see dwtx.jface.text.IInformationControlExtension5 + * @see AbstractInformationControl + * @see DefaultInformationControl + * @since 2.0 + */ +public interface IInformationControl { + + /** + * Sets the information to be presented by this information control. + *

                + * Replaced by {@link IInformationControlExtension2#setInput(Object)}. + * + * @param information the information to be presented + */ + void setInformation(String information); + + /** + * Sets the information control's size constraints. A constraint value of + * {@link DWT#DEFAULT} indicates no constraint. This method must be called before + * {@link #computeSizeHint()} is called. + *

                + * Note: An information control which implements {@link IInformationControlExtension3} + * may ignore this method or use it as hint for its very first appearance. + *

                + * @param maxWidth the maximal width of the control to present the information, or {@link DWT#DEFAULT} for not constraint + * @param maxHeight the maximal height of the control to present the information, or {@link DWT#DEFAULT} for not constraint + */ + void setSizeConstraints(int maxWidth, int maxHeight); + + /** + * Computes and returns a proposal for the size of this information control depending + * on the information to present. The method tries to honor known size constraints but might + * return a size that exceeds them. + * + * @return the computed size hint + */ + Point computeSizeHint(); + + /** + * Controls the visibility of this information control. + *

                + * Note: The information control must not grab focus when + * made visible. + *

                + * + * @param visible true if the control should be visible + */ + void setVisible(bool visible); + + /** + * Sets the size of this information control. + * + * @param width the width of the control + * @param height the height of the control + */ + void setSize(int width, int height); + + /** + * Sets the location of this information control. + * + * @param location the location + */ + void setLocation(Point location); + + /** + * Disposes this information control. + */ + void dispose(); + + /** + * Adds the given listener to the list of dispose listeners. + * If the listener is already registered it is not registered again. + * + * @param listener the listener to be added + */ + void addDisposeListener(DisposeListener listener); + + /** + * Removes the given listeners from the list of dispose listeners. + * If the listener is not registered this call has no effect. + * + * @param listener the listener to be removed + */ + void removeDisposeListener(DisposeListener listener); + + /** + * Sets the foreground color of this information control. + * + * @param foreground the foreground color of this information control + */ + void setForegroundColor(Color foreground); + + /** + * Sets the background color of this information control. + * + * @param background the background color of this information control + */ + void setBackgroundColor(Color background); + + /** + * Returns whether this information control (or one of its children) has the focus. + * The suggested implementation is like this (fShell is this information control's shell): + *
                return fShell.getDisplay().getActiveShell() is fShell
                + * + * @return true when the information control has the focus, otherwise false + */ + bool isFocusControl(); + + /** + * Sets the keyboard focus to this information control. + */ + void setFocus(); + + /** + * Adds the given listener to the list of focus listeners. + * If the listener is already registered it is not registered again. + *

                + * The suggested implementation is to install listeners for {@link DWT#Activate} and {@link DWT#Deactivate} + * on the shell and forward events to the focus listeners. Clients are + * encouraged to subclass {@link AbstractInformationControl}, which does this + * for free. + *

                + * + * @param listener the listener to be added + */ + void addFocusListener(FocusListener listener); + + /** + * Removes the given listeners from the list of focus listeners. + * If the listener is not registered this call has no affect. + * + * @param listener the listener to be removed + */ + void removeFocusListener(FocusListener listener); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IInformationControlCreator.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IInformationControlCreator.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,190 @@ +/******************************************************************************* + * 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 + * 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.text.IInformationControlCreator; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +import dwt.widgets.Shell; + + +/** + * Interface of a factory for information controls ( + * {@link dwtx.jface.text.IInformationControl}). + * + * In order to provide backward compatibility for clients of + * IInformationControlCreator, extension interfaces are used as + * a means of evolution. The following extension interfaces exist: + *
                  + *
                • {@link dwtx.jface.text.IInformationControlCreatorExtension} since + * version 3.0 introducing checks of whether existing information control can + * be reused and whether information control creators can replace each other. + *
                • + *
                + * + * @see dwtx.jface.text.IInformationControlCreatorExtension + * @since 2.0 + */ +public interface IInformationControlCreator { + + /** + * Creates a new information control with the given shell as the control's parent. + * + * @param parent the parent shell + * @return the created information control + */ + IInformationControl createInformationControl(Shell parent); +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IInformationControlCreatorExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IInformationControlCreatorExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IInformationControlCreatorExtension; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Extension interface for {@link dwtx.jface.text.IInformationControlCreator}

                + * Introduces tests whether information controls can be reused and whether information + * control creators can replace each other. + * + * @see dwtx.jface.text.IInformationControlCreator + * @see dwtx.jface.text.IInformationControl + * @since 3.0 + */ +public interface IInformationControlCreatorExtension { + + /** + * Tests if an existing information control can be reused. + * + * @param control the information control to test + * @return true if the control can be reused + */ + bool canReuse(IInformationControl control); + + /** + * Tests whether this information control creator can replace the given + * information control creator. This is the case if the two creators create + * the same kind of information controls. + * + * @param creator the creator to be checked + * @return true if the given creator can be replaced, + * false otherwise + */ + bool canReplace(IInformationControlCreator creator); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IInformationControlExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IInformationControlExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,179 @@ +/******************************************************************************* + * 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 + * 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.text.IInformationControlExtension; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + +/** + * Extension interface {@link dwtx.jface.text.IInformationControl}. + *

                + * As it is the responsibility of the implementer of + * {@link dwtx.jface.text.IInformationControl} and + * {@link dwtx.jface.text.IInformationControlExtension2} to specify the + * concrete nature of the information control's input, only the implementer can + * know whether it has something to show or not. + * + * @since 2.0 + */ +public interface IInformationControlExtension { + + /** + * Returns whether this information control has contents to be displayed. + * + * @return true if there is contents to be displayed. + */ + bool hasContents(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IInformationControlExtension2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IInformationControlExtension2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,180 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IInformationControlExtension2; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Extension interface for {@link dwtx.jface.text.IInformationControl}. + *

                + * Replaces the concept of textual information to be displayed with the more + * general concept of an input of the information control. Text to be displayed + * set with setInformation(String) is ignored. + * + * @see dwtx.jface.text.IInformationControl + * @since 2.1 + */ +public interface IInformationControlExtension2 { + + /** + * Sets the input to be presented in this information control. The concrete + * contract the input object is expected to adhere is defined by the + * implementer of this interface. + * + * @param input the object to be used as input for this control + */ + void setInput(Object input); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IInformationControlExtension3.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IInformationControlExtension3.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,227 @@ +/******************************************************************************* + * 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 + * 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.text.IInformationControlExtension3; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.graphics.Rectangle; + + +/** + * Extension interface for {@link dwtx.jface.text.IInformationControl}. + * Adds API which allows to get this information control's bounds and introduces + * the concept of persistent size and location by introducing predicates for + * whether the information control supports restoring of size and location. + *

                + * Note: An information control which implements this interface can ignore calls + * to + * {@link dwtx.jface.text.IInformationControl#setSizeConstraints(int, int)} + * or use it as hint for its very first appearance. + *

                + * + * @see dwtx.jface.text.IInformationControl + * @since 3.0 + */ +public interface IInformationControlExtension3 { + + /** + * Returns a rectangle describing the receiver's size and location + * relative to its parent (or its display if its parent is null). + *

                + * Note: If the receiver is already disposed then this methods must + * return the last valid location and size. + *

                + * + * @return the receiver's bounding rectangle + */ + Rectangle getBounds(); + + /** + * Computes the trim for this control. The trim is the space around the + * information control's actual content area. It includes all borders of the + * control and other static content placed around the content area (e.g. a + * toolbar). + * + * @return The receiver's trim. x and y denote + * the upper left corner of the trimming relative to this control's + * location i.e. this will most likely be negative values. + * width and height represent the + * border sizes (the sum of the horizontal and vertical trimmings, + * respectively). + */ + Rectangle computeTrim(); + + /** + * Tells whether this control allows to restore the previously + * used size. + *

                + * Note: This is not a static property - it can change during the + * lifetime of this control.

                + * + * @return true if restoring size is supported + */ + bool restoresSize(); + + /** + * Tells whether this control allows to restore the previously + * used location. + *

                + * Note: This is not a static property - it can change during the + * lifetime of this control.

                + * + * @return true if restoring location is supported + */ + bool restoresLocation(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IInformationControlExtension4.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IInformationControlExtension4.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,181 @@ +/******************************************************************************* + * 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.text.IInformationControlExtension4; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Extension interface for {@link dwtx.jface.text.IInformationControl}. + * Adds API which allows to set this information control's status field text. + * + * @see dwtx.jface.text.IInformationControl + * @since 3.3 + */ +public interface IInformationControlExtension4 { + + /** + * Sets the text of the status field. + *

                + * The implementor can specify whether the new text affects an + * already visible information control. + *

                + * + * @param statusFieldText the text to be used in the optional status field + * or null if the status field should be hidden + * @since 3.2 + */ + public void setStatusText(String statusFieldText); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IInformationControlExtension5.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IInformationControlExtension5.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,254 @@ +/******************************************************************************* + * 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.text.IInformationControlExtension5; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + + +import dwt.DWT; +import dwt.graphics.Point; +import dwt.widgets.Control; +import dwtx.jface.resource.JFaceResources; + + +/** + * Extension interface for {@link dwtx.jface.text.IInformationControl}. + * Adds API + *
                  + *
                • to test the visibility of the control,
                • + *
                • to test whether another control is a child of the information control,
                • + *
                • to compute size constraints based on the information control's main font and
                • + *
                • to return a control creator for an enriched version of this information control.
                • + *
                + * + *

                + * Important: Enriching this information control only works properly if + * {@link IInformationControl#isFocusControl()} is implemented like this (fShell + * is the control's shell): + * + *

                + * return fShell.getDisplay().getActiveShell() is fShell
                + * 
                + * Likewise, + * {@link IInformationControl#addFocusListener(dwt.events.FocusListener)} + * should install listeners for {@link DWT#Activate} and {@link DWT#Deactivate} + * on the shell and forward events to the focus listeners. Clients are + * encouraged to subclass {@link AbstractInformationControl}, which does this + * for free. + *

                + * + * @see dwtx.jface.text.IInformationControl + * @since 3.4 + */ +public interface IInformationControlExtension5 { + + /** + * Tests whether the given control is this information control + * or a child of this information control. + * + * @param control the control to test + * @return true iff the given control is this information control + * or a child of this information control + */ + public bool containsControl(Control control); + + /** + * @return true iff the information control is currently visible + */ + public abstract bool isVisible(); + + /** + * Computes the width- and height constraints of the information control in + * pixels, based on the given width and height in characters. Implementors + * should use the main font of the information control to do the + * characters-to-pixels conversion. This is typically the + * {@link JFaceResources#getDialogFont() dialog font}. + * + * @param widthInChars the width constraint in number of characters + * @param heightInChars the height constraint in number of characters + * @return a point with width and height in pixels, or null + * to use the subject control's font to calculate the size + */ + public Point computeSizeConstraints(int widthInChars, int heightInChars); + + /** + * Returns the rich information control creator for this information control. + *

                + * The returned information control creator is used to create an enriched version of this + * information control, e.g. when the mouse is moved into this control and it needs to be + * {@link ITextViewerExtension8#setHoverEnrichMode(dwtx.jface.text.ITextViewerExtension8.EnrichMode) enriched} + * or when it needs to be made sticky for other reasons. + *

                + *

                + * The returned information control creator must create information controls + * that implement {@link IInformationControlExtension3} and {@link IInformationControlExtension2}, + * and whose {@link IInformationControlExtension2#setInput(Object)} accepts all inputs that are + * also supported by this information control. + *

                + *

                + * Note that automatic enriching of this information control works only if it also implements + * {@link IInformationControlExtension3}. + *

                + *

                + * This method may be called frequently, so implementors should ensure it returns quickly, + * e.g. by caching the returned creator. + *

                + * + * @return the information presenter control creator or null to disable enriching + */ + IInformationControlCreator getInformationPresenterControlCreator(); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IInputChangedListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IInputChangedListener.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,175 @@ +/******************************************************************************* + * 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.text.IInputChangedListener; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * A listener which is notified when the target's input changes. + *

                + * Clients can implement that interface and its extension interfaces.

                + * + * @since 3.4 + */ +public interface IInputChangedListener { + + /** + * Called when a the input has changed. + * + * @param newInput the new input, or null iff the listener should not show any new input + */ + void inputChanged(Object newInput); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ILineTracker.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ILineTracker.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,291 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.ILineTracker; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * A line tracker maps character positions to line numbers and vice versa. + * Initially the line tracker is informed about its underlying text in order to + * initialize the mapping information. After that, the line tracker is informed + * about all changes of the underlying text allowing for incremental updates of + * the mapping information. It is the client's responsibility to actively inform + * the line tacker about text changes. For example, when using a line tracker in + * combination with a document the document controls the line tracker. + *

                + * In order to provide backward compatibility for clients of ILineTracker, extension + * interfaces are used to provide a means of evolution. The following extension interfaces + * exist: + *

                  + *
                • {@link dwtx.jface.text.ILineTrackerExtension} since version 3.1 introducing the concept + * of rewrite sessions.
                • + *
                + *

                + * Clients may implement this interface or use the standard implementation + *

                + * {@link dwtx.jface.text.DefaultLineTracker}or + * {@link dwtx.jface.text.ConfigurableLineTracker}. + */ +public interface ILineTracker { + + /** + * Returns the strings this tracker considers as legal line delimiters. + * + * @return the legal line delimiters + */ + String[] getLegalLineDelimiters(); + + /** + * Returns the line delimiter of the specified line. Returns null if the + * line is not closed with a line delimiter. + * + * @param line the line whose line delimiter is queried + * @return the line's delimiter or null if line does not have a delimiter + * @exception BadLocationException if the line number is invalid in this tracker's line structure + */ + String getLineDelimiter(int line) ; + + /** + * Computes the number of lines in the given text. + * + * @param text the text whose number of lines should be computed + * @return the number of lines in the given text + */ + int computeNumberOfLines(String text); + + /** + * Returns the number of lines. + * + * @return the number of lines in this tracker's line structure + */ + int getNumberOfLines(); + + /** + * Returns the number of lines which are occupied by a given text range. + * + * @param offset the offset of the specified text range + * @param length the length of the specified text range + * @return the number of lines occupied by the specified range + * @exception BadLocationException if specified range is unknown to this tracker + */ + int getNumberOfLines(int offset, int length) ; + + /** + * Returns the position of the first character of the specified line. + * + * @param line the line of interest + * @return offset of the first character of the line + * @exception BadLocationException if the line is unknown to this tracker + */ + int getLineOffset(int line) ; + + /** + * Returns length of the specified line including the line's delimiter. + * + * @param line the line of interest + * @return the length of the line + * @exception BadLocationException if line is unknown to this tracker + */ + int getLineLength(int line) ; + + /** + * Returns the line number the character at the given offset belongs to. + * + * @param offset the offset whose line number to be determined + * @return the number of the line the offset is on + * @exception BadLocationException if the offset is invalid in this tracker + */ + int getLineNumberOfOffset(int offset) ; + + /** + * Returns a line description of the line at the given offset. + * The description contains the start offset and the length of the line + * excluding the line's delimiter. + * + * @param offset the offset whose line should be described + * @return a region describing the line + * @exception BadLocationException if offset is invalid in this tracker + */ + IRegion getLineInformationOfOffset(int offset) ; + + /** + * Returns a line description of the given line. The description + * contains the start offset and the length of the line excluding the line's + * delimiter. + * + * @param line the line that should be described + * @return a region describing the line + * @exception BadLocationException if line is unknown to this tracker + */ + IRegion getLineInformation(int line) ; + + /** + * Informs the line tracker about the specified change in the tracked text. + * + * @param offset the offset of the replaced text + * @param length the length of the replaced text + * @param text the substitution text + * @exception BadLocationException if specified range is unknown to this tracker + */ + void replace(int offset, int length, String text) ; + + /** + * Sets the tracked text to the specified text. + * + * @param text the new tracked text + */ + void set(String text); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ILineTrackerExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ILineTrackerExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.ILineTrackerExtension; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Extension interface for {@link dwtx.jface.text.ILineTracker}. Adds the + * concept of rewrite sessions. A rewrite session is a sequence of replace + * operations that form a semantic unit. + * + * @since 3.1 + */ +public interface ILineTrackerExtension { + + /** + * Tells the line tracker that a rewrite session started. A rewrite session + * is a sequence of replace operations that form a semantic unit. The line + * tracker is allowed to use that information for internal optimization. + * + * @param session the rewrite session + * @throws IllegalStateException in case there is already an active rewrite + * session + */ + void startRewriteSession(DocumentRewriteSession session) ; + + /** + * Tells the line tracker that the rewrite session has finished. This method + * is only called when startRewriteSession has been called + * before. The text resulting from the rewrite session is passed to the line + * tracker. + * + * @param session the rewrite session + * @param text the text with which to re-initialize the line tracker + */ + void stopRewriteSession(DocumentRewriteSession session, String text); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IMarkRegionTarget.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IMarkRegionTarget.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IMarkRegionTarget; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + +/** + * A mark region target to support marked regions as found in emacs. + * + * @since 2.0 + */ +public interface IMarkRegionTarget { + + /** + * Sets or clears a mark at the current cursor position. + * + * @param set sets the mark if true, clears otherwise. + */ + void setMarkAtCursor(bool set); + + /** + * Swaps the mark and cursor position if the mark is in the visible region. + */ + void swapMarkAndCursor(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IMarkSelection.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IMarkSelection.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,198 @@ +/******************************************************************************* + * 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 + * 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.text.IMarkSelection; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.jface.viewers.ISelection; + + +/** + * A mark selection can be sent out by text viewers. By checking the + * type of the selection selection listeners can determine whether a selection + * event is about a mark or a normal text selection. + *

                + * This interface is not intended to be implemented by clients other than + * {@link dwtx.jface.text.ITextViewer} implementers. + *

                + * + * @since 2.0 + */ +public interface IMarkSelection : ISelection { + + /** + * Returns the marked document. + * + * @return the marked document + */ + IDocument getDocument(); + + /** + * Returns the mark position. The offset may be -1 if there's no marked region. + * + * @return the mark position or -1 if there is no marked region + */ + int getOffset(); + + /** + * Returns the length of the mark selection. The length may be negative, if the caret + * is before the mark position. The length has no meaning if getOffset() + * returns -1. + * + * @return the length of the mark selection. Result is undefined for getOffset is -1 + */ + int getLength(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IPaintPositionManager.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IPaintPositionManager.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,184 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IPaintPositionManager; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + + +/** + * Manages and updates positions used by {@link IPainter}s. + * + * @see dwtx.jface.text.IPainter + * @since 2.1 + */ +public interface IPaintPositionManager { + + /** + * Starts managing the given position until unmanagePosition is called. + * + * @param position the position to manage + * @see #unmanagePosition(Position) + */ + void managePosition(Position position); + + /** + * Stops managing the given position. If the position is not managed + * by this managed, this call has no effect. + * + * @param position the position that should no longer be managed + */ + void unmanagePosition(Position position); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IPainter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IPainter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,257 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IPainter; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + + +/** + * A painter is responsible for creating, managing, updating, and removing + * visual decorations on an ITextViewer's text widget. Examples + * are the highlighting of the caret line, the print margin, or the highlighting + * of matching peer characters such as pairs of brackets.

                + *

                + * Clients may implement this interface.

                + *

                + * Painters should be registered with a + * {@link dwtx.jface.text.PaintManager}. The paint manager tracks + * several classes of events issued by an ITextViewer and reacts + * by appropriately invoking the registered painters. + *

                + * Painters are either active or inactive. Usually, painters are initially + * inactive and are activated by the first call to their paint + * method. Painters can be deactivated by calling deactivate. + * Inactive painter can be reactivated by calling paint. + *

                + * Painters usually have to manage state information. E.g., a painter painting a + * caret line highlight must redraw the previous and the actual caret line in + * the advent of a change of the caret position. This state information must be + * adapted to changes of the viewer's content. In order to support this common + * scenario, the PaintManager gives a painter access to a + * {@link dwtx.jface.text.IPaintPositionManager}. The painter can use + * this updater to manage its state information. + *

                + * + * @see dwtx.jface.text.PaintManager + * @see dwtx.jface.text.IPaintPositionManager + * @since 2.1 + */ +public interface IPainter { + + /** + * Constant describing the reason of a repaint request: selection changed. + */ + static const int SELECTION= 0; + /** + * Constant describing the reason of a repaint request: text changed. + */ + static const int TEXT_CHANGE= 1; + /** + * Constant describing the reason of a repaint request: key pressed. + */ + static const int KEY_STROKE= 2; + /** + * Constant describing the reason of a repaint request: mouse button pressed. + */ + static const int MOUSE_BUTTON= 4; + /** + * Constant describing the reason of a repaint request: paint manager internal change. + */ + static const int INTERNAL= 8; + /** + * Constant describing the reason of a repaint request: paint manager or painter configuration changed. + */ + static const int CONFIGURATION= 16; + + + /** + * Disposes this painter. Prior to disposing, a painter should be deactivated. A disposed + * painter can not be reactivated. + * + * @see #deactivate(bool) + */ + void dispose(); + + /** + * Requests this painter to repaint because of the given reason. Based on + * the given reason the painter can decide whether it will repaint or not. + * If it repaints and is inactive, it will activate itself. + * + * @param reason the repaint reason, value is one of the constants defined + * in this interface + */ + void paint(int reason); + + /** + * Deactivates this painter. If the painter is inactive, this call does not + * have any effect. redraw indicates whether the painter + * should remove any decoration it previously applied. A deactivated painter + * can be reactivated by calling paint. + * + * @param redraw true if any previously applied decoration + * should be removed + * @see #paint(int) + */ + void deactivate(bool redraw); + + /** + * Sets the paint position manager that can be used by this painter or removes any previously + * set paint position manager. + * + * @param manager the paint position manager or null + */ + void setPositionManager(IPaintPositionManager manager); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IPositionUpdater.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IPositionUpdater.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IPositionUpdater; + +import dwtx.jface.text.DocumentEvent; // packageimport + +import dwt.dwthelper.utils; + + +/** + * A position updater is responsible for adapting document positions. When + * installed on a document, the position updater updates the document's + * positions to changes applied to this document. Document updaters can be + * selective, i.e. they might only update positions of a certain category. + *

                + * Position updaters are of primary importance for the definition of the + * semantics of positions. + *

                + * Clients may implement this interface or use the standard implementation + * {@link dwtx.jface.text.DefaultPositionUpdater}. + *

                + * + * @see dwtx.jface.text.IDocument + * @see dwtx.jface.text.Position + */ +public interface IPositionUpdater { + + /** + * Adapts positions to the change specified by the document event. + * It is ensured that the document's partitioning has been adapted to + * this document change and that all the position updaters which have + * a smaller index in the document's position updater list have been called. + * + * @param event the document event describing the document change + */ + void update(DocumentEvent event); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IRegion.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IRegion.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IRegion; + +/** + * A region describes a certain range in an indexed text store. Text stores are + * for example documents or strings. A region is defined by its offset into the + * text store and its length. + *

                + * A region is considered a value object. Its offset and length do not change + * over time. + *

                + * Clients may implement this interface or use the standard implementation + * {@link dwtx.jface.text.Region}. + *

                + */ +public interface IRegion { + + /** + * Returns the length of the region. + * + * @return the length of the region + */ + int getLength(); + + /** + * Returns the offset of the region. + * + * @return the offset of the region + */ + int getOffset(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IRepairableDocument.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IRepairableDocument.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,184 @@ +/******************************************************************************* + * 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.text.IRepairableDocument; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Tagging interface to be implemented by + * {@link dwtx.jface.text.IDocument} implementers that offer a line + * repair method on the documents. + *

                + * In order to provide backward compatibility for clients of + * IRepairableDocument, extension interfaces are used to provide + * a means of evolution. The following extension interfaces exist: + *

                  + *
                • {@link dwtx.jface.text.IRepairableDocumentExtension} since version 3.4 + * adds the ability to query whether the repairable document needs to be repaired.
                • + *
                + * + * + * @see dwtx.jface.text.IDocument + * @see dwtx.jface.text.IRepairableDocumentExtension + * @since 3.0 + */ +public interface IRepairableDocument { + + /** + * Repairs the line information of the document implementing this interface. + */ + void repairLineInformation(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IRepairableDocumentExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IRepairableDocumentExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,183 @@ +/******************************************************************************* + * 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.text.IRepairableDocumentExtension; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Extension interface for {@link dwtx.jface.text.IRepairableDocument}. + *

                + * Adds the ability to query whether the repairable document needs to be + * repaired. + * + * @see dwtx.jface.text.IRepairableDocument + * @since 3.4 + */ +public interface IRepairableDocumentExtension { + + /** + * Tells whether the line information of the document implementing this + * interface needs to be repaired. + * + * @param offset the document offset + * @param length the length of the specified range + * @param text the substitution text to check + * @return true if the line information must be repaired + * @throws BadLocationException if the offset is invalid in this document + * @see IRepairableDocument#repairLineInformation() + */ + bool isLineInformationRepairNeeded(int offset, int length, String text) ; +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IRewriteTarget.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IRewriteTarget.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,202 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IRewriteTarget; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + + /** + * A target publishing the required functions to modify a document that is displayed + * in a text viewer. It provides access to the document and control + * over the redraw behavior and the grouping of document changes into undo commands. + * + * @see dwtx.jface.text.ITextViewer + * @see dwtx.jface.text.IDocument + * @see dwtx.jface.text.IUndoManager + * @since 2.0 + */ +public interface IRewriteTarget { + + /** + * Returns the document of this target. + * + * @return the document of this target + */ + IDocument getDocument(); + + /** + * Disables/enables redrawing while modifying the target's document. + * + * @param redraw true if the document's visible presentation + * should be updated, false otherwise + */ + void setRedraw(bool redraw); + + /** + * If an undo manager is connected to the document's visible presentation, + * this method tells the undo manager to fold all subsequent changes into + * one single undo command until endCompoundChange is called. + */ + void beginCompoundChange(); + + /** + * If an undo manager is connected to the document's visible presentation, + * this method tells the undo manager to stop the folding of changes into a + * single undo command. After this call, all subsequent changes are + * considered to be individually undo-able. + */ + void endCompoundChange(); +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ISelectionValidator.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ISelectionValidator.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.ISelectionValidator; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.jface.viewers.ISelection; + + +/** + * A selection validator allows clients to test whether the selection they + * received during selection changed notification is valid. + *

                + * For example, selection and document changes that occur between the original + * selection and the point in time the validator is called cause the selection + * to be invalid.

                + *

                + * Clients may implement and use this interface. + *

                + * + * @since 3.0 + */ +public interface ISelectionValidator { + + /** + * Tests whether the given post selection is still valid. + * + * @param selection + * @return true if the selection is still valid + */ + bool isValid(ISelection selection); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ISlaveDocumentManager.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ISlaveDocumentManager.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,249 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.ISlaveDocumentManager; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + +/** + * Slave documents are documents whose contents is defined in terms of a master + * document. Thus, slave documents usually reflect a projection of the master document. + * Slave documents are causally connected to the master document. This means, changes + * of the master document have immediate effect on the slave document and vice versa. + *

                + * A slave document manager creates slave documents for given master documents, manages the + * life cycle of the slave documents, and keeps track of the information flow between + * master and slave documents. The slave document manager defines the construction rules of the + * slave documents in terms of the master document.

                + *

                +* In order to provided backward compatibility for clients of ISlaveDocumentManager, extension + * interfaces are used to provide a means of evolution. The following extension interfaces + * exist: + *

                  + *
                • {@link dwtx.jface.text.ISlaveDocumentManagerExtension} since version 3.0 extending the protocol + * with an access to all managed slave document for a given master document.
                • + *
                + *

                + * + * @see dwtx.jface.text.IDocument + * @since 2.1 + */ +public interface ISlaveDocumentManager { + + /** + * Creates a new slave document for the given master document. The slave document + * is causally connected to its master document until freeSlaveDocument + * is called. The connection between the newly created slave document and the master + * document is managed by this slave document manager. + * + * @param master the master document + * @return the newly created slave document + * @see #freeSlaveDocument(IDocument) + */ + IDocument createSlaveDocument(IDocument master); + + /** + * Frees the given slave document. If the given document is not a slave document known + * to this slave document manager, this call does not have any effect. A slave + * document is known to this slave document manager if it has been created by + * this manager using createSlaveDocument. + * + * @param slave the slave document to be freed + * @see #createSlaveDocument(IDocument) + */ + void freeSlaveDocument(IDocument slave); + + /** + * Creates a new document information mapping between the given slave document and + * its master document. Returns null if the given document is unknown + * to this slave document manager. + * + * @param slave the slave document + * @return a document information mapping between the slave document and its master document or + * null + */ + IDocumentInformationMapping createMasterSlaveMapping(IDocument slave); + + /** + * Returns the master document of the given slave document or null if the + * given document is unknown to this slave document manager. + * + * @param slave the slave document + * @return the master document of the given slave document or null + */ + IDocument getMasterDocument(IDocument slave); + + /** + * Returns whether the given document is a slave document known to this slave document manager. A slave document + * is known to this slave document manager, if the document has been created by this manager. + * + * @param document the document to be checked whether it is a slave document known to this manager + * @return true if the document is a slave document, false otherwise + */ + bool isSlaveDocument(IDocument document); + + /** + * Sets the given slave document's auto expand mode. In auto expand mode, a + * slave document is automatically adapted to reflect all changes applied to it's master document. + * Assume a master document contains 30 lines and the slave is defined to contain the lines 11-20. + * In auto expand mode, when the master document is changed at line 8, the slave document is expanded + * to contain the lines 8-20.

                + * This call is without effect if the given document is unknown to this slave document manager. + * + * @param slave the slave whose auto expand mode should be set + * @param autoExpand true for auto expand, false otherwise + */ + void setAutoExpandMode(IDocument slave, bool autoExpand); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ISlaveDocumentManagerExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ISlaveDocumentManagerExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.ISlaveDocumentManagerExtension; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Extension interface for {@link dwtx.jface.text.ISlaveDocumentManager}. + *

                + * Adds access to the list of all slave documents for a given master document. + * + * @see dwtx.jface.text.ISlaveDocumentManager + * @since 3.0 + */ +public interface ISlaveDocumentManagerExtension { + + /** + * Returns the list of slave documents for the given master document or + * null if there are no such slave document. + * + * @param master the master document + * @return the list of slave documents or null + */ + IDocument[] getSlaveDocuments(IDocument master); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ISynchronizable.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ISynchronizable.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,197 @@ +/******************************************************************************* + * 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 + * 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.text.ISynchronizable; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Interface for text related objects which may be used in the multi-threaded + * context and thus must provide a way to prevent concurrent access and + * manipulation. + *

                + * In order to reduce the probability of dead locks clients should synchronize + * their access to these objects by using the provided lock object rather than + * the object itself.

                + *

                + * Managing objects can use the setLockObject method in order to + * synchronize whole sets of objects.

                + * + * @since 3.0 + */ +public interface ISynchronizable { + + /** + * Sets the lock object for this object. If the lock object is not + * null subsequent calls to specified methods of this object + * are synchronized on this lock object. Which methods are synchronized is + * specified by the implementer. + *

                + * You should not override an existing lock object unless you own + * that lock object yourself. Use the existing lock object instead. + *

                + * + * @param lockObject the lock object. May be null. + */ + void setLockObject(Object lockObject); + + /** + * Returns the lock object or null if there is none. Clients + * should use the lock object in order to synchronize concurrent access to + * the implementer. + * + * @return the lock object or null + */ + Object getLockObject(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextDoubleClickStrategy.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextDoubleClickStrategy.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.ITextDoubleClickStrategy; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * A text double click strategy defines the reaction of a text viewer to mouse + * double click events. The strategy must be installed on an + * {@link dwtx.jface.text.ITextViewer}. + *

                + * Clients may implement this interface or use the standard implementation + * DefaultTextDoubleClickStrategy.

                + * + * @see dwtx.jface.text.ITextViewer + * @see dwt.events.MouseListener#mouseDoubleClick(dwt.events.MouseEvent) + */ +public interface ITextDoubleClickStrategy { + + /** + * The mouse has been double clicked on the given text viewer. + * + * @param viewer the viewer into which has been double clicked + */ + void doubleClicked(ITextViewer viewer); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextHover.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextHover.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,213 @@ +/******************************************************************************* + * 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 + * 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.text.ITextHover; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Computes the information to be shown in a hover popup which appears on top of + * the text viewer's text widget when a hover event occurs. If the text hover + * does not provide information no hover popup is shown. Any implementer of this + * interface must be capable of operating in a non-UI thread. + *

                + * + * In order to provide backward compatibility for clients of + * ITextHover, extension interfaces are used as a means of + * evolution. The following extension interfaces exist: + *

                  + *
                • {@link dwtx.jface.text.ITextHoverExtension} since version 3.0 + * allowing a text hover to provide a creator for the hover control. This allows + * for sophisticated hovers in a way that information computed by the hover can + * be displayed in the best possible form.
                • + *
                • {@link dwtx.jface.text.ITextHoverExtension2} since version 3.4 + * allowing a text hover to return hover-specific information objects.
                • + *

                + *

                + * Clients may implement this interface.

                + * + * @see dwtx.jface.text.ITextHoverExtension + * @see dwtx.jface.text.ITextHoverExtension2 + * @see dwtx.jface.text.ITextViewer + */ +public interface ITextHover { + + /** + * Returns the information which should be presented when a hover popup is shown + * for the specified hover region. The hover region has the same semantics + * as the region returned by getHoverRegion. If the returned + * information is null or empty no hover popup will be shown. + * + * @param textViewer the viewer on which the hover popup should be shown + * @param hoverRegion the text range in the viewer which is used to determine + * the hover display information + * @return the hover popup display information, or null if none available + * @deprecated As of 3.4, replaced by {@link ITextHoverExtension2#getHoverInfo2(ITextViewer, IRegion)} + */ + String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion); + + /** + * Returns the text region which should serve as the source of information + * to compute the hover popup display information. The popup has been requested + * for the given offset.

                + * For example, if hover information can be provided on a per method basis in a + * source viewer, the offset should be used to find the enclosing method and the + * source range of the method should be returned. + * + * @param textViewer the viewer on which the hover popup should be shown + * @param offset the offset for which the hover request has been issued + * @return the hover region used to compute the hover display information + */ + IRegion getHoverRegion(ITextViewer textViewer, int offset); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextHoverExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextHoverExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.ITextHoverExtension; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Extension interface for {@link dwtx.jface.text.ITextHover}. + *

                + * It provides a way for hovers to specify the information control creator they + * want to have used in order to create the hover control.

                + * + * @see dwtx.jface.text.IInformationControlCreator + * @see dwtx.jface.text.ITextHover + * @since 3.0 + */ +public interface ITextHoverExtension { + + /** + * Returns the hover control creator of this text hover or null + * + * @return the hover control creator or null + */ + IInformationControlCreator getHoverControlCreator(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextHoverExtension2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextHoverExtension2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,192 @@ +/******************************************************************************* + * 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.text.ITextHoverExtension2; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Extension interface for {@link dwtx.jface.text.ITextHover}. + *

                + * Provides a way for hovers to return hover-specific information objects. + *

                + * + * @see dwtx.jface.text.ITextHover + * @since 3.4 + */ +public interface ITextHoverExtension2 { + + /** + * Returns the information which should be presented when a hover popup is shown + * for the specified hover region. The hover region has the same semantics + * as the region returned by {@link ITextHover#getHoverRegion(ITextViewer, int)}. + * If the returned information is null, no hover popup will be shown. + *

                + * Note: Implementers have to ensure that {@link ITextHoverExtension#getHoverControlCreator()} + * returns {@link IInformationControl}s that implement + * {@link IInformationControlExtension2} and whose + * {@link IInformationControlExtension2#setInput(Object)} can handle the + * information objects returned by this method.

                + *

                + * Callers should ignore the text returned by {@link ITextHover#getHoverInfo(ITextViewer, IRegion)}.

                + * + * @param textViewer the viewer on which the hover popup should be shown + * @param hoverRegion the text range in the viewer which is used to determine + * the hover display information + * @return the hover popup display information, or null if none available + */ + Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextInputListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextInputListener.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.ITextInputListener; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + + +/** + * Text input listeners registered with an + * {@link dwtx.jface.text.ITextViewer} are informed if the document + * serving as the text viewer's model is replaced. + *

                + * Clients may implement this interface.

                + * + * @see dwtx.jface.text.ITextViewer + * @see dwtx.jface.text.IDocument + */ +public interface ITextInputListener { + + /** + * Called before the input document is replaced. + * + * @param oldInput the text viewer's previous input document + * @param newInput the text viewer's new input document + */ + void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput); + + /** + * Called after the input document has been replaced. + * + * @param oldInput the text viewer's previous input document + * @param newInput the text viewer's new input document + */ + void inputDocumentChanged(IDocument oldInput, IDocument newInput); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextListener.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,193 @@ +/******************************************************************************* + * 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.text.ITextListener; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + + +/** + * Text listeners registered with a text viewer are informed about all + * modifications of an {@link dwtx.jface.text.ITextViewer} by means of + * text events. A text event describes a change as a replace operation. + *

                + * The changes described in the event are the changes applied to the text + * viewer's widget (i.e., its visual representation) and not those applied to the + * text viewer's document. The text event can be asked to return the + * corresponding document event. If the text event does not contain a document + * event, the modification of the text viewer is a presentation change. For + * example, changing the visible region of a text viewer, is a presentation + * change. A completely empty text event represents a change of the viewer's + * redraw state.

                + *

                + * If a text listener receives a text event, it is guaranteed that both the + * document and the viewer's visual representation are synchronized.

                + *

                + * Clients may implement this interface.

                + * + * @see dwtx.jface.text.ITextViewer + * @see dwtx.jface.text.TextEvent + * @see dwtx.jface.text.DocumentEvent + */ +public interface ITextListener { + + /** + * The visual representation of a text viewer this listener is registered with + * has been changed. + * + * @param event the description of the change + */ + void textChanged(TextEvent event); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextOperationTarget.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextOperationTarget.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,259 @@ +/******************************************************************************* + * 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 + * 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.text.ITextOperationTarget; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Defines the target for text operations. canDoOperation informs + * the clients about the ability of the target to perform the specified + * operation at the current point in time. doOperation executes + * the specified operation. + *

                + * In order to provide backward compatibility for clients of + * ITextOperationTarget, extension interfaces are used as a + * means of evolution. The following extension interfaces exist: + *

                  + *
                • {@link dwtx.jface.text.ITextOperationTargetExtension} since + * version 2.0 introducing text operation enabling/disabling.
                • + *
                + * + * @see dwtx.jface.text.ITextOperationTargetExtension + */ +public interface ITextOperationTarget { + + + /** + * Text operation code for undoing the last edit command. + */ + public static const int UNDO= 1; + + /** + * Text operation code for redoing the last undone edit command. + */ + public static const int REDO= 2; + + /** + * Text operation code for moving the selected text to the clipboard. + */ + public static const int CUT= 3; + + /** + * Text operation code for copying the selected text to the clipboard. + */ + public static const int COPY= 4; + + /** + * Text operation code for inserting the clipboard content at the + * current position. + */ + public static const int PASTE= 5; + + /** + * Text operation code for deleting the selected text or if selection + * is empty the character at the right of the current position. + */ + public static const int DELETE= 6; + + /** + * Text operation code for selecting the complete text. + */ + public static const int SELECT_ALL= 7; + + /** + * Text operation code for shifting the selected text block to the right. + */ + public static const int SHIFT_RIGHT= 8; + + /** + * Text operation code for shifting the selected text block to the left. + */ + public static const int SHIFT_LEFT= 9; + + /** + * Text operation code for printing the complete text. + */ + public static const int PRINT= 10; + + /** + * Text operation code for prefixing the selected text block. + */ + public static const int PREFIX= 11; + + /** + * Text operation code for removing the prefix from the selected text block. + */ + public static const int STRIP_PREFIX= 12; + + + /** + * Returns whether the operation specified by the given operation code + * can be performed. + * + * @param operation the operation code + * @return true if the specified operation can be performed + */ + bool canDoOperation(int operation); + + /** + * Performs the operation specified by the operation code on the target. + * doOperation must only be called if canDoOperation + * returns true. + * + * @param operation the operation code + */ + void doOperation(int operation); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextOperationTargetExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextOperationTargetExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,180 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.ITextOperationTargetExtension; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + + +/** + * Extension interface for {@link dwtx.jface.text.ITextOperationTarget}. + *

                + * Allows a client to control the enable state of operations provided by this + * target. + * + * @see dwtx.jface.text.ITextOperationTarget + * @since 2.0 + */ +public interface ITextOperationTargetExtension { + + /** + * Enables/disabled the given text operation. + * + * @param operation the operation to enable/disable + * @param enable true to enable the operation otherwise false + */ + void enableOperation(int operation, bool enable); +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextPresentationListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextPresentationListener.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.ITextPresentationListener; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Text presentation listeners registered with an + * {@link dwtx.jface.text.ITextViewer} are informed when a + * {@link dwtx.jface.text.TextPresentation} is about to be applied to the + * text viewer. The listener can apply changes to the text presentation and thus + * participate in the process of text presentation creation. + * + * @since 3.0 + */ +public interface ITextPresentationListener { + + /** + * This method is called when a text presentation is about to be applied to + * the text viewer. The receiver is allowed to change the text presentation + * during that call. + * + * @param textPresentation the current text presentation + */ + public void applyTextPresentation(TextPresentation textPresentation); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextSelection.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextSelection.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,235 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.ITextSelection; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + + +import dwtx.jface.viewers.ISelection; + + +/** + * This interface represents a textual selection. A text selection is a range of + * characters. Although a text selection is a snapshot taken at a particular + * point in time, it must not copy the line information and the selected text + * from the selection provider. + *

                + * If, for example, the selection provider is a text viewer ( + * {@link dwtx.jface.text.ITextViewer}), and a text selection is created + * for the range [5, 10], the line formation for the 5th character must not be + * determined and remembered at the point of creation. It can rather be + * determined at the point, when getStartLine is called. If the + * source viewer range [0, 15] has been changed in the meantime between the + * creation of the text selection object and the invocation of + * getStartLine, the returned line number may differ from the + * line number of the 5th character at the point of creation of the text + * selection object. + *

                + * The contract of this interface is that weak in order to allow for efficient + * implementations.

                + *

                + * Clients may implement this interface or use the default implementation + * provided by {@link dwtx.jface.text.TextSelection}.

                + * + * @see dwtx.jface.text.TextSelection + */ +public interface ITextSelection : ISelection { + + /** + * Returns the offset of the selected text. + * + * @return the offset of the selected text + */ + int getOffset(); + + /** + * Returns the length of the selected text. + * + * @return the length of the selected text + */ + int getLength(); + + /** + * Returns number of the line containing the offset of the selected text. + * If the underlying text has been changed between the creation of this + * selection object and the call of this method, the value returned might + * differ from what it would have been at the point of creation. + * + * @return the start line of this selection or -1 if there is no valid line information + */ + int getStartLine(); + + /** + * Returns the number of the line containing the last character of the selected text. + * If the underlying text has been changed between the creation of this + * selection object and the call of this method, the value returned might + * differ from what it would have been at the point of creation. + * + * @return the end line of this selection or -1 if there is no valid line information + */ + int getEndLine(); + + /** + * Returns the selected text. + * If the underlying text has been changed between the creation of this + * selection object and the call of this method, the value returned might + * differ from what it would have been at the point of creation. + * + * @return the selected text or null if there is no valid text information + */ + String getText(); +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextStore.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextStore.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,213 @@ +/******************************************************************************* + * 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 + * 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.text.ITextStore; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Interface for storing and managing text. + *

                + * Provides access to the stored text and allows to manipulate it.

                + *

                + * Clients may + * implement this interface or use {@link dwtx.jface.text.GapTextStore} or + * {@link dwtx.jface.text.CopyOnWriteTextStore}.

                + */ +public interface ITextStore { + + /** + * Returns the character at the specified offset. + * + * @param offset the offset in this text store + * @return the character at this offset + */ + char get(int offset); + + /** + * Returns the text of the specified character range. + * + * @param offset the offset of the range + * @param length the length of the range + * @return the text of the range + */ + String get(int offset, int length); + + /** + * Returns number of characters stored in this text store. + * + * @return the number of characters stored in this text store + */ + int getLength(); + + /** + * Replaces the specified character range with the given text. + * replace(getLength(), 0, "some text") is a valid + * call and appends text to the end of the text store. + * + * @param offset the offset of the range to be replaced + * @param length the number of characters to be replaced + * @param text the substitution text + */ + void replace(int offset, int length, String text); + + /** + * Replace the content of the text store with the given text. + * Convenience method for replace(0, getLength(), text. + * + * @param text the new content of the text store + */ + void set(String text); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextViewer.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextViewer.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,692 @@ +/******************************************************************************* + * 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 + * 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.text.ITextViewer; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + + +import dwt.custom.StyledText; +import dwt.graphics.Color; +import dwt.graphics.Point; +import dwtx.jface.viewers.ISelectionProvider; + + +/** + * A text viewer connects a text widget with an + * {@link dwtx.jface.text.IDocument}. The document is used as the + * widget's text model. + *

                + * It supports the following kinds of listeners: + *

                  + *
                • view port listeners to inform about changes of the viewer's view port
                • + *
                • text listeners to inform about changes of the document and the + * subsequent viewer change
                • + *
                • text input listeners to inform about changes of the viewer's input + * document.
                • + *
                + * A text viewer supports a set of configuration options and plug-ins defining + * its behavior: + *
                  + *
                • undo manager
                • + *
                • double click behavior
                • + *
                • auto indentation
                • + *
                • text hover
                • + *
                + * Installed plug-ins are not automatically activated. Plug-ins must be + * activated with the activatePlugins call. Most plug-ins can be + * defined per content type. Content types are derived from a partitioning of + * the text viewer's input document. In case of documents that support multiple + * partitionings, the implementer is responsible for determining the + * partitioning to use. + *

                + * A text viewer also provides the concept of event consumption. Events handled + * by the viewer can be filtered and processed by a dynamic event consumer. With + * {@link dwtx.jface.text.ITextViewerExtension}, this mechanism has been + * replaced with the support for + * {@link dwt.custom.VerifyKeyListener}. + *

                + * A text viewer provides several text editing functions, some of them are + * configurable, through a text operation target interface. It also supports a + * presentation mode in which it only shows a specified section of its document. + * By calling setVisibleRegion clients define which section is + * visible. Clients can get access to this section by calling + * getVisibleRegion. The viewer's presentation mode does not + * affect any client of the viewer other than text listeners. With + * {@link dwtx.jface.text.ITextViewerExtension5} the visible region + * support has been reworked. With that extension interface, text viewers are + * allowed to show fractions of their input document. I.e. a widget selection of + * two visually neighboring characters is no longer guaranteed to be two + * neighboring characters in the viewer's input document. Thus, viewers + * implementing {@link dwtx.jface.text.ITextViewerExtension5} are + * potentially forced to change the fractions of the input document that are + * shown when clients ask for the visible region. + *

                + * + * In order to provide backward compatibility for clients of + * ITextViewer, extension interfaces are used as a means of + * evolution. The following extension interfaces exist: + *

                  + *
                • {@link dwtx.jface.text.ITextViewerExtension} since version 2.0 + * replacing the event consumer mechanism and introducing the concept of rewrite + * targets and means to manage the viewer's redraw behavior
                • + *
                • {@link dwtx.jface.text.ITextViewerExtension2}since version 2.1 + * adding a way to invalidate a viewer's presentation and setters for hovers. + *
                • + *
                • {@link dwtx.jface.text.ITextViewerExtension3} since version 2.1 + * which itself was replaced by + * {@link dwtx.jface.text.ITextViewerExtension5} in version 3.0
                • + *
                • {@link dwtx.jface.text.ITextViewerExtension4} since version 3.0 + * introducing focus handling for widget token keepers and the concept of text + * presentation listeners.
                • + *
                • {@link dwtx.jface.text.ITextViewerExtension5} since version 3.0 + * extending the visible region concept with explicit handling and conversion + * of widget and model coordinates.
                • + *
                • {@link dwtx.jface.text.ITextViewerExtension6} since version 3.1 + * extending the text viewer with the ability to detect hyperlinks and access the undo manager.
                • + *
                • {@link dwtx.jface.text.ITextViewerExtension7} since version 3.3 + * extending the text viewer with the ability to install tabs to spaces conversion.
                • + *
                • {@link dwtx.jface.text.ITextViewerExtension8} since version 3.4 + * extending the text viewer with the ability to print and rich hover support.
                • + *

                + *

                + * Clients may implement this interface and its extension interfaces or use the + * standard implementation {@link dwtx.jface.text.TextViewer}.

                + * + * @see dwtx.jface.text.ITextViewerExtension + * @see dwtx.jface.text.ITextViewerExtension2 + * @see dwtx.jface.text.ITextViewerExtension3 + * @see dwtx.jface.text.ITextViewerExtension4 + * @see dwtx.jface.text.ITextViewerExtension5 + * @see dwtx.jface.text.ITextViewerExtension6 + * @see dwtx.jface.text.ITextViewerExtension7 + * @see dwtx.jface.text.ITextViewerExtension8 + * @see dwtx.jface.text.IDocument + * @see dwtx.jface.text.ITextInputListener + * @see dwtx.jface.text.IViewportListener + * @see dwtx.jface.text.ITextListener + * @see dwtx.jface.text.IEventConsumer + */ +public interface ITextViewer { + + + /* ---------- widget --------- */ + + /** + * Returns this viewer's DWT control, null if the control is disposed. + *

                + * Calling API directly on the widget can interfere with features provided + * by a text viewer. Clients who call API directly on the widget are responsible + * to resolve such conflicts on their side. + *

                + * + * @return the DWT control or null + */ + StyledText getTextWidget(); + + + /* --------- plug-ins --------- */ + + /** + * Sets this viewer's undo manager. + * + * @param undoManager the new undo manager. null is a valid argument. + */ + void setUndoManager(IUndoManager undoManager); + + /** + * Sets this viewer's text double click strategy for the given content type. + * + * @param strategy the new double click strategy. null is a valid argument. + * @param contentType the type for which the strategy is registered + */ + void setTextDoubleClickStrategy(ITextDoubleClickStrategy strategy, String contentType); + + /** + * Sets this viewer's auto indent strategy for the given content type. If + * the given strategy is null any installed strategy for the + * content type is removed. This method has been replaced by + * {@link ITextViewerExtension2#prependAutoEditStrategy(IAutoEditStrategy, String)} and + * {@link ITextViewerExtension2#removeAutoEditStrategy(IAutoEditStrategy, String)}. + * It is now equivalent to + *
                +     *      ITextViewerExtension2 extension= cast(ITextViewerExtension2) viewer;
                +     *      extension.removeAutoEditStrategy(oldStrategy, contentType);
                +     *      extension.prependAutoEditStrategy(strategy, contentType);
                +     * 
                + * + * @param strategy the new auto indent strategy. null is a + * valid argument. + * @param contentType the type for which the strategy is registered + * @deprecated since 3.1, use + * {@link ITextViewerExtension2#prependAutoEditStrategy(IAutoEditStrategy, String)} and + * {@link ITextViewerExtension2#removeAutoEditStrategy(IAutoEditStrategy, String)} instead + */ + void setAutoIndentStrategy(IAutoIndentStrategy strategy, String contentType); + + /** + * Sets this viewer's text hover for the given content type. + *

                + * This method has been replaced by {@link ITextViewerExtension2#setTextHover(ITextHover, String, int)}. + * It is now equivalent to + *

                +     *    ITextViewerExtension2 extension= cast(ITextViewerExtension2) document;
                +     *    extension.setTextHover(textViewerHover, contentType, ITextViewerExtension2#DEFAULT_HOVER_STATE_MASK);
                +     * 
                + * + * + * @param textViewerHover the new hover. null is a valid + * argument. + * @param contentType the type for which the hover is registered + */ + void setTextHover(ITextHover textViewerHover, String contentType); + + /** + * Activates the installed plug-ins. If the plug-ins are already activated + * this call has no effect. + */ + void activatePlugins(); + + /** + * Resets the installed plug-ins. If plug-ins change their state or + * behavior over the course of time, this method causes them to be set + * back to their initial state and behavior. E.g., if an {@link IUndoManager} + * has been installed on this text viewer, the manager's list of remembered + * text editing operations is removed. + */ + void resetPlugins(); + + + + /* ---------- listeners ------------- */ + + /** + * Adds the given view port listener to this viewer. The listener + * is informed about all changes to the visible area of this viewer. + * If the listener is already registered with this viewer, this call + * has no effect. + * + * @param listener the listener to be added + */ + void addViewportListener(IViewportListener listener); + + /** + * Removes the given listener from this viewer's set of view port listeners. + * If the listener is not registered with this viewer, this call has + * no effect. + * + * @param listener the listener to be removed + */ + void removeViewportListener(IViewportListener listener); + + /** + * Adds a text listener to this viewer. If the listener is already registered + * with this viewer, this call has no effect. + * + * @param listener the listener to be added + */ + void addTextListener(ITextListener listener); + + /** + * Removes the given listener from this viewer's set of text listeners. + * If the listener is not registered with this viewer, this call has + * no effect. + * + * @param listener the listener to be removed + */ + void removeTextListener(ITextListener listener); + + /** + * Adds a text input listener to this viewer. If the listener is already registered + * with this viewer, this call has no effect. + * + * @param listener the listener to be added + */ + void addTextInputListener(ITextInputListener listener); + + /** + * Removes the given listener from this viewer's set of text input listeners. + * If the listener is not registered with this viewer, this call has + * no effect. + * + * @param listener the listener to be removed + */ + void removeTextInputListener(ITextInputListener listener); + + + + /* -------------- model manipulation ------------- */ + + /** + * Sets the given document as the text viewer's model and updates the + * presentation accordingly. An appropriate TextEvent is + * issued. This text event does not carry a related document event. + * + * @param document the viewer's new input document null if none + */ + void setDocument(IDocument document); + + /** + * Returns the text viewer's input document. + * + * @return the viewer's input document or null if none + */ + IDocument getDocument(); + + + /* -------------- event handling ----------------- */ + + /** + * Registers an event consumer with this viewer. This method has been + * replaces with the {@link dwt.custom.VerifyKeyListener} + * management methods in {@link ITextViewerExtension}. + * + * @param consumer the viewer's event consumer. null is a + * valid argument. + */ + void setEventConsumer(IEventConsumer consumer); + + /** + * Sets the editable state. + * + * @param editable the editable state + */ + void setEditable(bool editable); + + /** + * Returns whether the shown text can be manipulated. + * + * @return the viewer's editable state + */ + bool isEditable(); + + + /* ----------- visible region support ------------- */ + + /** + * Sets the given document as this viewer's model and + * exposes the specified region. An appropriate + * TextEvent is issued. The text event does not carry a + * related document event. This method is a convenience method for + * setDocument(document);setVisibleRegion(offset, length). + * + * @param document the new input document or null if none + * @param modelRangeOffset the offset of the model range + * @param modelRangeLength the length of the model range + */ + void setDocument(IDocument document, int modelRangeOffset, int modelRangeLength); + + /** + * Defines and sets the region of this viewer's document which will be + * visible in the presentation. Every character inside the specified region + * is supposed to be visible in the viewer's widget after that call. + * + * @param offset the offset of the visible region + * @param length the length of the visible region + */ + void setVisibleRegion(int offset, int length); + + /** + * Resets the region of this viewer's document which is visible in the presentation. + * Afterwards, the whole input document is visible. + */ + void resetVisibleRegion(); + + /** + * Returns the current visible region of this viewer's document. The result + * may differ from the argument passed to setVisibleRegion if + * the document has been modified since then. The visible region is supposed + * to be a consecutive region in viewer's input document and every character + * inside that region is supposed to visible in the viewer's widget. + *

                + * Viewers implementing {@link ITextViewerExtension5} may be forced to + * change the fractions of the input document that are shown, in order to + * fulfill this contract. + * + * @return this viewer's current visible region + */ + IRegion getVisibleRegion(); + + /** + * Returns whether a given range overlaps with the visible region of this + * viewer's document. + *

                + * Viewers implementing {@link ITextViewerExtension5}may be forced to + * change the fractions of the input document that are shown in order to + * fulfill this request. This is because the overlap is supposed to be + * without gaps. + * + * @param offset the offset + * @param length the length + * @return true if the specified range overlaps with the + * visible region + */ + bool overlapsWithVisibleRegion(int offset, int length); + + + + /* ------------- presentation manipulation ----------- */ + + /** + * Applies the color information encoded in the given text presentation. + * controlRedraw tells this viewer whether it should take care of + * redraw management or not. If, e.g., this call is one in a sequence of multiple + * presentation calls, it is more appropriate to explicitly control redrawing at the + * beginning and the end of the sequence. + * + * @param presentation the presentation to be applied to this viewer + * @param controlRedraw indicates whether this viewer should manage redraws + */ + void changeTextPresentation(TextPresentation presentation, bool controlRedraw); + + /** + * Marks the currently applied text presentation as invalid. It is the + * viewer's responsibility to take any action it can to repair the text + * presentation. + *

                + * See {@link ITextViewerExtension2#invalidateTextPresentation(int, int)} + * for a way to invalidate specific regions rather than the presentation as + * a whole. + * + * @since 2.0 + */ + void invalidateTextPresentation(); + + /** + * Applies the given color as text foreground color to this viewer's + * selection. + * + * @param color the color to be applied + */ + void setTextColor(Color color); + + /** + * Applies the given color as text foreground color to the specified section + * of this viewer. controlRedraw tells this viewer whether it + * should take care of redraw management or not. + * + * @param color the color to be applied + * @param offset the offset of the range to be changed + * @param length the length of the range to be changed + * @param controlRedraw indicates whether this viewer should manage redraws + */ + void setTextColor(Color color, int offset, int length, bool controlRedraw); + + + /* --------- target handling and configuration ------------ */ + + /** + * Returns the text operation target of this viewer. + * + * @return the text operation target of this viewer + */ + ITextOperationTarget getTextOperationTarget(); + + /** + * Returns the find/replace operation target of this viewer. + * + * @return the find/replace operation target of this viewer + */ + IFindReplaceTarget getFindReplaceTarget(); + + /** + * Sets the strings that are used as prefixes when lines of the given content type + * are prefixed using the prefix text operation. The prefixes are considered equivalent. + * Inserting a prefix always inserts the defaultPrefixes[0]. + * Removing a prefix removes all of the specified prefixes. + * + * @param defaultPrefixes the prefixes to be used + * @param contentType the content type for which the prefixes are specified + * @since 2.0 + */ + void setDefaultPrefixes(String[] defaultPrefixes, String contentType); + + /** + * Sets the strings that are used as prefixes when lines of the given content type + * are shifted using the shift text operation. The prefixes are considered equivalent. + * Thus "\t" and " " can both be used as prefix characters. + * Shift right always inserts the indentPrefixes[0]. + * Shift left removes all of the specified prefixes. + * + * @param indentPrefixes the prefixes to be used + * @param contentType the content type for which the prefixes are specified + */ + void setIndentPrefixes(String[] indentPrefixes, String contentType); + + + + /* --------- selection handling -------------- */ + + /** + * Sets the selection to the specified range. + * + * @param offset the offset of the selection range + * @param length the length of the selection range. A negative length places + * the caret at the visual start of the selection. + */ + void setSelectedRange(int offset, int length); + + /** + * Returns the range of the current selection in coordinates of this viewer's document. + * + * @return a Point with x as the offset and y as the length of the current selection + */ + Point getSelectedRange(); + + /** + * Returns a selection provider dedicated to this viewer. Subsequent + * calls to this method return always the same selection provider. + * + * @return this viewer's selection provider + */ + ISelectionProvider getSelectionProvider(); + + + /* ------------- appearance manipulation --------------- */ + + /** + * Ensures that the given range is visible. + * + * @param offset the offset of the range to be revealed + * @param length the length of the range to be revealed + */ + void revealRange(int offset, int length); + + /** + * Scrolls the widget so that the given index is the line + * with the smallest line number of all visible lines. + * + * @param index the line which should become the top most line + */ + void setTopIndex(int index); + + /** + * Returns the visible line with the smallest line number. + * + * @return the number of the top most visible line + */ + int getTopIndex(); + + /** + * Returns the document offset of the upper left corner of this viewer's view port. + * + * @return the upper left corner offset + */ + int getTopIndexStartOffset(); + + /** + * Returns the visible line with the highest line number. + * + * @return the number of the bottom most line + */ + int getBottomIndex(); + + /** + * Returns the document offset of the lower right + * corner of this viewer's view port. This is the visible character + * with the highest character position. If the content of this viewer + * is shorter, the position of the last character of the content is returned. + * + * @return the lower right corner offset + */ + int getBottomIndexEndOffset(); + + /** + * Returns the vertical offset of the first visible line. + * + * @return the vertical offset of the first visible line + */ + int getTopInset(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextViewerExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextViewerExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.ITextViewerExtension; + +import dwtx.jface.text.IRewriteTarget; // packageimport + +import dwt.dwthelper.utils; + +import dwt.custom.VerifyKeyListener; +import dwt.widgets.Control; + + +/** + * Extension interface for {@link dwtx.jface.text.ITextViewer}. + *

                + * This extension interface replaces the event consumer mechanism ( + * {@link dwtx.jface.text.ITextViewer#setEventConsumer(IEventConsumer)}) + * with a set of methods that allow to manage a sequence of + * {@link dwt.custom.VerifyKeyListener}objects. It also adds + *

                  + *
                • access to the control of this viewer
                • + *
                • marked region support as in emacs
                • + *
                • control of the viewer's redraw behavior by introducing + * setRedraw(bool) + *
                • access to the viewer's rewrite target. + *
                + * + * A rewrite target ({@link dwtx.jface.text.IRewriteTarget}) represents + * an facade offering the necessary methods to manipulate a document that is the + * input document of a text viewer. + * + * @since 2.0 + */ +public interface ITextViewerExtension { + + /** + * Inserts the verify key listener at the beginning of the viewer's list of + * verify key listeners. If the listener is already registered with the + * viewer this call moves the listener to the beginning of the list. + * + * @param listener the listener to be inserted + */ + void prependVerifyKeyListener(VerifyKeyListener listener); + + /** + * Appends a verify key listener to the viewer's list of verify key + * listeners. If the listener is already registered with the viewer this + * call moves the listener to the end of the list. + * + * @param listener the listener to be added + */ + void appendVerifyKeyListener(VerifyKeyListener listener); + + /** + * Removes the verify key listener from the viewer's list of verify key listeners. + * If the listener is not registered with this viewer, this call has no effect. + * + * @param listener the listener to be removed + */ + void removeVerifyKeyListener(VerifyKeyListener listener); + + /** + * Returns the control of this viewer. + * + * @return the control of this viewer + */ + Control getControl(); + + /** + * Sets a mark at the given offset or clears the mark if the specified + * offset is -1. If a mark is set and the selection is + * empty, cut and copy actions performed on this text viewer work on the + * region described by the positions of the mark and the cursor. + * + * @param offset the offset of the mark + */ + void setMark(int offset); + + /** + * Returns the position of the mark, -1 if the mark is not set. + * + * @return the position of the mark or -1 if no mark is set + */ + int getMark(); + + /** + * Enables/disables the redrawing of this text viewer. This temporarily + * disconnects the viewer from its underlying + * {@link dwt.custom.StyledText}widget. While being + * disconnected only the viewer's selection may be changed using + * setSelectedRange. Any direct manipulation of the widget + * as well as calls to methods that change the viewer's presentation state + * (such as enabling the segmented view) are not allowed. When redrawing is + * disabled the viewer does not send out any selection or view port change + * notification. When redrawing is enabled again, a selection change + * notification is sent out for the selected range and this range is + * revealed causing a view port changed notification. + * + * @param redraw true to enable redrawing, false + * otherwise + */ + void setRedraw(bool redraw); + + /** + * Returns the viewer's rewrite target. + * + * @return the viewer's rewrite target + */ + IRewriteTarget getRewriteTarget(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextViewerExtension2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextViewerExtension2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,276 @@ +/******************************************************************************* + * 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 + * 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.text.ITextViewerExtension2; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + +import dwt.graphics.Point; + +/** + * Extension interface for {@link dwtx.jface.text.ITextViewer}. + *

                + * It provides + *

                  + *
                • text presentation invalidation enhancements
                • + *
                • text hover management enhancements
                • + *
                • a replacement for auto indent strategies
                • + *
                • support for custom painters
                • + *
                + * + * It extends the means for text presentation invalidation by allowing a + * specific region of the presentation to get invalidated. It replaces + * {@link dwtx.jface.text.ITextViewer#setTextHover(ITextHover, String)} + * with a new method that allows to specify state masks for a better control of + * the hover behavior. + *

                + * An {@link dwtx.jface.text.IAutoEditStrategy} is a generalization of + * the original {@link dwtx.jface.text.IAutoIndentStrategy}. Auto edit + * strategies can be arranged in a list that is executed like a pipeline when + * the viewer content is changed. + *

                + * A {@link dwtx.jface.text.IPainter}is creating and managing visual + * decorations on the viewer's text widget. Viewer's can have an open number of + * painters. Painters are informed about changes to the viewer content and state + * and can take the necessary action in responds to the notification. + * + * @since 2.1 + */ +public interface ITextViewerExtension2 { + + /** + * The state mask of the default hover (value 0xff). + */ + static const int DEFAULT_HOVER_STATE_MASK= 0xff; + + /** + * Invalidates the viewer's text presentation for the given range. + * + * @param offset the offset of the first character to be redrawn + * @param length the length of the range to be redrawn + */ + void invalidateTextPresentation(int offset, int length); + + /** + * Sets this viewer's text hover for the given content type and the given state mask. If the given text hover + * is null, any hover installed for the given content type and state mask is removed. + * + * @param textViewerHover the new hover or null + * @param contentType the type for which the hover is to be registered or unregistered + * @param stateMask the DWT event state mask; DEFAULT_HOVER_STATE_MASK indicates that + * the hover is installed as the default hover. + */ + void setTextHover(ITextHover textViewerHover, String contentType, int stateMask); + + /** + * Removes all text hovers for the given content type independent from their state mask. + *

                + * Note: To remove a hover for a given content type and state mask + * use {@link #setTextHover(ITextHover, String, int)} with null + * as parameter for the text hover. + *

                + * @param contentType the type for which all text hovers are to be unregistered + */ + void removeTextHovers(String contentType); + + /** + * Returns the currently displayed text hover if any, null otherwise. + * + * @return the currently displayed text hover or null + */ + ITextHover getCurrentTextHover(); + + /** + * Returns the location at which the most recent mouse hover event + * has occurred. + * + * @return the location of the most recent mouse hover event + */ + Point getHoverEventLocation(); + + /** + * Prepends the given auto edit strategy to the existing list of strategies + * for the specified content type. The strategies are called in the order in + * which they appear in the list of strategies. + * + * @param strategy the auto edit strategy + * @param contentType the content type + */ + void prependAutoEditStrategy(IAutoEditStrategy strategy, String contentType); + + /** + * Removes the first occurrence of the given auto edit strategy in the list of strategies + * registered under the specified content type. + * + * @param strategy the auto edit strategy + * @param contentType the content type + */ + void removeAutoEditStrategy(IAutoEditStrategy strategy, String contentType); + + /** + * Adds the given painter to this viewer. + * + * @param painter the painter to be added + */ + void addPainter(IPainter painter); + + /** + * Removes the given painter from this viewer. If the painter has not been + * added to this viewer, this call is without effect. + * + * @param painter the painter to be removed + */ + void removePainter(IPainter painter); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextViewerExtension3.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextViewerExtension3.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,100 @@ +/******************************************************************************* + * 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 + * 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.text.ITextViewerExtension3; + +import dwtx.jface.text.IRegion; // packageimport + +import dwt.dwthelper.utils; + + +/** + * Extension interface for {@link dwtx.jface.text.ITextViewer}.

                + * This interface has been replaced by {@link dwtx.jface.text.ITextViewerExtension5}. + * Clients are not supposed to use this interface any longer. + * + * @since 2.1 + * @deprecated replaced by {@link dwtx.jface.text.ITextViewerExtension5} + */ +public interface ITextViewerExtension3 { + + + /** + * Returns the minimal region of the viewer's document that completely comprises everything that is + * visible in the viewer's widget or null if there is no such region. + * + * @return the minimal region of the viewer's document comprising the contents of the viewer's widget or null + */ + IRegion getModelCoverage(); + + + /** + * Returns the widget line that corresponds to the given line of the viewer's document or -1 if there is no such line. + * + * @param modelLine the line of the viewer's document + * @return the corresponding widget line or -1 + */ + int modelLine2WidgetLine(int modelLine); + + /** + * Returns the widget offset that corresponds to the given offset in the viewer's document + * or -1 if there is no such offset + * + * @param modelOffset the offset in the viewer's document + * @return the corresponding widget offset or -1 + */ + int modelOffset2WidgetOffset(int modelOffset); + + /** + * Returns the minimal region of the viewer's widget that completely comprises the given region of the + * viewer's document or null if there is no such region. + * + * @param modelRange the region of the viewer's document + * @return the minimal region of the widget comprising modelRange or null + */ + IRegion modelRange2WidgetRange(IRegion modelRange); + + + /** + * Returns the offset of the viewer's document that corresponds to the given widget offset + * or -1 if there is no such offset + * + * @param widgetOffset the widget offset + * @return the corresponding offset in the viewer's document or -1 + */ + int widgetOffset2ModelOffset(int widgetOffset); + + /** + * Returns the minimal region of the viewer's document that completely comprises the given widget region + * or null if there is no such region. + * + * @param widgetRange the widget region + * @return the minimal region of the viewer's document comprising widgetRange or null + */ + IRegion widgetRange2ModelRange(IRegion widgetRange); + + /** + * Returns the line of the viewer's document that corresponds to the given widget line or -1 if there is no such line. + * + * @param widgetLine the widget line + * @return the corresponding line of the viewer's document or -1 + */ + int widgetlLine2ModelLine(int widgetLine); + + /** + * Returns the widget line of the given widget offset. + * + * @param widgetOffset the widget offset + * @return the widget line of the widget offset + */ + int widgetLineOfWidgetOffset(int widgetOffset); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextViewerExtension4.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextViewerExtension4.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.ITextViewerExtension4; + +import dwtx.jface.text.ITextPresentationListener; // packageimport + +import dwt.dwthelper.utils; + + +/** + * Extension interface for {@link dwtx.jface.text.ITextViewer}. + * Introduces the concept of text presentation listeners and improves focus + * handling among widget token keepers. + *

                + * A {@link dwtx.jface.text.ITextPresentationListener}is a listener that + * is informed by the viewer that a text presentation is about to be applied. + * During this callback the listener is allowed to modify the presentation. Text + * presentation listeners are thus a mean to participate in the process of text + * presentation creation. + * + * @since 3.0 + */ +public interface ITextViewerExtension4 { + + /** + * Instructs the receiver to request the {@link IWidgetTokenKeeper} + * currently holding the widget token to take the keyboard focus. + * + * @return true if there was any + * IWidgetTokenKeeper that was asked to take the + * focus, false otherwise + */ + bool moveFocusToWidgetToken(); + + /** + * Adds the given text presentation listener to this text viewer. + * This call has no effect if the listener is already registered + * with this text viewer. + * + * @param listener the text presentation listener + */ + void addTextPresentationListener(ITextPresentationListener listener); + + /** + * Removes the given text presentation listener from this text viewer. + * This call has no effect if the listener is not registered with this + * text viewer. + * + * @param listener the text presentation listener + */ + void removeTextPresentationListener(ITextPresentationListener listener); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextViewerExtension5.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextViewerExtension5.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,140 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.ITextViewerExtension5; + +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport + +import dwt.dwthelper.utils; + +/** + * Extension interface for {@link dwtx.jface.text.ITextViewer}. Defines + * a conceptual replacement of the original visible region concept. This interface + * replaces {@link dwtx.jface.text.ITextViewerExtension3}. + *

                + * Introduces the explicit concept of model and widget coordinates. For example, + * a selection returned by the text viewer's control is a widget selection. A + * widget selection always maps to a certain range of the viewer's document. + * This range is considered the model selection. + *

                + * All model ranges that have a corresponding widget ranges are considered + * "exposed model ranges". The viewer can be requested to expose a given model + * range. Thus, a visible region is a particular degeneration of exposed model + * ranges. + *

                + * This interface allows implementers to follow a sophisticated presentation + * model in which the visible presentation is a complex projection of the + * viewer's input document. + * + * @since 3.0 + */ +public interface ITextViewerExtension5 : ITextViewerExtension3 { + + /** + * Returns the minimal region of the viewer's input document that completely + * comprises everything that is visible in the viewer's widget or + * null if there is no such region. + * + * @return the minimal region of the viewer's document comprising the + * contents of the viewer's widget or null + */ + IRegion getModelCoverage(); + + /** + * Returns the widget line that corresponds to the given line of the + * viewer's input document or -1 if there is no such line. + * + * @param modelLine the line of the viewer's document + * @return the corresponding widget line or -1 + */ + int modelLine2WidgetLine(int modelLine); + + /** + * Returns the widget offset that corresponds to the given offset in the + * viewer's input document or -1 if there is no such offset + * + * @param modelOffset the offset in the viewer's document + * @return the corresponding widget offset or -1 + */ + int modelOffset2WidgetOffset(int modelOffset); + + /** + * Returns the minimal region of the viewer's widget that completely + * comprises the given region of the viewer's input document or + * null if there is no such region. + * + * @param modelRange the region of the viewer's document + * @return the minimal region of the widget comprising + * modelRange or null + */ + IRegion modelRange2WidgetRange(IRegion modelRange); + + /** + * Returns the offset of the viewer's input document that corresponds to the + * given widget offset or -1 if there is no such offset + * + * @param widgetOffset the widget offset + * @return the corresponding offset in the viewer's document or + * -1 + */ + int widgetOffset2ModelOffset(int widgetOffset); + + /** + * Returns the minimal region of the viewer's input document that completely + * comprises the given widget region or null if there is no + * such region. + * + * @param widgetRange the widget region + * @return the minimal region of the viewer's document comprising + * widgetlRange or null + */ + IRegion widgetRange2ModelRange(IRegion widgetRange); + + /** + * Returns the line of the viewer's input document that corresponds to the + * given widget line or -1 if there is no such line. + * + * @param widgetLine the widget line + * @return the corresponding line of the viewer's document or + * -1 + */ + int widgetLine2ModelLine(int widgetLine); + + /** + * Returns the widget line of the given widget offset. + * + * @param widgetOffset the widget offset + * @return the widget line of the widget offset + */ + int widgetLineOfWidgetOffset(int widgetOffset); + + + /** + * Returns the maximal subranges of the given model range thus that there is + * no offset inside a subrange for which there is no image offset. + * + * @param modelRange the model range + * @return the list of subranges + */ + IRegion[] getCoveredModelRanges(IRegion modelRange); + + /** + * Exposes the given model range. Returns whether this call caused a change + * of the set of exposed model ranges. + * + * @param modelRange the model range to be exposed + * @return true if the set of exposed model ranges changed, + * false otherwise + */ + bool exposeModelRange(IRegion modelRange); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextViewerExtension6.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextViewerExtension6.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,48 @@ +/******************************************************************************* + * 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.text.ITextViewerExtension6; + +import dwtx.jface.text.IUndoManager; // packageimport + +import dwt.dwthelper.utils; + +import dwtx.jface.text.hyperlink.IHyperlinkDetector; + +/** + * Extension interface for {@link dwtx.jface.text.ITextViewer}. + * Introduces the concept of text hyperlinks and adds access to the undo manager. + * + * @see dwtx.jface.text.hyperlink.IHyperlink + * @see dwtx.jface.text.hyperlink.IHyperlinkDetector + * @since 3.1 + */ +public interface ITextViewerExtension6 { + + /** + * Sets this viewer's hyperlink detectors for the given state mask. + * + * @param hyperlinkDetectors the new array of hyperlink detectors, null + * or an empty array to disable hyperlinking + * @param eventStateMask the DWT event state mask to activate hyperlink mode + */ + void setHyperlinkDetectors(IHyperlinkDetector[] hyperlinkDetectors, int eventStateMask); + + /** + * Returns this viewer's undo manager. + * + * @return the undo manager or null if it has not been plugged-in + * @since 3.1 + */ + IUndoManager getUndoManager(); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextViewerExtension7.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextViewerExtension7.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,34 @@ +/******************************************************************************* + * 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.text.ITextViewerExtension7; + +import dwtx.jface.text.IAutoEditStrategy; // packageimport + +import dwt.dwthelper.utils; + + +/** + * Extension interface for {@link dwtx.jface.text.ITextViewer}. + * Adds the ability to install tabs to spaces conversion. + * + * @since 3.3 + */ +public interface ITextViewerExtension7 { + + /** + * Sets an auto edit strategy can converts tabs to spaces. + * + * @param converter the converter or null if none should be used + */ + void setTabsToSpacesConverter(IAutoEditStrategy converter); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITextViewerExtension8.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITextViewerExtension8.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,101 @@ +/******************************************************************************* + * 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 + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.text.ITextViewerExtension8; + +import dwt.dwthelper.utils; + +import dwt.custom.StyledTextPrintOptions; + + +/** + * Extension interface for {@link dwtx.jface.text.ITextViewer}. Adds the + * ability to print and set how hovers should be enriched when the mouse is moved into them. + * + * @since 3.4 + */ +public interface ITextViewerExtension8 { + + /** + * Print the text viewer contents using the given options. + * + * @param options the print options + */ + void print(StyledTextPrintOptions options); + + /** + * Sets the hover enrich mode. + * A non-null mode defines when hovers + * should be enriched once the mouse is moved into them. + * If mode is null, hovers are automatically closed + * when the mouse is moved out of the {@link ITextHover#getHoverRegion(ITextViewer, int) hover region}. + *

                + * Note that a hover can only be enriched if its {@link IInformationControlExtension5#getInformationPresenterControlCreator()} + * is not null. + *

                + * + * @param mode the enrich mode, or null + */ + void setHoverEnrichMode(EnrichMode mode); + + + +} + + /** + * Type-safe enum of the available enrich modes. + */ + public final class EnrichMode { + + /** + * Enrich the hover shortly after the mouse has been moved into it and + * stopped moving. + * + * @see ITextViewerExtension8#setHoverEnrichMode(dwtx.jface.text.ITextViewerExtension8.EnrichMode) + */ + public static const EnrichMode AFTER_DELAY; + + /** + * Enrich the hover immediately when the mouse is moved into it. + * + * @see ITextViewerExtension8#setHoverEnrichMode(dwtx.jface.text.ITextViewerExtension8.EnrichMode) + */ + public static const EnrichMode IMMEDIATELY; + + /** + * Enrich the hover on explicit mouse click. + * + * @see ITextViewerExtension8#setHoverEnrichMode(dwtx.jface.text.ITextViewerExtension8.EnrichMode) + */ + public static const EnrichMode ON_CLICK; + + + static this(){ + AFTER_DELAY= new EnrichMode("after delay"); //$NON-NLS-1$ + IMMEDIATELY= new EnrichMode("immediately"); //$NON-NLS-1$ + ON_CLICK= new EnrichMode("on click"); //$NON-NLS-1$; + } + + private String fName; + + private this(String name) { + fName= name; + } + + /* + * @see java.lang.Object#toString() + */ + public override String toString() { + return fName; + } + } +alias EnrichMode ITextViewerExtension8_EnrichMode; diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ITypedRegion.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ITypedRegion.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.ITypedRegion; + +import dwtx.jface.text.IRegion; // packageimport + +import dwt.dwthelper.utils; + + + +/** + * Describes a region of an indexed text store such as a document or a string. + * The region consists of offset, length, and type. The region type is defined + * as a string. + *

                + * A typed region can, e.g., be used to described document partitions.

                + *

                + * Clients may implement this interface or use the standard implementation + * {@link dwtx.jface.text.TypedRegion}.

                + */ +public interface ITypedRegion : IRegion { + + /** + * Returns the content type of the region. + * + * @return the content type of the region + */ + String getType(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IUndoManager.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IUndoManager.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,110 @@ +/******************************************************************************* + * 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 + * 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.text.IUndoManager; + +import dwtx.jface.text.ITextViewer; // packageimport + +import dwt.dwthelper.utils; + +/** + * An undo manager is connected to at most one + * {@link dwtx.jface.text.ITextViewer}. + *

                + * It monitors the text viewer and keeps a history of the changes applied to the + * viewer. The undo manager groups those changes into user interactions which on + * an undo request are rolled back in one atomic change.

                + *

                + * In order to provide backward compatibility for clients of + * IUndoManager, extension interfaces are used as a means of + * evolution. The following extension interfaces exist: + *

                  + *
                • {@link dwtx.jface.text.IUndoManagerExtension} since version 3.1 + * introducing access to the undo context.
                • + *

                + *

                + * Clients may implement this interface or use the standard implementation + * TextViewerUndoManager. + *

                + * + * @see TextViewerUndoManager + * @see IUndoManagerExtension + */ +public interface IUndoManager { + + /** + * Connects this undo manager to the given text viewer. + * + * @param viewer the viewer the undo manager is connected to + */ + void connect(ITextViewer viewer); + + /** + * Disconnects this undo manager from its text viewer. + * If this undo manager hasn't been connected before this + * operation has no effect. + */ + void disconnect(); + + /** + * Signals the undo manager that all subsequent changes until + * endCompoundChange is called are to be undone in one piece. + */ + void beginCompoundChange(); + + /** + * Signals the undo manager that the sequence of changes which started with + * beginCompoundChange has been finished. All subsequent changes + * are considered to be individually undo-able. + */ + void endCompoundChange(); + + /** + * Resets the history of the undo manager. After that call, + * there aren't any undo-able or redo-able text changes. + */ + void reset(); + + /** + * The given parameter determines the maximal length of the history + * remembered by the undo manager. + * + * @param undoLevel the length of this undo manager's history + */ + void setMaximalUndoLevel(int undoLevel); + + /** + * Returns whether at least one text change can be rolled back. + * + * @return true if at least one text change can be rolled back + */ + bool undoable(); + + /** + * Returns whether at least one text change can be repeated. A text change + * can be repeated only if it was executed and rolled back. + * + * @return true if at least on text change can be repeated + */ + bool redoable(); + + /** + * Rolls back the most recently executed text change. + */ + void undo(); + + /** + * Repeats the most recently rolled back text change. + */ + void redo(); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IUndoManagerExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IUndoManagerExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IUndoManagerExtension; + +import dwt.dwthelper.utils; + +import dwtx.core.commands.operations.IUndoContext; + + +/** + * Extension interface for {@link dwtx.jface.text.IUndoManager}. + * Introduces access to the undo context. + * + * @see dwtx.jface.text.IUndoManager + * @since 3.1 + */ +public interface IUndoManagerExtension { + + /** + * Returns this undo manager's undo context. + * + * @return the undo context or null if the undo manager is not connected + * @see dwtx.core.commands.operations.IUndoContext + */ + IUndoContext getUndoContext(); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IViewportListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IViewportListener.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IViewportListener; + +import dwt.dwthelper.utils; + + +/** + * Registered with a text viewer, view port listeners are informed about changes + * of a text viewer's view port. The view port is that portion of the viewer's + * document which is visible in the viewer. + *

                + * Clients may implement this interface.

                + * + * @see dwtx.jface.text.ITextViewer + */ +public interface IViewportListener { + + /** + * Informs about view port changes. The given vertical position is the new + * vertical scrolling offset measured in pixels. + * + * @param verticalOffset the vertical offset measured in pixels + */ + void viewportChanged(int verticalOffset); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IWidgetTokenKeeper.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IWidgetTokenKeeper.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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 + * 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.text.IWidgetTokenKeeper; + +import dwtx.jface.text.IWidgetTokenOwner; // packageimport + +import dwt.dwthelper.utils; + +/** + * A widget token keeper may require a widget token from an + * {@link dwtx.jface.text.IWidgetTokenOwner} and release the token to the + * owner after usage. A widget token owner may request the token from the token + * keeper. The keeper may deny the return of the token. + *

                + * The widget token owner and keeper interplay is used by a text viewer in + * order to manage the appearance and disappearance of addition, on-top popup + * windows such as text hovers, content assist, etc. + * + * In order to provide backward compatibility for clients of + * IWidgetTokeKeeper, extension interfaces are used as a means + * of evolution. The following extension interfaces exist: + *

                  + *
                • {@link dwtx.jface.text.IWidgetTokenKeeperExtension} since version + * 3.0 introducing priorities when requesting a widget token and thus replacing + * the non-prioritized scheme. It also allows a client to force a widget token + * keeper to accept focus.
                • + *
                + * + * @see dwtx.jface.text.IWidgetTokenKeeperExtension + * @since 2.0 + */ +public interface IWidgetTokenKeeper { + + /** + * The given widget token owner requests the widget token from this token + * keeper. Returns true if the token is released by this + * token keeper. Note, the keeper must not call + * releaseWidgetToken(IWidgetTokenKeeper) explicitly. + *

                + * Replaced by + * {@link IWidgetTokenKeeperExtension#requestWidgetToken(IWidgetTokenOwner, int)}. + * + * @param owner the token owner + * @return true if token has been released false + * otherwise + */ + bool requestWidgetToken(IWidgetTokenOwner owner); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IWidgetTokenKeeperExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IWidgetTokenKeeperExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IWidgetTokenKeeperExtension; + +import dwtx.jface.text.IWidgetTokenOwner; // packageimport + +import dwt.dwthelper.utils; + +/** + * Extension interface for {@link dwtx.jface.text.IWidgetTokenKeeper}. + *

                + * Replaces the original requestWidgetToken functionality with a + * new priority based approach. Adds the concept of focus handling. + * + * @since 3.0 + */ +public interface IWidgetTokenKeeperExtension { + + /** + * The given widget token owner requests the widget token from + * this token keeper. Returns true if the token is released + * by this token keeper. Note, the keeper must not call + * releaseWidgetToken(IWidgetTokenKeeper) explicitly. + * + *

                The general contract is that the receiver should release the token + * if priority exceeds the receiver's priority.

                + * + * @param owner the token owner + * @param priority the priority of the request + * @return true if token has been released false otherwise + */ + bool requestWidgetToken(IWidgetTokenOwner owner, int priority); + + /** + * Requests the receiver to give focus to its popup shell, hover, or similar. There is + * no assumption made whether the receiver actually succeeded in taking the focus. The return + * value gives a hint whether the receiver tried to take focus. + * + * @param owner the token owner + * @return true if the receiver tried to take focus, false if it did not. + */ + bool setFocus(IWidgetTokenOwner owner); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IWidgetTokenOwner.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IWidgetTokenOwner.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,66 @@ +/******************************************************************************* + * 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 + * 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.text.IWidgetTokenOwner; + +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport + +import dwt.dwthelper.utils; + + +/** + * In order to display information in a temporary window, a widget token must be + * acquired. The intent behind this concept is that only one temporary window + * should be presented at any moment in time and also to avoid overlapping + * temporary windows. This concept is used by the + * {@link dwtx.jface.text.ITextViewer}. + *

                + * In order to provide backward compatibility for clients of + * IWidgetTokenOwner, extension interfaces are used as a means + * of evolution. The following extension interfaces exist: + *

                  + *
                • {@link dwtx.jface.text.IWidgetTokenOwnerExtension} since version + * 3.0 introducing priorities when requesting a widget token and thus replacing + * the non-prioritized scheme.
                • + *
                + * + * @see dwtx.jface.text.IWidgetTokenOwnerExtension + * @since 2.0 + */ +public interface IWidgetTokenOwner { + + /** + * Requests the widget token from this token owner. Returns + * true if the token has been acquired or is already owned by + * the requester. This method is non-blocking. + *

                + * Replaced by + * {@link IWidgetTokenOwnerExtension#requestWidgetToken(IWidgetTokenKeeper, int)}. + * + * @param requester the token requester + * @return true if requester acquires the token, + * false otherwise + */ + bool requestWidgetToken(IWidgetTokenKeeper requester); + + /** + * The given token keeper releases the token to this + * token owner. If the token has previously not been held + * by the given token keeper, nothing happens. This + * method is non-blocking. + * + * @param tokenKeeper the token keeper + */ + void releaseWidgetToken(IWidgetTokenKeeper tokenKeeper); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/IWidgetTokenOwnerExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/IWidgetTokenOwnerExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.IWidgetTokenOwnerExtension; + +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport + +import dwt.dwthelper.utils; + +/** + * Extension interface for {@link dwtx.jface.text.IWidgetTokenOwner}. + *

                + * Replaces the original requestWidgetToken functionality with a + * new priority based approach. + * + * @since 3.0 + */ +public interface IWidgetTokenOwnerExtension { + + /** + * Requests the widget token from this token owner. Returns + * true if the token has been acquired or is + * already owned by the requester. This method is non-blocking. + * + *

                priority is forwarded to any existing token keeper + * to give it an estimate on whether the request has higher priority than + * the current keeper's. There is, however, no guarantee that another keeper + * will release the token even if it has a high priority.

                + * + * @param requester the token requester + * @param priority the priority of the request + * @return true if requester acquires the token, + * false otherwise + */ + bool requestWidgetToken(IWidgetTokenKeeper requester, int priority); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/JFaceTextMessages.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/JFaceTextMessages.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,182 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.JFaceTextMessages; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.dwthelper.ResourceBundle; + +class JFaceTextMessages { + +// private static const String RESOURCE_BUNDLE= "dwtx.jface.text.JFaceTextMessages";//$NON-NLS-1$ + + private static ResourceBundle fgResourceBundle;//= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + static this() { + fgResourceBundle = ResourceBundle.getBundle( + getImportData!("dwtx.jface.text.JFaceTextMessages.properties")); + } + + private this() { + } + + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" ~ key ~ "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/JFaceTextUtil.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/JFaceTextUtil.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,503 @@ +/******************************************************************************* + * 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 + * 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.text.JFaceTextUtil; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + + +import dwt.custom.StyledText; +import dwt.graphics.GC; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Control; +import dwtx.jface.text.source.ILineRange; +import dwtx.jface.text.source.LineRange; + +/** + * A collection of JFace Text functions. + *

                + * This class is neither intended to be instantiated nor subclassed. + *

                + * + * @since 3.3 + * @noinstantiate This class is not intended to be instantiated by clients. + */ +public final class JFaceTextUtil { + + private this() { + // Do not instantiate + } + + /** + * Computes the line height for the given line range. + * + * @param textWidget the StyledText widget + * @param startLine the start line + * @param endLine the end line (exclusive) + * @param lineCount the line count used by the old API + * @return the height of all lines starting with startLine and ending above endLime + */ + public static int computeLineHeight(StyledText textWidget, int startLine, int endLine, int lineCount) { + return getLinePixel(textWidget, endLine) - getLinePixel(textWidget, startLine); + } + + /** + * Returns the last fully visible line of the widget. The exact semantics of "last fully visible + * line" are: + *
                  + *
                • the last line of which the last pixel is visible, if any + *
                • otherwise, the only line that is partially visible + *
                + * + * @param widget the widget + * @return the last fully visible line + */ + public static int getBottomIndex(StyledText widget) { + int lastPixel= computeLastVisiblePixel(widget); + + // bottom is in [0 .. lineCount - 1] + int bottom= widget.getLineIndex(lastPixel); + + // bottom is the first line - no more checking + if (bottom is 0) + return bottom; + + int pixel= widget.getLinePixel(bottom); + // bottom starts on or before the client area start - bottom is the only visible line + if (pixel <= 0) + return bottom; + + int offset= widget.getOffsetAtLine(bottom); + int height= widget.getLineHeight(offset); + + // bottom is not showing entirely - use the previous line + if (pixel + height - 1 > lastPixel) + return bottom - 1; + + // bottom is fully visible and its last line is exactly the last pixel + return bottom; + } + + /** + * Returns the index of the first (possibly only partially) visible line of the widget + * + * @param widget the widget + * @return the index of the first line of which a pixel is visible + */ + public static int getPartialTopIndex(StyledText widget) { + // see StyledText#getPartialTopIndex() + int top= widget.getTopIndex(); + int pixels= widget.getLinePixel(top); + + // FIXME remove when https://bugs.eclipse.org/bugs/show_bug.cgi?id=123770 is fixed + if (pixels is -widget.getLineHeight(widget.getOffsetAtLine(top))) { + top++; + pixels= 0; + } + + if (pixels > 0) + top--; + + return top; + } + + /** + * Returns the index of the last (possibly only partially) visible line of the widget + * + * @param widget the text widget + * @return the index of the last line of which a pixel is visible + */ + public static int getPartialBottomIndex(StyledText widget) { + // @see StyledText#getPartialBottomIndex() + int lastPixel= computeLastVisiblePixel(widget); + int bottom= widget.getLineIndex(lastPixel); + return bottom; + } + + /** + * Returns the last visible pixel in the widget's client area. + * + * @param widget the widget + * @return the last visible pixel in the widget's client area + */ + private static int computeLastVisiblePixel(StyledText widget) { + int caHeight= widget.getClientArea().height; + int lastPixel= caHeight - 1; + // XXX what if there is a margin? can't take trim as this includes the scrollbars which are not part of the client area +// if ((textWidget.getStyle() & DWT.BORDER) !is 0) +// lastPixel -= 4; + return lastPixel; + } + + /** + * Returns the line index of the first visible model line in the viewer. The line may be only + * partially visible. + * + * @param viewer the text viewer + * @return the first line of which a pixel is visible, or -1 for no line + */ + public static int getPartialTopIndex(ITextViewer viewer) { + StyledText widget= viewer.getTextWidget(); + int widgetTop= getPartialTopIndex(widget); + return widgetLine2ModelLine(viewer, widgetTop); + } + + /** + * Returns the last, possibly partially, visible line in the view port. + * + * @param viewer the text viewer + * @return the last, possibly partially, visible line in the view port + */ + public static int getPartialBottomIndex(ITextViewer viewer) { + StyledText textWidget= viewer.getTextWidget(); + int widgetBottom= getPartialBottomIndex(textWidget); + return widgetLine2ModelLine(viewer, widgetBottom); + } + + /** + * Returns the range of lines that is visible in the viewer, including any partially visible + * lines. + * + * @param viewer the viewer + * @return the range of lines that is visible in the viewer, null if no lines are + * visible + */ + public static ILineRange getVisibleModelLines(ITextViewer viewer) { + int top= getPartialTopIndex(viewer); + int bottom= getPartialBottomIndex(viewer); + if (top is -1 || bottom is -1) + return null; + return new LineRange(top, bottom - top + 1); + } + + /** + * Converts a widget line into a model (i.e. {@link IDocument}) line using the + * {@link ITextViewerExtension5} if available, otherwise by adapting the widget line to the + * viewer's {@link ITextViewer#getVisibleRegion() visible region}. + * + * @param viewer the viewer + * @param widgetLine the widget line to convert. + * @return the model line corresponding to widgetLine or -1 to signal that there + * is no corresponding model line + */ + public static int widgetLine2ModelLine(ITextViewer viewer, int widgetLine) { + int modelLine; + if ( cast(ITextViewerExtension5)viewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) viewer; + modelLine= extension.widgetLine2ModelLine(widgetLine); + } else { + try { + IRegion r= viewer.getVisibleRegion(); + IDocument d= viewer.getDocument(); + modelLine= widgetLine + d.getLineOfOffset(r.getOffset()); + } catch (BadLocationException x) { + modelLine= widgetLine; + } + } + return modelLine; + } + + /** + * Converts a model (i.e. {@link IDocument}) line into a widget line using the + * {@link ITextViewerExtension5} if available, otherwise by adapting the model line to the + * viewer's {@link ITextViewer#getVisibleRegion() visible region}. + * + * @param viewer the viewer + * @param modelLine the model line to convert. + * @return the widget line corresponding to modelLine or -1 to signal that there + * is no corresponding widget line + */ + public static int modelLineToWidgetLine(ITextViewer viewer, int modelLine) { + int widgetLine; + if ( cast(ITextViewerExtension5)viewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) viewer; + widgetLine= extension.modelLine2WidgetLine(modelLine); + } else { + IRegion region= viewer.getVisibleRegion(); + IDocument document= viewer.getDocument(); + try { + int visibleStartLine= document.getLineOfOffset(region.getOffset()); + int visibleEndLine= document.getLineOfOffset(region.getOffset() + region.getLength()); + if (modelLine < visibleStartLine || modelLine > visibleEndLine) + widgetLine= -1; + else + widgetLine= modelLine - visibleStartLine; + } catch (BadLocationException x) { + // ignore and return -1 + widgetLine= -1; + } + } + return widgetLine; + } + + + /** + * Returns the number of hidden pixels of the first partially visible line. If there is no + * partially visible line, zero is returned. + * + * @param textWidget the widget + * @return the number of hidden pixels of the first partial line, always >= 0 + */ + public static int getHiddenTopLinePixels(StyledText textWidget) { + int top= getPartialTopIndex(textWidget); + return -textWidget.getLinePixel(top); + } + + /* + * @see StyledText#getLinePixel(int) + */ + public static int getLinePixel(StyledText textWidget, int line) { + return textWidget.getLinePixel(line); + } + + /* + * @see StyledText#getLineIndex(int) + */ + public static int getLineIndex(StyledText textWidget, int y) { + int lineIndex= textWidget.getLineIndex(y); + return lineIndex; + } + + /** + * Returns true if the widget displays the entire contents, i.e. it cannot + * be vertically scrolled. + * + * @param widget the widget + * @return true if the widget displays the entire contents, i.e. it cannot + * be vertically scrolled, false otherwise + */ + public static bool isShowingEntireContents(StyledText widget) { + if (widget.getTopPixel() !is 0) // more efficient shortcut + return false; + + int lastVisiblePixel= computeLastVisiblePixel(widget); + int lastPossiblePixel= widget.getLinePixel(widget.getLineCount()); + return lastPossiblePixel <= lastVisiblePixel; + } + + /** + * Determines the graphical area covered by the given text region in + * the given viewer. + * + * @param region the region whose graphical extend must be computed + * @param textViewer the text viewer containing the region + * @return the graphical extend of the given region in the given viewer + * + * @since 3.4 + */ + public static Rectangle computeArea(IRegion region, ITextViewer textViewer) { + int start= 0; + int end= 0; + IRegion widgetRegion= modelRange2WidgetRange(region, textViewer); + if (widgetRegion !is null) { + start= widgetRegion.getOffset(); + end= start + widgetRegion.getLength(); + } + + StyledText styledText= textViewer.getTextWidget(); + Rectangle bounds; + if (end > 0 && start < end) + bounds= styledText.getTextBounds(start, end - 1); + else { + Point loc= styledText.getLocationAtOffset(start); + bounds= new Rectangle(loc.x, loc.y, getAverageCharWidth(textViewer.getTextWidget()), styledText.getLineHeight(start)); + } + + return new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height); + } + + /** + * Translates a given region of the text viewer's document into + * the corresponding region of the viewer's widget. + * + * @param region the document region + * @param textViewer the viewer containing the region + * @return the corresponding widget region + * + * @since 3.4 + */ + private static IRegion modelRange2WidgetRange(IRegion region, ITextViewer textViewer) { + if ( cast(ITextViewerExtension5)textViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) textViewer; + return extension.modelRange2WidgetRange(region); + } + + IRegion visibleRegion= textViewer.getVisibleRegion(); + int start= region.getOffset() - visibleRegion.getOffset(); + int end= start + region.getLength(); + if (end > visibleRegion.getLength()) + end= visibleRegion.getLength(); + + return new Region(start, end - start); + } + + /** + * Returns the average character width of the given control's font. + * + * @param control the control to calculate the average char width for + * @return the average character width of the controls font + * + * @since 3.4 + */ + public static int getAverageCharWidth(Control control) { + GC gc= new GC(control); + gc.setFont(control.getFont()); + int increment= gc.getFontMetrics().getAverageCharWidth(); + gc.dispose(); + return increment; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/Line.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/Line.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,214 @@ +/******************************************************************************* + * 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 + * 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.text.Line; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Describes a line as a particular number of characters beginning at + * a particular offset, consisting of a particular number of characters, + * and being closed with a particular line delimiter. + */ +final class Line : IRegion { + + /** The offset of the line */ + public int offset; + /** The length of the line */ + public int length; + /** The delimiter of this line */ + public const String delimiter; + + /** + * Creates a new Line. + * + * @param offset the offset of the line + * @param end the last including character offset of the line + * @param delimiter the line's delimiter + */ + public this(int offset, int end, String delimiter) { + this.offset= offset; + this.length= (end - offset) +1; + this.delimiter= delimiter; + } + + /** + * Creates a new Line. + * + * @param offset the offset of the line + * @param length the length of the line + */ + public this(int offset, int length) { + this.offset= offset; + this.length= length; + this.delimiter= null; + } + + /* + * @see dwtx.jface.text.IRegion#getOffset() + */ + public int getOffset() { + return offset; + } + + /* + * @see dwtx.jface.text.IRegion#getLength() + */ + public int getLength() { + return length; + } +} + + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/ListLineTracker.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/ListLineTracker.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,505 @@ +/******************************************************************************* + * 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 + * 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.text.ListLineTracker; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; + +import dwtx.jface.text.AbstractLineTracker; + +/** + * Abstract, read-only implementation of ILineTracker. It lets the definition of + * line delimiters to subclasses. Assuming that '\n' is the only line delimiter, this abstract + * implementation defines the following line scheme: + *
                  + *
                • "" -> [0,0] + *
                • "a" -> [0,1] + *
                • "\n" -> [0,1], [1,0] + *
                • "a\n" -> [0,2], [2,0] + *
                • "a\nb" -> [0,2], [2,1] + *
                • "a\nbc\n" -> [0,2], [2,3], [5,0] + *
                + * This class must be subclassed. + * + * @since 3.2 + */ +abstract class ListLineTracker : ILineTracker { + + /** The line information */ + private const List fLines; + /** The length of the tracked text */ + private int fTextLength; + + /** + * Creates a new line tracker. + */ + protected this() { + fLines= new ArrayList(); + } + + /** + * Binary search for the line at a given offset. + * + * @param offset the offset whose line should be found + * @return the line of the offset + */ + private int findLine(int offset) { + + if (fLines.size() is 0) + return -1; + + int left= 0; + int right= fLines.size() - 1; + int mid= 0; + Line line= null; + + while (left < right) { + + mid= (left + right) / 2; + + line= cast(Line) fLines.get(mid); + if (offset < line.offset) { + if (left is mid) + right= left; + else + right= mid - 1; + } else if (offset > line.offset) { + if (right is mid) + left= right; + else + left= mid + 1; + } else if (offset is line.offset) { + left= right= mid; + } + } + + line= cast(Line) fLines.get(left); + if (line.offset > offset) + --left; + return left; + } + + /** + * Returns the number of lines covered by the specified text range. + * + * @param startLine the line where the text range starts + * @param offset the start offset of the text range + * @param length the length of the text range + * @return the number of lines covered by this text range + * @exception BadLocationException if range is undefined in this tracker + */ + private int getNumberOfLines(int startLine, int offset, int length) { + + if (length is 0) + return 1; + + int target= offset + length; + + Line l= cast(Line) fLines.get(startLine); + + if (l.delimiter is null) + return 1; + + if (l.offset + l.length > target) + return 1; + + if (l.offset + l.length is target) + return 2; + + return getLineNumberOfOffset(target) - startLine + 1; + } + + /* + * @see dwtx.jface.text.ILineTracker#getLineLength(int) + */ + public final int getLineLength(int line) { + int lines= fLines.size(); + + if (line < 0 || line > lines) + throw new BadLocationException(); + + if (lines is 0 || lines is line) + return 0; + + Line l= cast(Line) fLines.get(line); + return l.length; + } + + /* + * @see dwtx.jface.text.ILineTracker#getLineNumberOfOffset(int) + */ + public final int getLineNumberOfOffset(int position) { + if (position < 0 || position > fTextLength) + throw new BadLocationException(); + + if (position is fTextLength) { + + int lastLine= fLines.size() - 1; + if (lastLine < 0) + return 0; + + Line l= cast(Line) fLines.get(lastLine); + return (l.delimiter !is null ? lastLine + 1 : lastLine); + } + + return findLine(position); + } + + /* + * @see dwtx.jface.text.ILineTracker#getLineInformationOfOffset(int) + */ + public final IRegion getLineInformationOfOffset(int position) { + if (position > fTextLength) + throw new BadLocationException(); + + if (position is fTextLength) { + int size= fLines.size(); + if (size is 0) + return new Region(0, 0); + Line l= cast(Line) fLines.get(size - 1); + return (l.delimiter !is null ? new Line(fTextLength, 0) : new Line(fTextLength - l.length, l.length)); + } + + return getLineInformation(findLine(position)); + } + + /* + * @see dwtx.jface.text.ILineTracker#getLineInformation(int) + */ + public final IRegion getLineInformation(int line) { + int lines= fLines.size(); + + if (line < 0 || line > lines) + throw new BadLocationException(); + + if (lines is 0) + return new Line(0, 0); + + if (line is lines) { + Line l= cast(Line) fLines.get(line - 1); + return new Line(l.offset + l.length, 0); + } + + Line l= cast(Line) fLines.get(line); + return (l.delimiter !is null ? new Line(l.offset, l.length - l.delimiter.length()) : l); + } + + /* + * @see dwtx.jface.text.ILineTracker#getLineOffset(int) + */ + public final int getLineOffset(int line) { + int lines= fLines.size(); + + if (line < 0 || line > lines) + throw new BadLocationException(); + + if (lines is 0) + return 0; + + if (line is lines) { + Line l= cast(Line) fLines.get(line - 1); + if (l.delimiter !is null) + return l.offset + l.length; + throw new BadLocationException(); + } + + Line l= cast(Line) fLines.get(line); + return l.offset; + } + + /* + * @see dwtx.jface.text.ILineTracker#getNumberOfLines() + */ + public final int getNumberOfLines() { + int lines= fLines.size(); + + if (lines is 0) + return 1; + + Line l= cast(Line) fLines.get(lines - 1); + return (l.delimiter !is null ? lines + 1 : lines); + } + + /* + * @see dwtx.jface.text.ILineTracker#getNumberOfLines(int, int) + */ + public final int getNumberOfLines(int position, int length) { + + if (position < 0 || position + length > fTextLength) + throw new BadLocationException(); + + if (length is 0) // optimization + return 1; + + return getNumberOfLines(getLineNumberOfOffset(position), position, length); + } + + /* + * @see dwtx.jface.text.ILineTracker#computeNumberOfLines(java.lang.String) + */ + public final int computeNumberOfLines(String text) { + int count= 0; + int start= 0; + AbstractLineTracker_DelimiterInfo delimiterInfo= nextDelimiterInfo(text, start); + while (delimiterInfo !is null && delimiterInfo.delimiterIndex > -1) { + ++count; + start= delimiterInfo.delimiterIndex + delimiterInfo.delimiterLength; + delimiterInfo= nextDelimiterInfo(text, start); + } + return count; + } + + /* + * @see dwtx.jface.text.ILineTracker#getLineDelimiter(int) + */ + public final String getLineDelimiter(int line) { + int lines= fLines.size(); + + if (line < 0 || line > lines) + throw new BadLocationException(); + + if (lines is 0) + return null; + + if (line is lines) + return null; + + Line l= cast(Line) fLines.get(line); + return l.delimiter; + } + + /** + * Returns the information about the first delimiter found in the given text starting at the + * given offset. + * + * @param text the text to be searched + * @param offset the offset in the given text + * @return the information of the first found delimiter or null + */ + protected abstract AbstractLineTracker_DelimiterInfo nextDelimiterInfo(String text, int offset); + + /** + * Creates the line structure for the given text. Newly created lines are inserted into the line + * structure starting at the given position. Returns the number of newly created lines. + * + * @param text the text for which to create a line structure + * @param insertPosition the position at which the newly created lines are inserted into the + * tracker's line structure + * @param offset the offset of all newly created lines + * @return the number of newly created lines + */ + private int createLines(String text, int insertPosition, int offset) { + + int count= 0; + int start= 0; + AbstractLineTracker_DelimiterInfo delimiterInfo= nextDelimiterInfo(text, 0); + + while (delimiterInfo !is null && delimiterInfo.delimiterIndex > -1) { + + int index= delimiterInfo.delimiterIndex + (delimiterInfo.delimiterLength - 1); + + if (insertPosition + count >= fLines.size()) + fLines.add(new Line(offset + start, offset + index, delimiterInfo.delimiter)); + else + fLines.add(insertPosition + count, new Line(offset + start, offset + index, delimiterInfo.delimiter)); + + ++count; + start= index + 1; + delimiterInfo= nextDelimiterInfo(text, start); + } + + if (start < text.length()) { + if (insertPosition + count < fLines.size()) { + // there is a line below the current + Line l= cast(Line) fLines.get(insertPosition + count); + int delta= text.length() - start; + l.offset-= delta; + l.length+= delta; + } else { + fLines.add(new Line(offset + start, offset + text.length() - 1, null)); + ++count; + } + } + + return count; + } + + /* + * @see dwtx.jface.text.ILineTracker#replace(int, int, java.lang.String) + */ + public final void replace(int position, int length, String text) { + throw new UnsupportedOperationException(); + } + + /* + * @see dwtx.jface.text.ILineTracker#set(java.lang.String) + */ + public final void set(String text) { + fLines.clear(); + if (text !is null) { + fTextLength= text.length(); + createLines(text, 0, 0); + } + } + + /** + * Returns the internal data structure, a {@link List} of {@link Line}s. Used only by + * {@link TreeLineTracker#TreeLineTracker(ListLineTracker)}. + * + * @return the internal list of lines. + */ + final List getLines() { + return fLines; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/MarginPainter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/MarginPainter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,322 @@ +/******************************************************************************* + * 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 + * 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.text.MarginPainter; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +import dwt.DWT; +import dwt.custom.StyledText; +import dwt.events.PaintEvent; +import dwt.events.PaintListener; +import dwt.graphics.Color; +import dwt.graphics.GC; +import dwt.graphics.Rectangle; + + +/** + * Paints a vertical line (margin line) after a given column respecting the text + * viewer's font. + *

                + * Clients usually instantiate and configure objects of this class.

                + *

                + * This class is not intended to be subclassed.

                + * + * @since 2.1 + * @noextend This class is not intended to be subclassed by clients. + */ +public class MarginPainter : IPainter, PaintListener { + + /** The widget of the text viewer */ + private StyledText fTextWidget; + + /** The column after which to paint the line, default value 80 */ + private int fMarginWidth= 80; + /** The color in which to paint the line */ + private Color fColor; + /** The line style of the line to be painted, default value DWT.LINE_SOLID */ + private int fLineStyle= DWT.LINE_SOLID; + /** The line width of the line to be painted, default value 1 */ + private int fLineWidth= 0; // NOTE: 0 means width is 1 but with optimized performance + /** The cached x-offset of the fMarginWidth for the current font */ + private int fCachedWidgetX= -1; + /** The active state of this painter */ + private bool fIsActive= false; + + /** + * Creates a new painter for the given text viewer. + * + * @param textViewer the text viewer + */ + public this(ITextViewer textViewer) { + fTextWidget= textViewer.getTextWidget(); + } + + /** + * Sets the column after which to draw the margin line. + * + * @param width the column + */ + public void setMarginRulerColumn(int width) { + fMarginWidth= width; + initialize(); + } + + /** + * Sets the line style of the margin line. + * + * @param lineStyle a DWT style constant describing the line style + */ + public void setMarginRulerStyle(int lineStyle) { + fLineStyle= lineStyle; + } + + /** + * Sets the line width of the margin line. + * + * @param lineWidth the line width + */ + public void setMarginRulerWidth(int lineWidth) { + if (lineWidth is 1) + lineWidth= 0; // NOTE: 0 means width is 1 but with optimized performance + fLineWidth= lineWidth; + } + + /** + * Sets the color of the margin line. Must be called before paint is called the first time. + * + * @param color the color + */ + public void setMarginRulerColor(Color color) { + fColor= color; + } + + /** + * Initializes this painter, by flushing and recomputing all caches and causing + * the widget to be redrawn. Must be called explicitly when font of text widget changes. + */ + public void initialize() { + computeWidgetX(); + fTextWidget.redraw(); + } + + /** + * Computes and remembers the x-offset of the margin column for the + * current widget font. + */ + private void computeWidgetX() { + GC gc= new GC(fTextWidget); + int pixels= gc.getFontMetrics().getAverageCharWidth(); + gc.dispose(); + + fCachedWidgetX= pixels * fMarginWidth; + } + + /* + * @see IPainter#deactivate(bool) + */ + public void deactivate(bool redraw) { + if (fIsActive) { + fIsActive= false; + fCachedWidgetX= -1; + fTextWidget.removePaintListener(this); + if (redraw) + fTextWidget.redraw(); + } + } + + /* + * @see IPainter#dispose() + */ + public void dispose() { + fTextWidget= null; + } + + /* + * @see IPainter#paint(int) + */ + public void paint(int reason) { + if (!fIsActive) { + fIsActive= true; + fTextWidget.addPaintListener(this); + if (fCachedWidgetX is -1) + computeWidgetX(); + fTextWidget.redraw(); + } else if (CONFIGURATION is reason || INTERNAL is reason) + fTextWidget.redraw(); + } + + /* + * @see dwt.events.PaintListener#paintControl(dwt.events.PaintEvent) + */ + public void paintControl(PaintEvent e) { + if (fTextWidget !is null) { + int x= fCachedWidgetX - fTextWidget.getHorizontalPixel(); + if (x >= 0) { + Rectangle area= fTextWidget.getClientArea(); + e.gc.setForeground(fColor); + e.gc.setLineStyle(fLineStyle); + e.gc.setLineWidth(fLineWidth); + e.gc.drawLine(x, 0, x, area.height); + } + } + } + + /* + * @see dwtx.jface.text.IPainter#setPositionManager(dwtx.jface.text.IPaintPositionManager) + */ + public void setPositionManager(IPaintPositionManager manager) { + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/MarkSelection.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/MarkSelection.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,216 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.MarkSelection; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + + +/** + * Default implementation of {@link dwtx.jface.text.IMarkSelection}. + * + * @since 2.0 + */ +public class MarkSelection : IMarkSelection { + + /** The marked document. */ + private const IDocument fDocument; + /** The offset of the mark selection. */ + private const int fOffset; + /** The length of the mark selection. */ + private const int fLength; + + /** + * Creates a MarkSelection. + * + * @param document the marked document + * @param offset the offset of the mark + * @param length the length of the mark, may be negative if caret before offset + */ + public this(IDocument document, int offset, int length) { + fDocument= document; + fOffset= offset; + fLength= length; + } + + /* + * @see IMarkSelection#getDocument() + */ + public IDocument getDocument() { + return fDocument; + } + + /* + * @see IMarkSelection#getOffset() + */ + public int getOffset() { + return fOffset; + } + + /* + * @see IMarkSelection#getLength() + */ + public int getLength() { + return fLength; + } + + /* + * @see ISelection#isEmpty() + */ + public bool isEmpty() { + return fLength is 0; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/PaintManager.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/PaintManager.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,528 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.PaintManager; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.dwtxhelper.Collection; + + + +import dwt.custom.StyledText; +import dwt.events.KeyEvent; +import dwt.events.KeyListener; +import dwt.events.MouseEvent; +import dwt.events.MouseListener; +import dwt.widgets.Control; +import dwtx.jface.viewers.ISelectionChangedListener; +import dwtx.jface.viewers.ISelectionProvider; +import dwtx.jface.viewers.SelectionChangedEvent; + + +/** + * Manages the {@link dwtx.jface.text.IPainter} object registered with an + * {@link dwtx.jface.text.ITextViewer}. + *

                + * Clients usually instantiate and configure objects of this type.

                + * + * @since 2.1 + */ +public final class PaintManager : KeyListener, MouseListener, ISelectionChangedListener, ITextListener, ITextInputListener { + + /** + * Position updater used by the position manager. This position updater differs from the default position + * updater in that it extends a position when an insertion happens at the position's offset and right behind + * the position. + */ + static class PaintPositionUpdater : DefaultPositionUpdater { + + /** + * Creates the position updater for the given category. + * + * @param category the position category + */ + protected this(String category) { + super(category); + } + + /** + * If an insertion happens at a position's offset, the + * position is extended rather than shifted. Also, if something is added + * right behind the end of the position, the position is extended rather + * than kept stable. + */ + protected void adaptToInsert() { + + int myStart= fPosition.offset; + int myEnd= fPosition.offset + fPosition.length; + myEnd= Math.max(myStart, myEnd); + + int yoursStart= fOffset; + int yoursEnd= fOffset + fReplaceLength;// - 1; + yoursEnd= Math.max(yoursStart, yoursEnd); + + if (myEnd < yoursStart) + return; + + if (myStart <= yoursStart) + fPosition.length += fReplaceLength; + else + fPosition.offset += fReplaceLength; + } + } + + /** + * The paint position manager used by this paint manager. The paint position + * manager is installed on a single document and control the creation/disposed + * and updating of a position category that will be used for managing positions. + */ + static class PositionManager : IPaintPositionManager { + +// /** The document this position manager works on */ + private IDocument fDocument; + /** The position updater used for the managing position category */ + private IPositionUpdater fPositionUpdater; + /** The managing position category */ + private String fCategory; + + /** + * Creates a new position manager. Initializes the managing + * position category using its class name and its hash value. + */ + public this() { + fCategory= this.classinfo.name ~ Integer.toString(toHash()); + fPositionUpdater= new PaintPositionUpdater(fCategory); + } + + /** + * Installs this position manager in the given document. The position manager stays + * active until uninstall or dispose + * is called. + * + * @param document the document to be installed on + */ + public void install(IDocument document) { + fDocument= document; + fDocument.addPositionCategory(fCategory); + fDocument.addPositionUpdater(fPositionUpdater); + } + + /** + * Disposes this position manager. The position manager is automatically + * removed from the document it has previously been installed + * on. + */ + public void dispose() { + uninstall(fDocument); + } + + /** + * Uninstalls this position manager form the given document. If the position + * manager has no been installed on this document, this method is without effect. + * + * @param document the document form which to uninstall + */ + public void uninstall(IDocument document) { + if (document is fDocument && document !is null) { + try { + fDocument.removePositionUpdater(fPositionUpdater); + fDocument.removePositionCategory(fCategory); + } catch (BadPositionCategoryException x) { + // should not happen + } + fDocument= null; + } + } + + /* + * @see IPositionManager#addManagedPosition(Position) + */ + public void managePosition(Position position) { + try { + fDocument.addPosition(fCategory, position); + } catch (BadPositionCategoryException x) { + // should not happen + } catch (BadLocationException x) { + // should not happen + } + } + + /* + * @see IPositionManager#removeManagedPosition(Position) + */ + public void unmanagePosition(Position position) { + try { + fDocument.removePosition(fCategory, position); + } catch (BadPositionCategoryException x) { + // should not happen + } + } + } + + + /** The painters managed by this paint manager. */ + private List fPainters; + /** The position manager used by this paint manager */ + private PositionManager fManager; + /** The associated text viewer */ + private ITextViewer fTextViewer; + + /** + * Creates a new paint manager for the given text viewer. + * + * @param textViewer the text viewer associated to this newly created paint manager + */ + public this(ITextViewer textViewer) { + fPainters= new ArrayList(2); + fTextViewer= textViewer; + } + + + /** + * Adds the given painter to the list of painters managed by this paint manager. + * If the painter is already registered with this paint manager, this method is + * without effect. + * + * @param painter the painter to be added + */ + public void addPainter(IPainter painter) { + if (!fPainters.contains(cast(Object)painter)) { + fPainters.add(cast(Object)painter); + if (fPainters.size() is 1) + install(); + painter.setPositionManager(fManager); + painter.paint(IPainter.INTERNAL); + } + } + + /** + * Removes the given painter from the list of painters managed by this + * paint manager. If the painter has not previously been added to this + * paint manager, this method is without effect. + * + * @param painter the painter to be removed + */ + public void removePainter(IPainter painter) { + if (fPainters.remove(cast(Object)painter)) { + painter.deactivate(true); + painter.setPositionManager(null); + } + if (fPainters.size() is 0) + dispose(); + } + + /** + * Installs/activates this paint manager. Is called as soon as the + * first painter is to be managed by this paint manager. + */ + private void install() { + + fManager= new PositionManager(); + if (fTextViewer.getDocument() !is null) + fManager.install(fTextViewer.getDocument()); + + fTextViewer.addTextInputListener(this); + + addListeners(); + } + + /** + * Installs our listener set on the text viewer and the text widget, + * respectively. + */ + private void addListeners() { + ISelectionProvider provider= fTextViewer.getSelectionProvider(); + provider.addSelectionChangedListener(this); + + fTextViewer.addTextListener(this); + + StyledText text= fTextViewer.getTextWidget(); + text.addKeyListener(this); + text.addMouseListener(this); + } + + /** + * Disposes this paint manager. The paint manager uninstalls itself + * and clears all registered painters. This method is also called when the + * last painter is removed from the list of managed painters. + */ + public void dispose() { + + if (fManager !is null) { + fManager.dispose(); + fManager= null; + } + + for (Iterator e = fPainters.iterator(); e.hasNext();) + (cast(IPainter) e.next()).dispose(); + fPainters.clear(); + + fTextViewer.removeTextInputListener(this); + + removeListeners(); + } + + /** + * Removes our set of listeners from the text viewer and widget, + * respectively. + */ + private void removeListeners() { + ISelectionProvider provider= fTextViewer.getSelectionProvider(); + if (provider !is null) + provider.removeSelectionChangedListener(this); + + fTextViewer.removeTextListener(this); + + StyledText text= fTextViewer.getTextWidget(); + if (text !is null && !text.isDisposed()) { + text.removeKeyListener(this); + text.removeMouseListener(this); + } + } + + /** + * Triggers all registered painters for the given reason. + * + * @param reason the reason + * @see IPainter + */ + private void paint(int reason) { + for (Iterator e = fPainters.iterator(); e.hasNext();) + (cast(IPainter) e.next()).paint(reason); + } + + /* + * @see KeyListener#keyPressed(KeyEvent) + */ + public void keyPressed(KeyEvent e) { + paint(IPainter.KEY_STROKE); + } + + /* + * @see KeyListener#keyReleased(KeyEvent) + */ + public void keyReleased(KeyEvent e) { + } + + /* + * @see MouseListener#mouseDoubleClick(MouseEvent) + */ + public void mouseDoubleClick(MouseEvent e) { + } + + /* + * @see MouseListener#mouseDown(MouseEvent) + */ + public void mouseDown(MouseEvent e) { + paint(IPainter.MOUSE_BUTTON); + } + + /* + * @see MouseListener#mouseUp(MouseEvent) + */ + public void mouseUp(MouseEvent e) { + } + + /* + * @see ISelectionChangedListener#selectionChanged(SelectionChangedEvent) + */ + public void selectionChanged(SelectionChangedEvent event) { + paint(IPainter.SELECTION); + } + + /* + * @see ITextListener#textChanged(TextEvent) + */ + public void textChanged(TextEvent event) { + + if (!event.getViewerRedrawState()) + return; + + Control control= fTextViewer.getTextWidget(); + if (control !is null) { + control.getDisplay().asyncExec(new class() Runnable { + public void run() { + if (fTextViewer !is null) + paint(IPainter.TEXT_CHANGE); + } + }); + } + } + + /* + * @see ITextInputListener#inputDocumentAboutToBeChanged(IDocument, IDocument) + */ + public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { + if (oldInput !is null) { + for (Iterator e = fPainters.iterator(); e.hasNext();) + (cast(IPainter) e.next()).deactivate(false); + fManager.uninstall(oldInput); + removeListeners(); + } + } + + /* + * @see ITextInputListener#inputDocumentChanged(IDocument, IDocument) + */ + public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { + if (newInput !is null) { + fManager.install(newInput); + paint(IPainter.TEXT_CHANGE); + addListeners(); + } + } +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/Position.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/Position.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,342 @@ +/******************************************************************************* + * 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.text.Position; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.core.runtime.Assert; + + +/** + * Positions describe text ranges of a document. Positions are adapted to + * changes applied to that document. The text range is specified by an offset + * and a length. Positions can be marked as deleted. Deleted positions are + * considered to no longer represent a valid text range in the managing + * document. + *

                + * Positions attached to documents are usually updated by position updaters. + * Because position updaters are freely definable and because of the frequency + * in which they are used, the fields of a position are made publicly + * accessible. Clients other than position updaters are not allowed to access + * these public fields. + *

                + *

                + * Positions cannot be used as keys in hash tables as they override + * equals and hashCode as they would be value + * objects. + *

                + * + * @see dwtx.jface.text.IDocument + */ +public class Position { + + /** The offset of the position */ + public int offset; + /** The length of the position */ + public int length; + /** Indicates whether the position has been deleted */ + public bool isDeleted_; + + /** + * Creates a new position with the given offset and length 0. + * + * @param offset the position offset, must be >= 0 + */ + public this(int offset) { + this(offset, 0); + } + + /** + * Creates a new position with the given offset and length. + * + * @param offset the position offset, must be >= 0 + * @param length the position length, must be >= 0 + */ + public this(int offset, int length) { + Assert.isTrue(offset >= 0); + Assert.isTrue(length >= 0); + this.offset= offset; + this.length= length; + } + + /** + * Creates a new, not initialized position. + */ + protected this() { + } + + /* + * @see java.lang.Object#hashCode() + */ + public override hash_t toHash() { + int deleted= isDeleted_ ? 0 : 1; + return (offset << 24) | (length << 16) | deleted; + } + + /** + * Marks this position as deleted. + */ + public void delete_() { + isDeleted_= true; + } + + /** + * Marks this position as not deleted. + * + * @since 2.0 + */ + public void undelete() { + isDeleted_= false; + } + + /* + * @see java.lang.Object#equals(java.lang.Object) + */ + public override int opEquals(Object other) { + if ( auto rp = cast(Position)other ) { + return (rp.offset is offset) && (rp.length is length); + } + return super.opEquals(other); + } + + /** + * Returns the length of this position. + * + * @return the length of this position + */ + public int getLength() { + return length; + } + + /** + * Returns the offset of this position. + * + * @return the offset of this position + */ + public int getOffset() { + return offset; + } + + /** + * Checks whether the given index is inside + * of this position's text range. + * + * @param index the index to check + * @return true if index is inside of this position + */ + public bool includes(int index) { + + if (isDeleted_) + return false; + + return (this.offset <= index) && (index < this.offset + length); + } + + /** + * Checks whether the intersection of the given text range + * and the text range represented by this position is empty + * or not. + * + * @param rangeOffset the offset of the range to check + * @param rangeLength the length of the range to check + * @return true if intersection is not empty + */ + public bool overlapsWith(int rangeOffset, int rangeLength) { + + if (isDeleted_) + return false; + + int end= rangeOffset + rangeLength; + int thisEnd= this.offset + this.length; + + if (rangeLength > 0) { + if (this.length > 0) + return this.offset < end && rangeOffset < thisEnd; + return rangeOffset <= this.offset && this.offset < end; + } + + if (this.length > 0) + return this.offset <= rangeOffset && rangeOffset < thisEnd; + return this.offset is rangeOffset; + } + + /** + * Returns whether this position has been deleted or not. + * + * @return true if position has been deleted + */ + public bool isDeleted() { + return isDeleted_; + } + + /** + * Changes the length of this position to the given length. + * + * @param length the new length of this position + */ + public void setLength(int length) { + Assert.isTrue(length >= 0); + this.length= length; + } + + /** + * Changes the offset of this position to the given offset. + * + * @param offset the new offset of this position + */ + public void setOffset(int offset) { + Assert.isTrue(offset >= 0); + this.offset= offset; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/PropagatingFontFieldEditor.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/PropagatingFontFieldEditor.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,290 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.PropagatingFontFieldEditor; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + + + + +import dwt.graphics.FontData; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Label; +import dwtx.jface.preference.FontFieldEditor; +import dwtx.jface.preference.IPreferenceStore; +import dwtx.jface.preference.PreferenceConverter; +import dwtx.jface.util.IPropertyChangeListener; +import dwtx.jface.util.PropertyChangeEvent; + + +/** + * This font field editor implements chaining between a source preference + * store and a target preference store. Any time the source preference + * store changes, the change is propagated to the target store. Propagation + * means that the actual value stored in the source store is set as default + * value in the target store. If the target store does not contain a value + * other than the default value, the new default value is immediately + * effective. + * + * @see FontFieldEditor + * @since 2.0 + * @deprecated since 3.0 not longer in use, no longer supported + */ +public class PropagatingFontFieldEditor : FontFieldEditor { + + /** The editor's parent widget */ + private Composite fParent; + /** The representation of the default font choice */ + private String fDefaultFontLabel; + + /** + * Creates a new font field editor with the given parameters. + * + * @param name the editor's name + * @param labelText the text shown as editor description + * @param parent the editor's parent widget + * @param defaultFontLabel the label shown in the editor value field when the default value should be taken + */ + public this(String name, String labelText, Composite parent, String defaultFontLabel) { + super(name, labelText, parent); + fParent= parent; + fDefaultFontLabel= defaultFontLabel is null ? "" : defaultFontLabel; //$NON-NLS-1$ + } + + /* + * @see FontFieldEditor#doLoad() + */ + protected void doLoad() { + if (getPreferenceStore().isDefault(getPreferenceName())) + loadDefault(); + super.doLoad(); + checkForDefault(); + } + + /* + * @see FontFieldEditor#doLoadDefault() + */ + protected void doLoadDefault() { + super.doLoadDefault(); + checkForDefault(); + } + + /** + * Checks whether this editor presents the default value "inherited" + * from the workbench rather than its own font. + */ + private void checkForDefault() { + if (presentsDefaultValue()) { + Control c= getValueControl(fParent); + if ( cast(Label)c ) + (cast(Label) c).setText(fDefaultFontLabel); + } + } + + /** + * Propagates the font set in the source store to the + * target store using the given keys. + * + * @param source the store from which to read the text font + * @param sourceKey the key under which the font can be found + * @param target the store to which to propagate the font + * @param targetKey the key under which to store the font + */ + private static void propagateFont(IPreferenceStore source, String sourceKey, IPreferenceStore target, String targetKey) { + FontData fd= PreferenceConverter.getFontData(source, sourceKey); + if (fd !is null) { + bool isDefault= target.isDefault(targetKey); // save old state! + PreferenceConverter.setDefault(target, targetKey, fd); + if (isDefault) { + // restore old state + target.setToDefault(targetKey); + } + } + } + + /** + * Starts the propagation of the font preference stored in the source preference + * store under the source key to the target preference store using the target + * preference key. + * + * @param source the source preference store + * @param sourceKey the key to be used in the source preference store + * @param target the target preference store + * @param targetKey the key to be used in the target preference store + */ + public static void startPropagate(IPreferenceStore source, String sourceKey, IPreferenceStore target, String targetKey) { + source.addPropertyChangeListener(new class(source,sourceKey,target,targetKey) IPropertyChangeListener { + IPreferenceStore source_; + String sourceKey_; + IPreferenceStore target_; + String targetKey_; + this(IPreferenceStore a, String b, IPreferenceStore c, String d){ + source_=a; + sourceKey_=b; + target_=c; + targetKey_=d; + } + public void propertyChange(PropertyChangeEvent event) { + if (sourceKey_.equals(event.getProperty())) + propagateFont(source_, sourceKey_, target_, targetKey_); + } + }); + + propagateFont(source, sourceKey, target, targetKey); + } +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/RegExMessages.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/RegExMessages.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,191 @@ +/******************************************************************************* + * 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.text.RegExMessages; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +// import dwt.dwthelper.MissingResourceException; +import dwt.dwthelper.ResourceBundle; + + +/** + * RegEx messages. Helper class to get NLSed messages. + * + * @since 3.4 + */ +final class RegExMessages { + + //private static const String RESOURCE_BUNDLE= RegExMessages.classinfo.getName(); + private static ResourceBundle fgResourceBundle;//= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + static this() { + fgResourceBundle = ResourceBundle.getBundle( + getImportData!("dwtx.jface.text.RegExMessages.properties")); + } + + private this() { + // Do not instantiate + } + + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" ~ key ~ "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/Region.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/Region.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,220 @@ +/******************************************************************************* + * 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.text.Region; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; +import tango.text.convert.Format; + + +/** + * The default implementation of the {@link dwtx.jface.text.IRegion} interface. + */ +public class Region : IRegion { + + /** The region offset */ + private int fOffset; + /** The region length */ + private int fLength; + + /** + * Create a new region. + * + * @param offset the offset of the region + * @param length the length of the region + */ + public this(int offset, int length) { + fOffset= offset; + fLength= length; + } + + /* + * @see dwtx.jface.text.IRegion#getLength() + */ + public int getLength() { + return fLength; + } + + /* + * @see dwtx.jface.text.IRegion#getOffset() + */ + public int getOffset() { + return fOffset; + } + + /* + * @see java.lang.Object#equals(java.lang.Object) + */ + public bool equals(Object o) { + if ( cast(IRegion)o ) { + IRegion r= cast(IRegion) o; + return r.getOffset() is fOffset && r.getLength() is fLength; + } + return false; + } + + /* + * @see java.lang.Object#hashCode() + */ + public override hash_t toHash() { + return (fOffset << 24) | (fLength << 16); + } + + /* + * @see java.lang.Object#toString() + */ + public override String toString() { + return Format("[{}+{}]", fOffset, fLength ); //$NON-NLS-1$ + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/RewriteSessionEditProcessor.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/RewriteSessionEditProcessor.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,260 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.text.RewriteSessionEditProcessor; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.text.edits.CopyTargetEdit; +import dwtx.text.edits.DeleteEdit; +import dwtx.text.edits.InsertEdit; +import dwtx.text.edits.MalformedTreeException; +import dwtx.text.edits.MoveTargetEdit; +import dwtx.text.edits.ReplaceEdit; +import dwtx.text.edits.TextEdit; +import dwtx.text.edits.TextEditProcessor; +import dwtx.text.edits.TextEditVisitor; +import dwtx.text.edits.UndoEdit; + +/** + * A text edit processor that brackets the application of edits into a document rewrite session. + * + * @since 3.3 + */ +public final class RewriteSessionEditProcessor : TextEditProcessor { + /** The threshold for large text edits. */ + private static const int THRESHOLD= 1000; + + /** + * Text edit visitor that estimates the compound size of an edit tree in characters. + */ + private static final class SizeVisitor : TextEditVisitor { + int fSize= 0; + + public bool visit(CopyTargetEdit edit) { + fSize += edit.getLength(); + return super.visit(edit); + } + + public bool visit(DeleteEdit edit) { + fSize += edit.getLength(); + return super.visit(edit); + } + + public bool visit(InsertEdit edit) { + fSize += edit.getText().length(); + return super.visit(edit); + } + + public bool visit(MoveTargetEdit edit) { + fSize += edit.getLength(); + return super.visit(edit); + } + + public bool visit(ReplaceEdit edit) { + fSize += Math.max(edit.getLength(), edit.getText().length()); + return super.visit(edit); + } + } + + /** + * Constructs a new edit processor for the given document. + * + * @param document the document to manipulate + * @param root the root of the text edit tree describing the modifications. By passing a text + * edit a a text edit processor the ownership of the edit is transfered to the text edit + * processors. Clients must not modify the edit (e.g adding new children) any longer. + * @param style {@link TextEdit#NONE}, {@link TextEdit#CREATE_UNDO} or + * {@link TextEdit#UPDATE_REGIONS}) + */ + public this(IDocument document, TextEdit root, int style) { + super(document, root, style); + } + + /* + * @see dwtx.text.edits.TextEditProcessor#performEdits() + */ + public UndoEdit performEdits() { + IDocument document= getDocument(); + if (!( cast(IDocumentExtension4)document )) + return super.performEdits(); + + IDocumentExtension4 extension= cast(IDocumentExtension4) document; + bool isLargeEdit= isLargeEdit(getRoot()); + DocumentRewriteSessionType type= isLargeEdit ? DocumentRewriteSessionType.UNRESTRICTED : DocumentRewriteSessionType.UNRESTRICTED_SMALL; + + DocumentRewriteSession session= extension.startRewriteSession(type); + try { + return super.performEdits(); + } finally { + extension.stopRewriteSession(session); + } + } + + /** + * Returns true if the passed edit is considered large, + * false otherwise. + * + * @param edit the edit to check + * @return true if edit is considered large, + * false otherwise + * @since 3.3 + */ + public static bool isLargeEdit(TextEdit edit) { + SizeVisitor sizeVisitor= new SizeVisitor(); + edit.accept(sizeVisitor); + return sizeVisitor.fSize > THRESHOLD; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/SequentialRewriteTextStore.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/SequentialRewriteTextStore.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,417 @@ +/******************************************************************************* + * 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 + * 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.text.SequentialRewriteTextStore; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.dwtxhelper.Collection; + + + +/** + * A text store that optimizes a given source text store for sequential rewriting. + * While rewritten it keeps a list of replace command that serve as patches for + * the source store. Only on request, the source store is indeed manipulated + * by applying the patch commands to the source text store. + * + * @since 2.0 + * @deprecated since 3.3 as {@link GapTextStore} performs better even for sequential rewrite scenarios + */ +public class SequentialRewriteTextStore : ITextStore { + + /** + * A buffered replace command. + */ + private static class Replace { + public int newOffset; + public const int offset; + public const int length; + public const String text; + + public this(int offset, int newOffset, int length, String text) { + this.newOffset= newOffset; + this.offset= offset; + this.length= length; + this.text= text; + } + } + + /** The list of buffered replacements. */ + private LinkedList fReplaceList; + /** The source text store */ + private ITextStore fSource; + /** A flag to enforce sequential access. */ + private static const bool ASSERT_SEQUENTIALITY= false; + + + /** + * Creates a new sequential rewrite store for the given source store. + * + * @param source the source text store + */ + public this(ITextStore source) { + fReplaceList= new LinkedList(); + fSource= source; + } + + /** + * Returns the source store of this rewrite store. + * + * @return the source store of this rewrite store + */ + public ITextStore getSourceStore() { + commit(); + return fSource; + } + + /* + * @see dwtx.jface.text.ITextStore#replace(int, int, java.lang.String) + */ + public void replace(int offset, int length, String text) { + if (text is null) + text= ""; //$NON-NLS-1$ + + if (fReplaceList.size() is 0) { + fReplaceList.add(new Replace(offset, offset, length, text)); + + } else { + Replace firstReplace= cast(Replace) fReplaceList.getFirst(); + Replace lastReplace= cast(Replace) fReplaceList.getLast(); + + // backward + if (offset + length <= firstReplace.newOffset) { + int delta= text.length - length; + if (delta !is 0) { + for (Iterator i= fReplaceList.iterator(); i.hasNext(); ) { + Replace replace= cast(Replace) i.next(); + replace.newOffset += delta; + } + } + + fReplaceList.addFirst(new Replace(offset, offset, length, text)); + + // forward + } else if (offset >= lastReplace.newOffset + lastReplace.text.length) { + int delta= getDelta(lastReplace); + fReplaceList.add(new Replace(offset - delta, offset, length, text)); + + } else if (ASSERT_SEQUENTIALITY) { + throw new IllegalArgumentException(null); + + } else { + commit(); + fSource.replace(offset, length, text); + } + } + } + + /* + * @see dwtx.jface.text.ITextStore#set(java.lang.String) + */ + public void set(String text) { + fSource.set(text); + fReplaceList.clear(); + } + + /* + * @see dwtx.jface.text.ITextStore#get(int, int) + */ + public String get(int offset, int length) { + + if (fReplaceList.isEmpty()) + return fSource.get(offset, length); + + + Replace firstReplace= cast(Replace) fReplaceList.getFirst(); + Replace lastReplace= cast(Replace) fReplaceList.getLast(); + + // before + if (offset + length <= firstReplace.newOffset) { + return fSource.get(offset, length); + + // after + } else if (offset >= lastReplace.newOffset + lastReplace.text.length) { + int delta= getDelta(lastReplace); + return fSource.get(offset - delta, length); + + } else if (ASSERT_SEQUENTIALITY) { + throw new IllegalArgumentException(null); + + } else { + + int delta= 0; + for (Iterator i= fReplaceList.iterator(); i.hasNext(); ) { + Replace replace= cast(Replace) i.next(); + + if (offset + length < replace.newOffset) { + return fSource.get(offset - delta, length); + + } else if (offset >= replace.newOffset && offset + length <= replace.newOffset + replace.text.length) { + return replace.text.substring(offset - replace.newOffset, offset - replace.newOffset + length); + + } else if (offset >= replace.newOffset + replace.text.length) { + delta= getDelta(replace); + continue; + + } else { + commit(); + return fSource.get(offset, length); + } + } + + return fSource.get(offset - delta, length); + } + + } + + /** + * Returns the difference between the offset in the source store and the "same" offset in the + * rewrite store after the replace operation. + * + * @param replace the replace command + * @return the difference + */ + private static final int getDelta(Replace replace) { + return replace.newOffset - replace.offset + replace.text.length() - replace.length; + } + + /* + * @see dwtx.jface.text.ITextStore#get(int) + */ + public char get(int offset) { + if (fReplaceList.isEmpty()) + return fSource.get(offset); + + Replace firstReplace= cast(Replace) fReplaceList.getFirst(); + Replace lastReplace= cast(Replace) fReplaceList.getLast(); + + // before + if (offset < firstReplace.newOffset) { + return fSource.get(offset); + + // after + } else if (offset >= lastReplace.newOffset + lastReplace.text.length()) { + int delta= getDelta(lastReplace); + return fSource.get(offset - delta); + + } else if (ASSERT_SEQUENTIALITY) { + throw new IllegalArgumentException(null); + + } else { + + int delta= 0; + for (Iterator i= fReplaceList.iterator(); i.hasNext(); ) { + Replace replace= cast(Replace) i.next(); + + if (offset < replace.newOffset) + return fSource.get(offset - delta); + + else if (offset < replace.newOffset + replace.text.length()) + return replace.text.charAt(offset - replace.newOffset); + + delta= getDelta(replace); + } + + return fSource.get(offset - delta); + } + } + + /* + * @see dwtx.jface.text.ITextStore#getLength() + */ + public int getLength() { + if (fReplaceList.isEmpty()) + return fSource.getLength(); + + Replace lastReplace= cast(Replace) fReplaceList.getLast(); + return fSource.getLength() + getDelta(lastReplace); + } + + /** + * Disposes this rewrite store. + */ + public void dispose() { + fReplaceList= null; + fSource= null; + } + + /** + * Commits all buffered replace commands. + */ + private void commit() { + + if (fReplaceList.isEmpty()) + return; + + StringBuffer buffer= new StringBuffer(); + + int delta= 0; + for (Iterator i= fReplaceList.iterator(); i.hasNext(); ) { + Replace replace= cast(Replace) i.next(); + + int offset= buffer.length() - delta; + buffer.append(fSource.get(offset, replace.offset - offset)); + buffer.append(replace.text); + delta= getDelta(replace); + } + + int offset= buffer.length() - delta; + buffer.append(fSource.get(offset, fSource.getLength() - offset)); + + fSource.set(buffer.toString()); + fReplaceList.clear(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/SlaveDocumentEvent.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/SlaveDocumentEvent.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.SlaveDocumentEvent; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * A slave document event represents a master document event as a slave-relative + * document event. It also carries the master document event. + */ +public class SlaveDocumentEvent : DocumentEvent { + + /** The master document event */ + private DocumentEvent fMasterEvent; + + /** + * Creates a new slave document event. + * + * @param doc the slave document + * @param offset the offset in the slave document + * @param length the length in the slave document + * @param text the substitution text + * @param masterEvent the master document event + */ + public this(IDocument doc, int offset, int length, String text, DocumentEvent masterEvent) { + super(doc, offset, length, text); + fMasterEvent= masterEvent; + } + + /** + * Returns this event's master event. + * + * @return this event's master event + */ + public DocumentEvent getMasterEvent() { + return fMasterEvent; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/TabsToSpacesConverter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/TabsToSpacesConverter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,241 @@ +/******************************************************************************* + * 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.text.TabsToSpacesConverter; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Auto edit strategy that converts tabs into spaces. + *

                + * Clients usually instantiate and configure this class but + * can also extend it in their own subclass. + *

                + * + * @since 3.3 + */ +public class TabsToSpacesConverter : IAutoEditStrategy { + + private int fTabRatio; + private ILineTracker fLineTracker; + + + public void setNumberOfSpacesPerTab(int ratio) { + fTabRatio= ratio; + } + + public void setLineTracker(ILineTracker lineTracker) { + fLineTracker= lineTracker; + } + + private int insertTabString(StringBuffer buffer, int offsetInLine) { + + if (fTabRatio is 0) + return 0; + + int remainder= offsetInLine % fTabRatio; + remainder= fTabRatio - remainder; + for (int i= 0; i < remainder; i++) + buffer.append(' '); + return remainder; + } + + public void customizeDocumentCommand(IDocument document, DocumentCommand command) { + String text= command.text; + if (text is null) + return; + + int index= text.indexOf('\t'); + if (index > -1) { + + StringBuffer buffer= new StringBuffer(); + + fLineTracker.set(command.text); + int lines= fLineTracker.getNumberOfLines(); + + try { + + for (int i= 0; i < lines; i++) { + + int offset= fLineTracker.getLineOffset(i); + int endOffset= offset + fLineTracker.getLineLength(i); + String line= text.substring(offset, endOffset); + + int position= 0; + if (i is 0) { + IRegion firstLine= document.getLineInformationOfOffset(command.offset); + position= command.offset - firstLine.getOffset(); + } + + int length= line.length(); + for (int j= 0; j < length; j++) { + char c= line.charAt(j); + if (c is '\t') { + position += insertTabString(buffer, position); + } else { + buffer.append(c); + ++ position; + } + } + + } + + command.text= buffer.toString(); + + } catch (BadLocationException x) { + } + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/TextAttribute.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/TextAttribute.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,328 @@ +/******************************************************************************* + * 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 + * 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.text.TextAttribute; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +import dwt.DWT; +import dwt.graphics.Color; +import dwt.graphics.Font; + + +/** + * Description of textual attributes such as color and style. Text attributes + * are considered value objects. + *

                + * Clients usually instantiate object of the class.

                + */ +public class TextAttribute { + + /** + * Text attribute for strikethrough style. + * (value 1 << 29). + * @since 3.1 + */ + public static const int STRIKETHROUGH= 1 << 29; + + /** + * Text attribute for underline style. + * (value 1 << 30) + * @since 3.1 + */ + public static const int UNDERLINE= 1 << 30; + + + /** Foreground color */ + private Color foreground; + + /** Background color */ + private Color background; + + /** The text style */ + private int style; + + /** + * The text font. + * @since 3.3 + */ + private Font font; + + /** + * Cached hash code. + * @since 3.3 + */ + private int fHashCode; + + /** + * Creates a text attribute with the given colors and style. + * + * @param foreground the foreground color, null if none + * @param background the background color, null if none + * @param style the style + */ + public this(Color foreground, Color background, int style) { + this.foreground= foreground; + this.background= background; + this.style= style; + } + + /** + * Creates a text attribute with the given colors and style. + * + * @param foreground the foreground color, null if none + * @param background the background color, null if none + * @param style the style + * @param font the font, null if none + * @since 3.3 + */ + public this(Color foreground, Color background, int style, Font font) { + this.foreground= foreground; + this.background= background; + this.style= style; + this.font= font; + } + + /** + * Creates a text attribute for the given foreground color, no background color and + * with the DWT normal style. + * + * @param foreground the foreground color, null if none + */ + public this(Color foreground) { + this(foreground, null, DWT.NORMAL); + } + + /* + * @see Object#equals(Object) + */ + public bool equals(Object object) { + + if (object is this) + return true; + + if (!( cast(TextAttribute)object )) + return false; + TextAttribute a= cast(TextAttribute)object; + + return (a.style is style && equals(a.foreground, foreground) && equals(a.background, background) && equals(a.font, font)); + } + + /** + * Returns whether the two given objects are equal. + * + * @param o1 the first object, can be null + * @param o2 the second object, can be null + * @return true if the given objects are equals + * @since 2.0 + */ + private bool equals(Object o1, Object o2) { + if (o1 !is null) + return cast(bool) o1.opEquals(o2); + return (o2 is null); + } + + /* + * @see Object#hashCode() + */ + public override hash_t toHash() { + if (fHashCode is 0) { + int multiplier= 37; // some prime + fHashCode= 13; // some random value + fHashCode= multiplier * fHashCode + (font is null ? 0 : font.toHash()); + fHashCode= multiplier * fHashCode + (background is null ? 0 : background.toHash()); + fHashCode= multiplier * fHashCode + (foreground is null ? 0 : foreground.toHash()); + fHashCode= multiplier * fHashCode + style; + } + return fHashCode; + } + + /** + * Returns the attribute's foreground color. + * + * @return the attribute's foreground color or null if not set + */ + public Color getForeground() { + return foreground; + } + + /** + * Returns the attribute's background color. + * + * @return the attribute's background color or null if not set + */ + public Color getBackground() { + return background; + } + + /** + * Returns the attribute's style. + * + * @return the attribute's style + */ + public int getStyle() { + return style; + } + + /** + * Returns the attribute's font. + * + * @return the attribute's font or null if not set + * @since 3.3 + */ + public Font getFont() { + return font; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/TextEvent.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/TextEvent.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,270 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.TextEvent; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * This event is sent to implementers of + * {@link dwtx.jface.text.ITextListener}. It represents a change applied + * to text viewer. The change is specified as a replace command using offset, + * length, inserted text, and replaced text. The text viewer issues a text event + * after the viewer has been changed either in response to a change of the + * viewer's document or when the viewer's visual content has been changed. In + * the first case, the text event also carries the original document event. + * Depending on the viewer's presentation mode, the text event coordinates are + * different from the document event's coordinates. + *

                + * An empty text event usually indicates a change of the viewer's redraw state.

                + *

                + * Clients other than text viewer's don't create instances of this class.

                + * + * @see dwtx.jface.text.ITextListener + * @see dwtx.jface.text.ITextViewer + * @see dwtx.jface.text.DocumentEvent + */ +public class TextEvent { + + /** Start offset of the change */ + private int fOffset; + /** The length of the change */ + private int fLength; + /** Inserted text */ + private String fText; + /** Replaced text */ + private String fReplacedText; + /** The original document event, may by null */ + private DocumentEvent fDocumentEvent; + /** + * The redraw state of the viewer issuing this event + * @since 2.0 + */ + private bool fViewerRedrawState; + + /** + * Creates a new TextEvent based on the specification. + * + * @param offset the offset + * @param length the length + * @param text the inserted text + * @param replacedText the replaced text + * @param event the associated document event or null if none + * @param viewerRedrawState the redraw state of the viewer + */ + /+protected+/ this(int offset, int length, String text, String replacedText, DocumentEvent event, bool viewerRedrawState) { + fOffset= offset; + fLength= length; + fText= text; + fReplacedText= replacedText; + fDocumentEvent= event; + fViewerRedrawState= viewerRedrawState; + } + + /** + * Returns the offset of the event. + * + * @return the offset of the event + */ + public int getOffset() { + return fOffset; + } + + /** + * Returns the length of the event. + * + * @return the length of the event + */ + public int getLength() { + return fLength; + } + + /** + * Returns the text of the event. + * + * @return the text of the event + */ + public String getText() { + return fText; + } + + /** + * Returns the text replaced by this event. + * + * @return the text replaced by this event + */ + public String getReplacedText() { + return fReplacedText; + } + + /** + * Returns the corresponding document event that caused the viewer change + * + * @return the corresponding document event, null if a visual change only + */ + public DocumentEvent getDocumentEvent() { + return fDocumentEvent; + } + + /** + * Returns the viewer's redraw state. + * + * @return true if the viewer's redraw state is true + * @since 2.0 + */ + public bool getViewerRedrawState() { + return fViewerRedrawState; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/TextMessages.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/TextMessages.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,194 @@ +/******************************************************************************* + * 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 + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.text.TextMessages; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.dwthelper.ResourceBundle; +import dwtx.dwtxhelper.MessageFormat; + + +/** + * Helper class to get NLSed messages. + * + * @since 3.4 + */ +class TextMessages { +// private static const String BUNDLE_NAME= "dwtx.jface.text.TextMessages"; //$NON-NLS-1$ + + private static const ResourceBundle RESOURCE_BUNDLE;//= ResourceBundle.getBundle(BUNDLE_NAME); + + static this() { + RESOURCE_BUNDLE = ResourceBundle.getBundle( + getImportData!("dwtx.jface.text.TextMessages.properties")); + } + + + private this() { + } + + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' ~ key ~ '!'; + } + } + + public static String getFormattedString(String key, Object[] args...) { + return MessageFormat.format(getString(key), args); + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/TextPresentation.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/TextPresentation.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,873 @@ +/******************************************************************************* + * 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.text.TextPresentation; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; +import tango.core.Exception; + +import dwt.DWT; +import dwt.custom.StyleRange; +import dwt.custom.StyledText; +import dwtx.core.runtime.Assert; + + +/** + * Describes the presentation styles for a section of an indexed text such as a + * document or string. A text presentation defines a default style for the whole + * section and in addition style differences for individual subsections. Text + * presentations can be narrowed down to a particular result window. All methods + * are result window aware, i.e. ranges outside the result window are always + * ignored. + *

                + * All iterators provided by a text presentation assume that they enumerate non + * overlapping, consecutive ranges inside the default range. Thus, all these + * iterators do not include the default range. The default style range must be + * explicitly asked for using getDefaultStyleRange. + */ +public class TextPresentation { + + /** + * Applies the given presentation to the given text widget. Helper method. + * + * @param presentation the style information + * @param text the widget to which to apply the style information + * @since 2.0 + */ + public static void applyTextPresentation(TextPresentation presentation, StyledText text) { + + StyleRange[] ranges= new StyleRange[presentation.getDenumerableRanges()]; + + int i= 0; + Iterator e= presentation.getAllStyleRangeIterator(); + while (e.hasNext()) + ranges[i++]= cast(StyleRange) e.next(); + + text.setStyleRanges(ranges); + } + + + + + /** + * Enumerates all the StyleRanges included in the presentation. + */ + class FilterIterator : Iterator { + + /** The index of the next style range to be enumerated */ + protected int fIndex; + /** The upper bound of the indices of style ranges to be enumerated */ + protected int fLength; + /** Indicates whether ranges similar to the default range should be enumerated */ + protected bool fSkipDefaults; + /** The result window */ + protected IRegion fWindow; + + /** + * skipDefaults tells the enumeration to skip all those style ranges + * which define the same style as the presentation's default style range. + * + * @param skipDefaults false if ranges similar to the default range should be enumerated + */ + protected this(bool skipDefaults) { + + fSkipDefaults= skipDefaults; + + fWindow= fResultWindow; + fIndex= getFirstIndexInWindow(fWindow); + fLength= getFirstIndexAfterWindow(fWindow); + + if (fSkipDefaults) + computeIndex(); + } + + /* + * @see Iterator#next() + */ + public Object next() { + try { + StyleRange r= cast(StyleRange) fRanges.get(fIndex++); + return createWindowRelativeRange(fWindow, r); + } catch (ArrayIndexOutOfBoundsException x) { + throw new NoSuchElementException(null); + } finally { + if (fSkipDefaults) + computeIndex(); + } + } + + /* + * @see Iterator#hasNext() + */ + public bool hasNext() { + return fIndex < fLength; + } + + /* + * @see Iterator#remove() + */ + public void remove() { + throw new UnsupportedOperationException(); + } + + /** + * Returns whether the given object should be skipped. + * + * @param o the object to be checked + * @return true if the object should be skipped by the iterator + */ + protected bool skip(Object o) { + StyleRange r= cast(StyleRange) o; + return r.similarTo(fDefaultRange); + } + + /** + * Computes the index of the styled range that is the next to be enumerated. + */ + protected void computeIndex() { + while (fIndex < fLength && skip(fRanges.get(fIndex))) + ++ fIndex; + } + } + + /** The style information for the range covered by the whole presentation */ + private StyleRange fDefaultRange; + /** The member ranges of the presentation */ + private ArrayList fRanges; + /** A clipping region against which the presentation can be clipped when asked for results */ + private IRegion fResultWindow; + /** + * The optional extent for this presentation. + * @since 3.0 + */ + private IRegion fExtent; + + + /** + * Creates a new empty text presentation. + */ + public this() { + fRanges= new ArrayList(50); + } + + /** + * Creates a new empty text presentation. sizeHint tells the + * expected size of this presentation. + * + * @param sizeHint the expected size of this presentation + */ + public this(int sizeHint) { + Assert.isTrue(sizeHint > 0); + fRanges= new ArrayList(sizeHint); + } + + /** + * Creates a new empty text presentation with the given extent. + * sizeHint tells the expected size of this presentation. + * + * @param extent the extent of the created TextPresentation + * @param sizeHint the expected size of this presentation + * @since 3.0 + */ + public this(IRegion extent, int sizeHint) { + this(sizeHint); + Assert.isNotNull(cast(Object)extent); + fExtent= extent; + } + + /** + * Sets the result window for this presentation. When dealing with + * this presentation all ranges which are outside the result window + * are ignored. For example, the size of the presentation is 0 + * when there is no range inside the window even if there are ranges + * outside the window. All methods are aware of the result window. + * + * @param resultWindow the result window + */ + public void setResultWindow(IRegion resultWindow) { + fResultWindow= resultWindow; + } + + /** + * Set the default style range of this presentation. + * The default style range defines the overall area covered + * by this presentation and its style information. + * + * @param range the range describing the default region + */ + public void setDefaultStyleRange(StyleRange range) { + fDefaultRange= range; + } + + /** + * Returns this presentation's default style range. The returned StyleRange + * is relative to the start of the result window. + * + * @return this presentation's default style range + */ + public StyleRange getDefaultStyleRange() { + StyleRange range= createWindowRelativeRange(fResultWindow, fDefaultRange); + if (range is null) + return null; + return cast(StyleRange)range.clone(); + + } + + /** + * Add the given range to the presentation. The range must be a + * subrange of the presentation's default range. + * + * @param range the range to be added + */ + public void addStyleRange(StyleRange range) { + checkConsistency(range); + fRanges.add(range); + } + + /** + * Replaces the given range in this presentation. The range must be a + * subrange of the presentation's default range. + * + * @param range the range to be added + * @since 3.0 + */ + public void replaceStyleRange(StyleRange range) { + applyStyleRange(range, false); + } + + /** + * Merges the given range into this presentation. The range must be a + * subrange of the presentation's default range. + * + * @param range the range to be added + * @since 3.0 + */ + public void mergeStyleRange(StyleRange range) { + applyStyleRange(range, true); + } + + /** + * Applies the given range to this presentation. The range must be a + * subrange of the presentation's default range. + * + * @param range the range to be added + * @param merge true if the style should be merged instead of replaced + * @since 3.0 + */ + private void applyStyleRange(StyleRange range, bool merge) { + if (range.length is 0) + return; + + checkConsistency(range); + + int start= range.start; + int length= range.length; + int end= start + length; + + if (fRanges.size() is 0) { + StyleRange defaultRange= getDefaultStyleRange(); + if (defaultRange is null) + defaultRange= range; + + defaultRange.start= start; + defaultRange.length= length; + applyStyle(range, defaultRange, merge); + fRanges.add(defaultRange); + } else { + IRegion rangeRegion= new Region(start, length); + int first= getFirstIndexInWindow(rangeRegion); + + if (first is fRanges.size()) { + StyleRange defaultRange= getDefaultStyleRange(); + if (defaultRange is null) + defaultRange= range; + defaultRange.start= start; + defaultRange.length= length; + applyStyle(range, defaultRange, merge); + fRanges.add(defaultRange); + return; + } + + int last= getFirstIndexAfterWindow(rangeRegion); + for (int i= first; i < last && length > 0; i++) { + + StyleRange current= cast(StyleRange)fRanges.get(i); + int currentStart= current.start; + int currentEnd= currentStart + current.length; + + if (end <= currentStart) { + fRanges.add(i, range); + return; + } + + if (start >= currentEnd) + continue; + + StyleRange currentCopy= null; + if (end < currentEnd) + currentCopy= cast(StyleRange)current.clone(); + + if (start < currentStart) { + // Apply style to new default range and add it + StyleRange defaultRange= getDefaultStyleRange(); + if (defaultRange is null) + defaultRange= new StyleRange(); + + defaultRange.start= start; + defaultRange.length= currentStart - start; + applyStyle(range, defaultRange, merge); + fRanges.add(i, defaultRange); + i++; last++; + + + // Apply style to first part of current range + current.length= Math.min(end, currentEnd) - currentStart; + applyStyle(range, current, merge); + } + + if (start >= currentStart) { + // Shorten the current range + current.length= start - currentStart; + + // Apply the style to the rest of the current range and add it + if (current.length > 0) { + current= cast(StyleRange)current.clone(); + i++; last++; + fRanges.add(i, current); + } + applyStyle(range, current, merge); + current.start= start; + current.length= Math.min(end, currentEnd) - start; + } + + if (end < currentEnd) { + // Add rest of current range + currentCopy.start= end; + currentCopy.length= currentEnd - end; + i++; last++; + fRanges.add(i, currentCopy); + } + + // Update range + range.start= currentEnd; + range.length= Math.max(end - currentEnd, 0); + start= range.start; + length= range.length; + } + if (length > 0) { + // Apply style to new default range and add it + StyleRange defaultRange= getDefaultStyleRange(); + if (defaultRange is null) + defaultRange= range; + defaultRange.start= start; + defaultRange.length= end - start; + applyStyle(range, defaultRange, merge); + fRanges.add(last, defaultRange); + } + } + } + + /** + * Replaces the given ranges in this presentation. Each range must be a + * subrange of the presentation's default range. The ranges must be ordered + * by increasing offset and must not overlap (but may be adjacent). + * + * @param ranges the ranges to be added + * @since 3.0 + */ + public void replaceStyleRanges(StyleRange[] ranges) { + applyStyleRanges(ranges, false); + } + + /** + * Merges the given ranges into this presentation. Each range must be a + * subrange of the presentation's default range. The ranges must be ordered + * by increasing offset and must not overlap (but may be adjacent). + * + * @param ranges the ranges to be added + * @since 3.0 + */ + public void mergeStyleRanges(StyleRange[] ranges) { + applyStyleRanges(ranges, true); + } + + /** + * Applies the given ranges to this presentation. Each range must be a + * subrange of the presentation's default range. The ranges must be ordered + * by increasing offset and must not overlap (but may be adjacent). + * + * @param ranges the ranges to be added + * @param merge true if the style should be merged instead of replaced + * @since 3.0 + */ + private void applyStyleRanges(StyleRange[] ranges, bool merge) { + int j= 0; + ArrayList oldRanges= fRanges; + ArrayList newRanges= new ArrayList(2*ranges.length + oldRanges.size()); + for (int i= 0, n= ranges.length; i < n; i++) { + StyleRange range= ranges[i]; + fRanges= oldRanges; // for getFirstIndexAfterWindow(...) + for (int m= getFirstIndexAfterWindow(new Region(range.start, range.length)); j < m; j++) + newRanges.add(oldRanges.get(j)); + fRanges= newRanges; // for mergeStyleRange(...) + applyStyleRange(range, merge); + } + for (int m= oldRanges.size(); j < m; j++) + newRanges.add(oldRanges.get(j)); + fRanges= newRanges; + } + + /** + * Applies the template_'s style to the target. + * + * @param template_ the style range to be used as template_ + * @param target the style range to which to apply the template_ + * @param merge true if the style should be merged instead of replaced + * @since 3.0 + */ + private void applyStyle(StyleRange template_, StyleRange target, bool merge) { + if (merge) { + if (template_.font !is null) + target.font= template_.font; + target.fontStyle|= template_.fontStyle; + + if (template_.metrics !is null) + target.metrics= template_.metrics; + + if (template_.foreground !is null) + target.foreground= template_.foreground; + if (template_.background !is null) + target.background= template_.background; + + target.strikeout|= template_.strikeout; + if (template_.strikeoutColor !is null) + target.strikeoutColor= template_.strikeoutColor; + + target.underline|= template_.underline; + if (template_.underlineStyle !is DWT.NONE) + target.underlineStyle= template_.underlineStyle; + if (template_.underlineColor !is null) + target.underlineColor= template_.underlineColor; + + if (template_.borderStyle !is DWT.NONE) + target.borderStyle= template_.borderStyle; + if (template_.borderColor !is null) + target.borderColor= template_.borderColor; + + } else { + target.font= template_.font; + target.fontStyle= template_.fontStyle; + target.metrics= template_.metrics; + target.foreground= template_.foreground; + target.background= template_.background; + target.strikeout= template_.strikeout; + target.strikeoutColor= template_.strikeoutColor; + target.underline= template_.underline; + target.underlineStyle= template_.underlineStyle; + target.underlineColor= template_.underlineColor; + target.borderStyle= template_.borderStyle; + target.borderColor= template_.borderColor; + } + } + + /** + * Checks whether the given range is a subrange of the presentation's + * default style range. + * + * @param range the range to be checked + * @exception IllegalArgumentException if range is not a subrange of the presentation's default range + */ + private void checkConsistency(StyleRange range) { + + if (range is null) + throw new IllegalArgumentException(null); + + if (fDefaultRange !is null) { + + if (range.start < fDefaultRange.start) + range.start= fDefaultRange.start; + + int defaultEnd= fDefaultRange.start + fDefaultRange.length; + int end= range.start + range.length; + if (end > defaultEnd) + range.length -= (end - defaultEnd); + } + } + + /** + * Returns the index of the first range which overlaps with the + * specified window. + * + * @param window the window to be used for searching + * @return the index of the first range overlapping with the window + */ + private int getFirstIndexInWindow(IRegion window) { + if (window !is null) { + int start= window.getOffset(); + int i= -1, j= fRanges.size(); + while (j - i > 1) { + int k= (i + j) >> 1; + StyleRange r= cast(StyleRange) fRanges.get(k); + if (r.start + r.length > start) + j= k; + else + i= k; + } + return j; + } + return 0; + } + + /** + * Returns the index of the first range which comes after the specified window and does + * not overlap with this window. + * + * @param window the window to be used for searching + * @return the index of the first range behind the window and not overlapping with the window + */ + private int getFirstIndexAfterWindow(IRegion window) { + if (window !is null) { + int end= window.getOffset() + window.getLength(); + int i= -1, j= fRanges.size(); + while (j - i > 1) { + int k= (i + j) >> 1; + StyleRange r= cast(StyleRange) fRanges.get(k); + if (r.start < end) + i= k; + else + j= k; + } + return j; + } + return fRanges.size(); + } + + /** + * Returns a style range which is relative to the specified window and + * appropriately clipped if necessary. The original style range is not + * modified. + * + * @param window the reference window + * @param range the absolute range + * @return the window relative range based on the absolute range + */ + private StyleRange createWindowRelativeRange(IRegion window, StyleRange range) { + if (window is null || range is null) + return range; + + int start= range.start - window.getOffset(); + if (start < 0) + start= 0; + + int rangeEnd= range.start + range.length; + int windowEnd= window.getOffset() + window.getLength(); + int end= (rangeEnd > windowEnd ? windowEnd : rangeEnd); + end -= window.getOffset(); + + StyleRange newRange= cast(StyleRange) range.clone(); + newRange.start= start; + newRange.length= end - start; + return newRange; + } + + /** + * Returns the region which is relative to the specified window and + * appropriately clipped if necessary. + * + * @param coverage the absolute coverage + * @return the window relative region based on the absolute coverage + * @since 3.0 + */ + private IRegion createWindowRelativeRegion(IRegion coverage) { + if (fResultWindow is null || coverage is null) + return coverage; + + int start= coverage.getOffset() - fResultWindow.getOffset(); + if (start < 0) + start= 0; + + int rangeEnd= coverage.getOffset() + coverage.getLength(); + int windowEnd= fResultWindow.getOffset() + fResultWindow.getLength(); + int end= (rangeEnd > windowEnd ? windowEnd : rangeEnd); + end -= fResultWindow.getOffset(); + + return new Region(start, end - start); + } + + /** + * Returns an iterator which enumerates all style ranged which define a style + * different from the presentation's default style range. The default style range + * is not enumerated. + * + * @return a style range iterator + */ + public Iterator getNonDefaultStyleRangeIterator() { + return new FilterIterator(fDefaultRange !is null); + } + + /** + * Returns an iterator which enumerates all style ranges of this presentation + * except the default style range. The returned StyleRanges + * are relative to the start of the presentation's result window. + * + * @return a style range iterator + */ + public Iterator getAllStyleRangeIterator() { + return new FilterIterator(false); + } + + /** + * Returns whether this collection contains any style range including + * the default style range. + * + * @return true if there is no style range in this presentation + */ + public bool isEmpty() { + return (fDefaultRange is null && getDenumerableRanges() is 0); + } + + /** + * Returns the number of style ranges in the presentation not counting the default + * style range. + * + * @return the number of style ranges in the presentation excluding the default style range + */ + public int getDenumerableRanges() { + int size= getFirstIndexAfterWindow(fResultWindow) - getFirstIndexInWindow(fResultWindow); + return (size < 0 ? 0 : size); + } + + /** + * Returns the style range with the smallest offset ignoring the default style range or null + * if the presentation is empty. + * + * @return the style range with the smallest offset different from the default style range + */ + public StyleRange getFirstStyleRange() { + try { + + StyleRange range= cast(StyleRange) fRanges.get(getFirstIndexInWindow(fResultWindow)); + return createWindowRelativeRange(fResultWindow, range); + + } catch (NoSuchElementException x) { + } catch (IndexOutOfBoundsException x) { + } + + return null; + } + + /** + * Returns the style range with the highest offset ignoring the default style range. + * + * @return the style range with the highest offset different from the default style range + */ + public StyleRange getLastStyleRange() { + try { + + StyleRange range= cast(StyleRange) fRanges.get(getFirstIndexAfterWindow(fResultWindow) - 1); + return createWindowRelativeRange(fResultWindow, range); + + } catch (NoSuchElementException x) { + return null; + } catch (IndexOutOfBoundsException x) { + return null; + } + } + + /** + * Returns the coverage of this presentation as clipped by the presentation's + * result window. + * + * @return the coverage of this presentation + */ + public IRegion getCoverage() { + + if (fDefaultRange !is null) { + StyleRange range= getDefaultStyleRange(); + return new Region(range.start, range.length); + } + + StyleRange first= getFirstStyleRange(); + StyleRange last= getLastStyleRange(); + + if (first is null || last is null) + return null; + + return new Region(first.start, last.start - first. start + last.length); + } + + /** + * Returns the extent of this presentation clipped by the + * presentation's result window. + * + * @return the clipped extent + * @since 3.0 + */ + public IRegion getExtent() { + if (fExtent !is null) + return createWindowRelativeRegion(fExtent); + return getCoverage(); + } + + /** + * Clears this presentation by resetting all applied changes. + * @since 2.0 + */ + public void clear() { + fDefaultRange= null; + fResultWindow= null; + fRanges.clear(); + } + + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/TextSelection.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/TextSelection.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,343 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.TextSelection; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Standard implementation of {@link dwtx.jface.text.ITextSelection}. + *

                + * Makes advantage of the weak contract of correctness of its interface. If + * generated from a selection provider, it only remembers its offset and length + * and computes the remaining information on request.

                + */ +public class TextSelection : ITextSelection { + + /** Internal empty text selection */ + private static ITextSelection NULL_; + private static ITextSelection NULL(){ + if( NULL_ is null ){ + synchronized( TextSelection.classinfo ){ + if( NULL_ is null ){ + NULL_= new TextSelection(); + } + } + } + return NULL_; + } + + /** + * Returns a shared instance of an empty text selection. + * + * @return a shared instance of an empty text selection + */ + public static ITextSelection emptySelection() { + return NULL; + } + + /** Document which delivers the data of the selection */ + private IDocument fDocument; + /** Offset of the selection */ + private int fOffset; + /** Length of the selection */ + private int fLength; + + + /** + * Creates an empty text selection. + */ + private this() { + this(null, -1, -1); + } + + /** + * Creates a text selection for the given range. This + * selection object describes generically a text range and + * is intended to be an argument for the setSelection + * method of selection providers. + * + * @param offset the offset of the range + * @param length the length of the range + */ + public this(int offset, int length) { + this(null, offset, length); + } + + /** + * Creates a text selection for the given range of the given document. + * This selection object is created by selection providers in responds + * getSelection. + * + * @param document the document whose text range is selected in a viewer + * @param offset the offset of the selected range + * @param length the length of the selected range + */ + public this(IDocument document, int offset, int length) { + fDocument= document; + fOffset= offset; + fLength= length; + } + + /** + * + * Returns true if the offset and length are smaller than 0. + * A selection of length 0, is a valid text selection as it + * describes, e.g., the cursor position in a viewer. + * + * @return true if this selection is empty + * @see dwtx.jface.viewers.ISelection#isEmpty() + */ + public bool isEmpty() { + return fOffset < 0 || fLength < 0; + } + + /* + * @see dwtx.jface.text.ITextSelection#getOffset() + */ + public int getOffset() { + return fOffset; + } + + /* + * @see dwtx.jface.text.ITextSelection#getLength() + */ + public int getLength() { + return fLength; + } + + /* + * @see dwtx.jface.text.ITextSelection#getStartLine() + */ + public int getStartLine() { + + try { + if (fDocument !is null) + return fDocument.getLineOfOffset(fOffset); + } catch (BadLocationException x) { + } + + return -1; + } + + /* + * @see dwtx.jface.text.ITextSelection#getEndLine() + */ + public int getEndLine() { + try { + if (fDocument !is null) { + int endOffset= fOffset + fLength; + if (fLength !is 0) + endOffset--; + return fDocument.getLineOfOffset(endOffset); + } + } catch (BadLocationException x) { + } + + return -1; + } + + /* + * @see dwtx.jface.text.ITextSelection#getText() + */ + public String getText() { + try { + if (fDocument !is null) + return fDocument.get(fOffset, fLength); + } catch (BadLocationException x) { + } + + return null; + } + + /* + * @see java.lang.Object#equals(Object) + */ + public override int opEquals(Object obj) { + if (obj is this) + return true; + + if (obj is null || this.classinfo !is obj.classinfo) + return false; + + TextSelection s= cast(TextSelection) obj; + bool sameRange= (s.fOffset is fOffset && s.fLength is fLength); + if (sameRange) { + + if (s.fDocument is null && fDocument is null) + return true; + if (s.fDocument is null || fDocument is null) + return false; + + try { + String sContent= s.fDocument.get(fOffset, fLength); + String content= fDocument.get(fOffset, fLength); + return sContent==/+eq+/content; + } catch (BadLocationException x) { + } + } + + return false; + } + + /* + * @see java.lang.Object#hashCode() + */ + public override hash_t toHash() { + int low= fDocument !is null ? (cast(Object)fDocument).toHash() : 0; + return (fOffset << 24) | (fLength << 16) | low; + } +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/TextUtilities.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/TextUtilities.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,718 @@ +/******************************************************************************* + * 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 + * 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.text.TextUtilities; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +// import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + + + + + +import dwtx.core.runtime.Assert; + + +/** + * A collection of text functions. + *

                + * This class is neither intended to be instantiated nor subclassed. + *

                + * @noinstantiate This class is not intended to be instantiated by clients. + * @noextend This class is not intended to be subclassed by clients. + */ +public class TextUtilities { + + /** + * Default line delimiters used by the text functions of this class. + */ + public const static String[] DELIMITERS= [ "\n", "\r", "\r\n" ]; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ + + /** + * Default line delimiters used by these text functions. + * + * @deprecated use DELIMITERS instead + */ + public const static String[] fgDelimiters= DELIMITERS; + + + + /** + * Determines which one of default line delimiters appears first in the list. If none of them the + * hint is returned. + * + * @param text the text to be checked + * @param hint the line delimiter hint + * @return the line delimiter + */ + public static String determineLineDelimiter(String text, String hint) { + try { + int[] info= indexOf(DELIMITERS, text, 0); + return DELIMITERS[info[1]]; + } catch (ArrayIndexOutOfBoundsException x) { + } + return hint; + } + + /** + * Returns the starting position and the index of the first matching search string + * in the given text that is greater than the given offset. If more than one search + * string matches with the same starting position then the longest one is returned. + * + * @param searchStrings the strings to search for + * @param text the text to be searched + * @param offset the offset at which to start the search + * @return an int[] with two elements where the first is the starting offset, the second the index of the found + * search string in the given searchStrings array, returns [-1, -1] if no match exists + */ + public static int[] indexOf(String[] searchStrings, String text, int offset) { + + int[] result= [ -1, -1 ]; + int zeroIndex= -1; + + for (int i= 0; i < searchStrings.length; i++) { + + int length= searchStrings[i].length(); + + if (length is 0) { + zeroIndex= i; + continue; + } + + int index= .indexOf( text, searchStrings[i], offset); + if (index >= 0) { + + if (result[0] is -1) { + result[0]= index; + result[1]= i; + } else if (index < result[0]) { + result[0]= index; + result[1]= i; + } else if (index is result[0] && length > searchStrings[result[1]].length) { + result[0]= index; + result[1]= i; + } + } + } + + if (zeroIndex > -1 && result[0] is -1) { + result[0]= 0; + result[1]= zeroIndex; + } + + return result; + } + + /** + * Returns the index of the longest search string with which the given text ends or + * -1 if none matches. + * + * @param searchStrings the strings to search for + * @param text the text to search + * @return the index in searchStrings of the longest string with which text ends or -1 + */ + public static int endsWith(String[] searchStrings, String text) { + + int index= -1; + + for (int i= 0; i < searchStrings.length; i++) { + if (.endsWith(text, searchStrings[i])) { + if (index is -1 || searchStrings[i].length() > searchStrings[index].length()) + index= i; + } + } + + return index; + } + + /** + * Returns the index of the longest search string with which the given text starts or -1 + * if none matches. + * + * @param searchStrings the strings to search for + * @param text the text to search + * @return the index in searchStrings of the longest string with which text starts or -1 + */ + public static int startsWith(String[] searchStrings, String text) { + + int index= -1; + + for (int i= 0; i < searchStrings.length; i++) { + if (.startsWith(text, searchStrings[i])) { + if (index is -1 || searchStrings[i].length() > searchStrings[index].length()) + index= i; + } + } + + return index; + } + + /** + * Returns the index of the first compare string that equals the given text or -1 + * if none is equal. + * + * @param compareStrings the strings to compare with + * @param text the text to check + * @return the index of the first equal compare string or -1 + */ + public static int equals(String[] compareStrings, String text) { + for (int i= 0; i < compareStrings.length; i++) { + if (.equals(text,compareStrings[i])) + return i; + } + return -1; + } + + /** + * Returns a document event which is an accumulation of a list of document events, + * null if the list of documentEvents is empty. + * The document of the document events are ignored. + * + * @param unprocessedDocument the document to which the document events would be applied + * @param documentEvents the list of document events to merge + * @return returns the merged document event + * @throws BadLocationException might be thrown if document is not in the correct state with respect to document events + */ + public static DocumentEvent mergeUnprocessedDocumentEvents(IDocument unprocessedDocument, List documentEvents) { + + if (documentEvents.size() is 0) + return null; + + final Iterator iterator= documentEvents.iterator(); + final DocumentEvent firstEvent= cast(DocumentEvent) iterator.next(); + + // current merged event + final IDocument document= unprocessedDocument; + int offset= firstEvent.getOffset(); + int length= firstEvent.getLength(); + final StringBuffer text= new StringBuffer(firstEvent.getText() is null ? "" : firstEvent.getText()); //$NON-NLS-1$ + + while (iterator.hasNext()) { + + final int delta= text.length() - length; + + final DocumentEvent event= cast(DocumentEvent) iterator.next(); + final int eventOffset= event.getOffset(); + final int eventLength= event.getLength(); + final String eventText= event.getText() is null ? "" : event.getText(); //$NON-NLS-1$ + + // event is right from merged event + if (eventOffset > offset + length + delta) { + final String string= document.get(offset + length, (eventOffset - delta) - (offset + length)); + text.append(string); + text.append(eventText); + + length= (eventOffset - delta) + eventLength - offset; + + // event is left from merged event + } else if (eventOffset + eventLength < offset) { + final String string= document.get(eventOffset + eventLength, offset - (eventOffset + eventLength)); + text.select(0,0); + text.replace(string); + text.select(0,0); + text.replace(eventText); + + length= offset + length - eventOffset; + offset= eventOffset; + + // events overlap each other + } else { + final int start= Math.max(0, eventOffset - offset); + final int end= Math.min(text.length(), eventLength + eventOffset - offset); + text.select(start, end); + text.replace(eventText); + + offset= Math.min(offset, eventOffset); + final int totalDelta= delta + eventText.length - eventLength; + length= text.length() - totalDelta; + } + } + + return new DocumentEvent(document, offset, length, text.toString()); + } + + /** + * Returns a document event which is an accumulation of a list of document events, + * null if the list of document events is empty. + * The document events being merged must all refer to the same document, to which + * the document changes have been already applied. + * + * @param documentEvents the list of document events to merge + * @return returns the merged document event + * @throws BadLocationException might be thrown if document is not in the correct state with respect to document events + */ + public static DocumentEvent mergeProcessedDocumentEvents(List documentEvents) { + + if (documentEvents.size() is 0) + return null; + + final ListIterator iterator= documentEvents.listIterator(documentEvents.size()); + final DocumentEvent firstEvent= cast(DocumentEvent) iterator.previous(); + + // current merged event + final IDocument document= firstEvent.getDocument(); + int offset= firstEvent.getOffset(); + int length= firstEvent.getLength(); + int textLength= firstEvent.getText() is null ? 0 : firstEvent.getText().length; + + while (iterator.hasPrevious()) { + + final int delta= length - textLength; + + final DocumentEvent event= cast(DocumentEvent) iterator.previous(); + final int eventOffset= event.getOffset(); + final int eventLength= event.getLength(); + final int eventTextLength= event.getText() is null ? 0 : event.getText().length; + + // event is right from merged event + if (eventOffset > offset + textLength + delta) { + length= (eventOffset - delta) - (offset + textLength) + length + eventLength; + textLength= (eventOffset - delta) + eventTextLength - offset; + + // event is left from merged event + } else if (eventOffset + eventTextLength < offset) { + length= offset - (eventOffset + eventTextLength) + length + eventLength; + textLength= offset + textLength - eventOffset; + offset= eventOffset; + + // events overlap each other + } else { + final int start= Math.max(0, eventOffset - offset); + final int end= Math.min(length, eventTextLength + eventOffset - offset); + length += eventLength - (end - start); + + offset= Math.min(offset, eventOffset); + final int totalDelta= delta + eventLength - eventTextLength; + textLength= length - totalDelta; + } + } + + final String text= document.get(offset, textLength); + return new DocumentEvent(document, offset, length, text); + } + + /** + * Removes all connected document partitioners from the given document and stores them + * under their partitioning name in a map. This map is returned. After this method has been called + * the given document is no longer connected to any document partitioner. + * + * @param document the document + * @return the map containing the removed partitioners + */ + public static Map removeDocumentPartitioners(IDocument document) { + Map partitioners= new HashMap(); + if (cast(IDocumentExtension3)document ) { + IDocumentExtension3 extension3= cast(IDocumentExtension3) document; + String[] partitionings= extension3.getPartitionings(); + for (int i= 0; i < partitionings.length; i++) { + IDocumentPartitioner partitioner= extension3.getDocumentPartitioner(partitionings[i]); + if (partitioner !is null) { + extension3.setDocumentPartitioner(partitionings[i], null); + partitioner.disconnect(); + partitioners.put(stringcast(partitionings[i]), cast(Object)partitioner); + } + } + } else { + IDocumentPartitioner partitioner= document.getDocumentPartitioner(); + if (partitioner !is null) { + document.setDocumentPartitioner(null); + partitioner.disconnect(); + partitioners.put(stringcast(IDocumentExtension3.DEFAULT_PARTITIONING), cast(Object)partitioner); + } + } + return partitioners; + } + + /** + * Connects the given document with all document partitioners stored in the given map under + * their partitioning name. This method cleans the given map. + * + * @param document the document + * @param partitioners the map containing the partitioners to be connected + * @since 3.0 + */ + public static void addDocumentPartitioners(IDocument document, Map partitioners) { + if (cast(IDocumentExtension3)document ) { + IDocumentExtension3 extension3= cast(IDocumentExtension3) document; + Iterator e= partitioners.keySet().iterator(); + while (e.hasNext()) { + String partitioning= stringcast( e.next() ); + IDocumentPartitioner partitioner= cast(IDocumentPartitioner) partitioners.get(partitioning); + partitioner.connect(document); + extension3.setDocumentPartitioner(partitioning, partitioner); + } + partitioners.clear(); + } else { + IDocumentPartitioner partitioner= cast(IDocumentPartitioner) partitioners.get(IDocumentExtension3.DEFAULT_PARTITIONING); + partitioner.connect(document); + document.setDocumentPartitioner(partitioner); + } + } + + /** + * Returns the content type at the given offset of the given document. + * + * @param document the document + * @param partitioning the partitioning to be used + * @param offset the offset + * @param preferOpenPartitions true if precedence should be + * given to a open partition ending at offset over a + * closed partition starting at offset + * @return the content type at the given offset of the document + * @throws BadLocationException if offset is invalid in the document + * @since 3.0 + */ + public static String getContentType(IDocument document, String partitioning, int offset, bool preferOpenPartitions) { + if (cast(IDocumentExtension3)document ) { + IDocumentExtension3 extension3= cast(IDocumentExtension3) document; + try { + return extension3.getContentType(partitioning, offset, preferOpenPartitions); + } catch (BadPartitioningException x) { + return IDocument.DEFAULT_CONTENT_TYPE; + } + } + + return document.getContentType(offset); + } + + /** + * Returns the partition of the given offset of the given document. + * + * @param document the document + * @param partitioning the partitioning to be used + * @param offset the offset + * @param preferOpenPartitions true if precedence should be + * given to a open partition ending at offset over a + * closed partition starting at offset + * @return the content type at the given offset of this viewer's input + * document + * @throws BadLocationException if offset is invalid in the given document + * @since 3.0 + */ + public static ITypedRegion getPartition(IDocument document, String partitioning, int offset, bool preferOpenPartitions) { + if (cast(IDocumentExtension3)document ) { + IDocumentExtension3 extension3= cast(IDocumentExtension3) document; + try { + return extension3.getPartition(partitioning, offset, preferOpenPartitions); + } catch (BadPartitioningException x) { + return new TypedRegion(0, document.getLength(), IDocument.DEFAULT_CONTENT_TYPE); + } + } + + return document.getPartition(offset); + } + + /** + * Computes and returns the partitioning for the given region of the given + * document for the given partitioning name. + * + * @param document the document + * @param partitioning the partitioning name + * @param offset the region offset + * @param length the region length + * @param includeZeroLengthPartitions whether to include zero-length partitions + * @return the partitioning for the given region of the given document for + * the given partitioning name + * @throws BadLocationException if the given region is invalid for the given + * document + * @since 3.0 + */ + public static ITypedRegion[] computePartitioning(IDocument document, String partitioning, int offset, int length, bool includeZeroLengthPartitions) { + if (cast(IDocumentExtension3)document ) { + IDocumentExtension3 extension3= cast(IDocumentExtension3) document; + try { + return extension3.computePartitioning(partitioning, offset, length, includeZeroLengthPartitions); + } catch (BadPartitioningException x) { + return new ITypedRegion[0]; + } + } + + return document.computePartitioning(offset, length); + } + + /** + * Computes and returns the partition managing position categories for the + * given document or null if this was impossible. + * + * @param document the document + * @return the partition managing position categories or null + * @since 3.0 + */ + public static String[] computePartitionManagingCategories(IDocument document) { + if (cast(IDocumentExtension3)document ) { + IDocumentExtension3 extension3= cast(IDocumentExtension3) document; + String[] partitionings= extension3.getPartitionings(); + if (partitionings !is null) { + Set categories= new HashSet(); + for (int i= 0; i < partitionings.length; i++) { + IDocumentPartitioner p= extension3.getDocumentPartitioner(partitionings[i]); + if (cast(IDocumentPartitionerExtension2)p ) { + IDocumentPartitionerExtension2 extension2= cast(IDocumentPartitionerExtension2) p; + String[] c= extension2.getManagingPositionCategories(); + if (c !is null) { + for (int j= 0; j < c.length; j++) + categories.add(c[j]); + } + } + } + return stringcast(categories.toArray()); + } + } + return null; + } + + /** + * Returns the default line delimiter for the given document. This is either the delimiter of the first line, or the platform line delimiter if it is + * a legal line delimiter or the first one of the legal line delimiters. The default line delimiter should be used when performing document + * manipulations that span multiple lines. + * + * @param document the document + * @return the document's default line delimiter + * @since 3.0 + */ + public static String getDefaultLineDelimiter(IDocument document) { + + if (cast(IDocumentExtension4)document ) + return (cast(IDocumentExtension4)document).getDefaultLineDelimiter(); + + String lineDelimiter= null; + + try { + lineDelimiter= document.getLineDelimiter(0); + } catch (BadLocationException x) { + } + + if (lineDelimiter !is null) + return lineDelimiter; + + String sysLineDelimiter= System.getProperty("line.separator"); //$NON-NLS-1$ + String[] delimiters= document.getLegalLineDelimiters(); + Assert.isTrue(delimiters.length > 0); + for (int i= 0; i < delimiters.length; i++) { + if (.equals(delimiters[i], sysLineDelimiter)) { + lineDelimiter= sysLineDelimiter; + break; + } + } + + if (lineDelimiter is null) + lineDelimiter= delimiters[0]; + + return lineDelimiter; + } + + /** + * Returns true if the two regions overlap. Returns false if one of the + * arguments is null. + * + * @param left the left region + * @param right the right region + * @return true if the two regions overlap, false otherwise + * @since 3.0 + */ + public static bool overlaps(IRegion left, IRegion right) { + + if (left is null || right is null) + return false; + + int rightEnd= right.getOffset() + right.getLength(); + int leftEnd= left.getOffset()+ left.getLength(); + + if (right.getLength() > 0) { + if (left.getLength() > 0) + return left.getOffset() < rightEnd && right.getOffset() < leftEnd; + return right.getOffset() <= left.getOffset() && left.getOffset() < rightEnd; + } + + if (left.getLength() > 0) + return left.getOffset() <= right.getOffset() && right.getOffset() < leftEnd; + + return left.getOffset() is right.getOffset(); + } + + /** + * Returns a copy of the given string array. + * + * @param array the string array to be copied + * @return a copy of the given string array or null when array is null + * @since 3.1 + */ + public static String[] copy(String[] array) { + if (array !is null) { + String[] copy= new String[array.length]; + System.arraycopy(array, 0, copy, 0, array.length); + return copy; + } + return null; + } + + /** + * Returns a copy of the given integer array. + * + * @param array the integer array to be copied + * @return a copy of the given integer array or null when array is null + * @since 3.1 + */ + public static int[] copy(int[] array) { + if (array !is null) { + int[] copy= new int[array.length]; + System.arraycopy(array, 0, copy, 0, array.length); + return copy; + } + return null; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/TextViewer.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/TextViewer.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,5543 @@ +/******************************************************************************* + * 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 + * 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.text.TextViewer; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; +import dwtx.dwtxhelper.regex; +import tango.text.convert.Format; +import tango.core.Thread; + +import dwt.DWT; +import dwt.custom.LineBackgroundEvent; +import dwt.custom.LineBackgroundListener; +import dwt.custom.MovementEvent; +import dwt.custom.MovementListener; +import dwt.custom.ST; +import dwt.custom.StyleRange; +import dwt.custom.StyledText; +import dwt.custom.StyledTextPrintOptions; +import dwt.custom.VerifyKeyListener; +import dwt.events.ControlEvent; +import dwt.events.ControlListener; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.events.KeyEvent; +import dwt.events.KeyListener; +import dwt.events.MouseAdapter; +import dwt.events.MouseEvent; +import dwt.events.MouseListener; +import dwt.events.SelectionEvent; +import dwt.events.SelectionListener; +import dwt.events.TraverseEvent; +import dwt.events.TraverseListener; +import dwt.events.VerifyEvent; +import dwt.events.VerifyListener; +import dwt.graphics.Color; +import dwt.graphics.GC; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.printing.PrintDialog; +import dwt.printing.Printer; +import dwt.printing.PrinterData; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Listener; +import dwt.widgets.ScrollBar; +import dwtx.core.runtime.Assert; +import dwtx.jface.internal.text.NonDeletingPositionUpdater; +import dwtx.jface.internal.text.StickyHoverManager; +import dwtx.jface.text.hyperlink.HyperlinkManager; +import dwtx.jface.text.hyperlink.IHyperlinkDetector; +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; +import dwtx.jface.text.hyperlink.IHyperlinkPresenter; +import dwtx.jface.text.hyperlink.HyperlinkManager; +import dwtx.jface.text.projection.ChildDocument; +import dwtx.jface.text.projection.ChildDocumentManager; +import dwtx.jface.viewers.IPostSelectionProvider; +import dwtx.jface.viewers.ISelection; +import dwtx.jface.viewers.ISelectionChangedListener; +import dwtx.jface.viewers.ISelectionProvider; +import dwtx.jface.viewers.SelectionChangedEvent; +import dwtx.jface.viewers.Viewer; + + +/** + * DWT based implementation of {@link ITextViewer} and its extension interfaces. + * Once the viewer and its DWT control have been created the viewer can only + * indirectly be disposed by disposing its DWT control. + *

                + * Clients are supposed to instantiate a text viewer and subsequently to + * communicate with it exclusively using the + * {@link dwtx.jface.text.ITextViewer} interface or any of the + * implemented extension interfaces. + *

                + * A text viewer serves as text operation target. It only partially supports the + * external control of the enable state of its text operations. A text viewer is + * also a widget token owner. Anything that wants to display an overlay window + * on top of a text viewer should implement the + * {@link dwtx.jface.text.IWidgetTokenKeeper} interface and participate + * in the widget token negotiation between the text viewer and all its potential + * widget token keepers. + *

                + * This class is not intended to be subclassed outside the JFace Text component.

                + * @noextend This class is not intended to be subclassed by clients. + */ +public class TextViewer : Viewer , + ITextViewer, ITextViewerExtension, ITextViewerExtension2, ITextViewerExtension4, ITextViewerExtension6, ITextViewerExtension7, ITextViewerExtension8, + IEditingSupportRegistry, ITextOperationTarget, ITextOperationTargetExtension, + IWidgetTokenOwner, IWidgetTokenOwnerExtension, IPostSelectionProvider { + + alias Viewer.fireSelectionChanged fireSelectionChanged; + + /** Internal flag to indicate the debug state. */ + public static const bool TRACE_ERRORS= false; + /** Internal flag to indicate the debug state. */ + private static const bool TRACE_DOUBLE_CLICK= false; + + /** + * Width constraint for text hovers (in characters). + * @since 3.4 + */ + private static const int TEXT_HOVER_WIDTH_CHARS= 100; //used to be 60 (text font) + /** + * Height constraint for text hovers (in characters). + * @since 3.4 + */ + private static const int TEXT_HOVER_HEIGHT_CHARS= 12; //used to be 10 (text font) + + /** + * Represents a replace command that brings the text viewer's text widget + * back in synchronization with text viewer's document after the document + * has been changed. + */ + protected class WidgetCommand { + + /** The document event encapsulated by this command. */ + public DocumentEvent event; + /** The start of the event. */ + public int start; + /** The length of the event. */ + public int length; + /** The inserted and replaced text segments of event. */ + public String text; + /** The replaced text segments of event. */ + public String preservedText; + + /** + * Translates a document event into the presentation coordinates of this text viewer. + * + * @param e the event to be translated + */ + public void setEvent(DocumentEvent e) { + + event= e; + + start= e.getOffset(); + length= e.getLength(); + text= e.getText(); + + if (length !is 0) { + try { + + if ( cast(SlaveDocumentEvent)e ) { + SlaveDocumentEvent slave= cast(SlaveDocumentEvent) e; + DocumentEvent master= slave.getMasterEvent(); + if (master !is null) + preservedText= master.getDocument().get(master.getOffset(), master.getLength()); + } else { + preservedText= e.getDocument().get(e.getOffset(), e.getLength()); + } + + } catch (BadLocationException x) { + preservedText= null; + if (TRACE_ERRORS) + System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.WidgetCommand.setEvent")); //$NON-NLS-1$ + } + } else + preservedText= null; + } + } + + + /** + * Connects a text double click strategy to this viewer's text widget. + * Calls the double click strategies when the mouse has + * been clicked inside the text editor. + */ + class TextDoubleClickStrategyConnector : MouseAdapter , MovementListener { + + /** Internal flag to remember the last double-click selection. */ + private Point fDoubleClickSelection; + + /* + * @see dwt.events.MouseAdapter#mouseUp(dwt.events.MouseEvent) + * @since 3.2 + */ + public void mouseUp(MouseEvent e) { + fDoubleClickSelection= null; + } + + /* + * @see dwt.custom.MovementListener#getNextOffset(dwt.custom.MovementEvent) + * @since 3.3 + */ + public void getNextOffset(MovementEvent event) { + if (event.movement !is DWT.MOVEMENT_WORD_END) + return; + + if (TRACE_DOUBLE_CLICK) { + System.out_.println("\n+++"); //$NON-NLS-1$ + print(event); + } + + if (fDoubleClickSelection !is null) { + if (fDoubleClickSelection.x <= event.offset && event.offset <= fDoubleClickSelection.y) + event.newOffset= fDoubleClickSelection.y; + } + } + + /* + * @see dwt.custom.MovementListener#getPreviousOffset(dwt.custom.MovementEvent) + * @since 3.3 + */ + public void getPreviousOffset(MovementEvent event) { + if (event.movement !is DWT.MOVEMENT_WORD_START) + return; + + if (TRACE_DOUBLE_CLICK) { + System.out_.println("\n---"); //$NON-NLS-1$ + print(event); + } + if (fDoubleClickSelection is null) { + ITextDoubleClickStrategy s= cast(ITextDoubleClickStrategy) selectContentTypePlugin(getSelectedRange().x, fDoubleClickStrategies); + if (s !is null) { + StyledText textWidget= getTextWidget(); + s.doubleClicked(this.outer); + fDoubleClickSelection= textWidget.getSelection(); + event.newOffset= fDoubleClickSelection.x; + if (TRACE_DOUBLE_CLICK) + System.out_.println(Format("- setting selection: x= {}, y= {}", fDoubleClickSelection.x, fDoubleClickSelection.y)); //$NON-NLS-1$ //$NON-NLS-2$ + } + } else { + if (fDoubleClickSelection.x <= event.offset && event.offset <= fDoubleClickSelection.y) + event.newOffset= fDoubleClickSelection.x; + } + } + } + + /** + * Print trace info about MovementEvent. + * + * @param e the event to print + * @since 3.3 + */ + private void print(MovementEvent e) { + System.out_.println(Format("line offset: {}", e.lineOffset)); //$NON-NLS-1$ + System.out_.println(Format("line: {}", e.lineText)); //$NON-NLS-1$ + System.out_.println(Format("type: {}", e.movement)); //$NON-NLS-1$ + System.out_.println(Format("offset: {}", e.offset)); //$NON-NLS-1$ + System.out_.println(Format("newOffset: {}", e.newOffset)); //$NON-NLS-1$ + } + + /** + * Monitors the area of the viewer's document that is visible in the viewer. + * If the area might have changed, it informs the text viewer about this + * potential change and its origin. The origin is internally used for optimization + * purposes. + */ + class ViewportGuard : MouseAdapter + , ControlListener, KeyListener, SelectionListener { + + /* + * @see ControlListener#controlResized(ControlEvent) + */ + public void controlResized(ControlEvent e) { + updateViewportListeners(RESIZE); + } + + /* + * @see ControlListener#controlMoved(ControlEvent) + */ + public void controlMoved(ControlEvent e) { + } + + /* + * @see KeyListener#keyReleased + */ + public void keyReleased(KeyEvent e) { + updateViewportListeners(KEY); + } + + /* + * @see KeyListener#keyPressed + */ + public void keyPressed(KeyEvent e) { + updateViewportListeners(KEY); + } + + /* + * @see MouseListener#mouseUp + */ + public void mouseUp(MouseEvent e) { + if (fTextWidget !is null) + fTextWidget.removeSelectionListener(this); + updateViewportListeners(MOUSE_END); + } + + /* + * @see MouseListener#mouseDown + */ + public void mouseDown(MouseEvent e) { + if (fTextWidget !is null) + fTextWidget.addSelectionListener(this); + } + + /* + * @see SelectionListener#widgetSelected + */ + public void widgetSelected(SelectionEvent e) { + if (e.widget is fScroller) + updateViewportListeners(SCROLLER); + else + updateViewportListeners(MOUSE); + } + + /* + * @see SelectionListener#widgetDefaultSelected + */ + public void widgetDefaultSelected(SelectionEvent e) {} + } + + /** + * This position updater is used to keep the selection during text shift operations. + */ + static class ShiftPositionUpdater : DefaultPositionUpdater { + + /** + * Creates the position updater for the given category. + * + * @param category the category this updater takes care of + */ + protected this(String category) { + super(category); + } + + /** + * If an insertion happens at the selection's start offset, + * the position is extended rather than shifted. + */ + protected void adaptToInsert() { + + int myStart= fPosition.offset; + int myEnd= fPosition.offset + fPosition.length -1; + myEnd= Math.max(myStart, myEnd); + + int yoursStart= fOffset; + int yoursEnd= fOffset + fReplaceLength -1; + yoursEnd= Math.max(yoursStart, yoursEnd); + + if (myEnd < yoursStart) + return; + + if (myStart <= yoursStart) { + fPosition.length += fReplaceLength; + return; + } + + if (myStart > yoursStart) + fPosition.offset += fReplaceLength; + } + } + + /** + * Internal document listener on the visible document. + */ + class VisibleDocumentListener : IDocumentListener { + + /* + * @see IDocumentListener#documentAboutToBeChanged + */ + public void documentAboutToBeChanged(DocumentEvent e) { + if (e.getDocument() is getVisibleDocument()) + fWidgetCommand.setEvent(e); + handleVisibleDocumentAboutToBeChanged(e); + } + + /* + * @see IDocumentListener#documentChanged + */ + public void documentChanged(DocumentEvent e) { + if (fWidgetCommand.event is e) + updateTextListeners(fWidgetCommand); + fLastSentSelectionChange= null; + handleVisibleDocumentChanged(e); + } + } + + /** + * Internal verify listener. + */ + class TextVerifyListener : VerifyListener { + + /** + * Indicates whether verify events are forwarded or ignored. + * @since 2.0 + */ + private bool fForward= true; + + /** + * Tells the listener to forward received events. + * + * @param forward true if forwarding should be enabled. + * @since 2.0 + */ + public void forward(bool forward) { + fForward= forward; + } + + /* + * @see VerifyListener#verifyText(VerifyEvent) + */ + public void verifyText(VerifyEvent e) { + if (fForward) + handleVerifyEvent(e); + } + } + + /** + * The viewer's manager responsible for registered verify key listeners. + * Uses batches rather than robust iterators because of performance issues. + *

                + * The implementation is reentrant, i.e. installed listeners may trigger + * further VerifyKeyEvents that may cause other listeners to be + * installed, but not thread safe. + *

                + * @since 2.0 + */ + class VerifyKeyListenersManager : VerifyKeyListener { + + /** + * Represents a batched addListener/removeListener command. + */ + class Batch { + /** The index at which to insert the listener. */ + int index; + /** The listener to be inserted. */ + VerifyKeyListener listener; + + /** + * Creates a new batch containing the given listener for the given index. + * + * @param l the listener to be added + * @param i the index at which to insert the listener + */ + public this(VerifyKeyListener l, int i) { + listener= l; + index= i; + } + } + + /** List of registered verify key listeners. */ + private List fListeners; + /** List of pending batches. */ + private List fBatched; + /** The reentrance count. */ + private int fReentranceCount= 0; + + this(){ + fListeners= new ArrayList(); + fBatched= new ArrayList(); + } + + /* + * @see VerifyKeyListener#verifyKey(VerifyEvent) + */ + public void verifyKey(VerifyEvent event) { + if (fListeners.isEmpty()) + return; + + try { + fReentranceCount++; + Iterator iterator= fListeners.iterator(); + while (iterator.hasNext() && event.doit) { + VerifyKeyListener listener= cast(VerifyKeyListener) iterator.next(); + listener.verifyKey(event); // we might trigger reentrant calls on GTK + } + } finally { + fReentranceCount--; + } + if (fReentranceCount is 0) + processBatchedRequests(); + } + + /** + * Processes the pending batched requests. + */ + private void processBatchedRequests() { + if (!fBatched.isEmpty()) { + Iterator e= fBatched.iterator(); + while (e.hasNext()) { + Batch batch= cast(Batch) e.next(); + insertListener(batch.listener, batch.index); + } + fBatched.clear(); + } + } + + /** + * Returns the number of registered verify key listeners. + * + * @return the number of registered verify key listeners + */ + public int numberOfListeners() { + return fListeners.size(); + } + + /** + * Inserts the given listener at the given index or moves it + * to that index. + * + * @param listener the listener to be inserted + * @param index the index of the listener or -1 for remove + */ + public void insertListener(VerifyKeyListener listener, int index) { + + if (index is -1) { + removeListener(listener); + } else if (listener !is null) { + + if (fReentranceCount > 0) { + + fBatched.add(new Batch(listener, index)); + + } else { + + int idx= -1; + + // find index based on identity + int size= fListeners.size(); + for (int i= 0; i < size; i++) { + if (cast(Object)listener is fListeners.get(i)) { + idx= i; + break; + } + } + + // move or add it + if (idx !is index) { + + if (idx !is -1) + fListeners.remove(idx); + + if (index > fListeners.size()) + fListeners.add(cast(Object)listener); + else + fListeners.add(index, cast(Object)listener); + } + + if (size is 0) // checking old size, i.e. current size is size + 1 + install(); + } + } + } + + /** + * Removes the given listener. + * + * @param listener the listener to be removed + */ + public void removeListener(VerifyKeyListener listener) { + if (listener is null) + return; + + if (fReentranceCount > 0) { + + fBatched.add(new Batch(listener, -1)); + + } else { + + int size= fListeners.size(); + for (int i= 0; i < size; i++) { + if (cast(Object)listener is fListeners.get(i)) { + fListeners.remove(i); + if (size is 1) // checking old size, i.e. current size is size - 1 + uninstall(); + return; + } + } + } + } + + /** + * Installs this manager. + */ + private void install() { + StyledText textWidget= getTextWidget(); + if (textWidget !is null && !textWidget.isDisposed()) + textWidget.addVerifyKeyListener(this); + } + + /** + * Uninstalls this manager. + */ + private void uninstall() { + StyledText textWidget= getTextWidget(); + if (textWidget !is null && !textWidget.isDisposed()) + textWidget.removeVerifyKeyListener(this); + } + } + + + /** + * Reification of a range in which a find replace operation is performed. This range is visually + * highlighted in the viewer as long as the replace operation is in progress. + * + * @since 2.0 + */ + class FindReplaceRange : LineBackgroundListener, ITextListener, IPositionUpdater { + + /** Internal name for the position category used to update the range. */ + private const static String RANGE_CATEGORY= "dwtx.jface.text.TextViewer.find.range"; //$NON-NLS-1$ + + /** The highlight color of this range. */ + private Color fHighlightColor; + /** The position used to lively update this range's extent. */ + private Position fPosition; + + /** Creates a new find/replace range with the given extent. + * + * @param range the extent of this range + */ + public this(IRegion range) { + setRange(range); + } + + /** + * Sets the extent of this range. + * + * @param range the extent of this range + */ + public void setRange(IRegion range) { + fPosition= new Position(range.getOffset(), range.getLength()); + } + + /** + * Returns the extent of this range. + * + * @return the extent of this range + */ + public IRegion getRange() { + return new Region(fPosition.getOffset(), fPosition.getLength()); + } + + /** + * Sets the highlight color of this range. Causes the range to be redrawn. + * + * @param color the highlight color + */ + public void setHighlightColor(Color color) { + fHighlightColor= color; + paint(); + } + + /* + * @see LineBackgroundListener#lineGetBackground(LineBackgroundEvent) + * @since 2.0 + */ + public void lineGetBackground(LineBackgroundEvent event) { + /* Don't use cached line information because of patched redrawing events. */ + + if (fTextWidget !is null) { + int offset= widgetOffset2ModelOffset(event.lineOffset); + if (fPosition.includes(offset)) + event.lineBackground= fHighlightColor; + } + } + + /** + * Installs this range. The range registers itself as background + * line painter and text listener. Also, it creates a category with the + * viewer's document to maintain its own extent. + */ + public void install() { + this.outer.addTextListener(this); + fTextWidget.addLineBackgroundListener(this); + + IDocument document= this.outer.getDocument(); + try { + document.addPositionCategory(RANGE_CATEGORY); + document.addPosition(RANGE_CATEGORY, fPosition); + document.addPositionUpdater(this); + } catch (BadPositionCategoryException e) { + // should not happen + } catch (BadLocationException e) { + // should not happen + } + + paint(); + } + + /** + * Uninstalls this range. + * @see #install() + */ + public void uninstall() { + + // http://bugs.eclipse.org/bugs/show_bug.cgi?id=19612 + + IDocument document= this.outer.getDocument(); + if (document !is null) { + document.removePositionUpdater(this); + document.removePosition(fPosition); + } + + if (fTextWidget !is null && !fTextWidget.isDisposed()) + fTextWidget.removeLineBackgroundListener(this); + + this.outer.removeTextListener(this); + + clear(); + } + + /** + * Clears the highlighting of this range. + */ + private void clear() { + if (fTextWidget !is null && !fTextWidget.isDisposed()) + fTextWidget.redraw(); + } + + /** + * Paints the highlighting of this range. + */ + private void paint() { + + IRegion widgetRegion= modelRange2WidgetRange(fPosition); + int offset= widgetRegion.getOffset(); + int length= widgetRegion.getLength(); + + int count= fTextWidget.getCharCount(); + if (offset + length >= count) { + length= count - offset; // clip + + Point upperLeft= fTextWidget.getLocationAtOffset(offset); + Point lowerRight= fTextWidget.getLocationAtOffset(offset + length); + int width= fTextWidget.getClientArea().width; + int height= fTextWidget.getLineHeight(offset + length) + lowerRight.y - upperLeft.y; + fTextWidget.redraw(upperLeft.x, upperLeft.y, width, height, false); + } + + fTextWidget.redrawRange(offset, length, true); + } + + /* + * @see ITextListener#textChanged(TextEvent) + * @since 2.0 + */ + public void textChanged(TextEvent event) { + if (event.getViewerRedrawState()) + paint(); + } + + /* + * @see IPositionUpdater#update(DocumentEvent) + * @since 2.0 + */ + public void update(DocumentEvent event) { + int offset= event.getOffset(); + int length= event.getLength(); + int delta= event.getText().length - length; + + if (offset < fPosition.getOffset()) + fPosition.setOffset(fPosition.getOffset() + delta); + else if (offset < fPosition.getOffset() + fPosition.getLength()) + fPosition.setLength(fPosition.getLength() + delta); + } + } + + /** + * This viewer's find/replace target. + */ + class FindReplaceTarget : IFindReplaceTarget, IFindReplaceTargetExtension, IFindReplaceTargetExtension3 { + + /** The range for this target. */ + private FindReplaceRange fRange; + /** The highlight color of the range of this target. */ + private Color fScopeHighlightColor; + /** The document partitioner remembered in case of a "Replace All". */ + private Map fRememberedPartitioners; + /** + * The active rewrite session. + * @since 3.1 + */ + private DocumentRewriteSession fRewriteSession; + + /* + * @see IFindReplaceTarget#getSelectionText() + */ + public String getSelectionText() { + Point s= this.outer.getSelectedRange(); + if (s.x > -1 && s.y > -1) { + try { + IDocument document= this.outer.getDocument(); + return document.get(s.x, s.y); + } catch (BadLocationException x) { + } + } + return ""; //$NON-NLS-1$ + } + + /* + * @see IFindReplaceTarget#replaceSelection(String) + */ + public void replaceSelection(String text) { + replaceSelection(text, false); + } + + /* + * @see IFindReplaceTarget#replaceSelection(String) + */ + public void replaceSelection(String text, bool regExReplace) { + Point s= this.outer.getSelectedRange(); + if (s.x > -1 && s.y > -1) { + try { + IRegion matchRegion= this.outer.getFindReplaceDocumentAdapter().replace(text, regExReplace); + int length= -1; + if (matchRegion !is null) + length= matchRegion.getLength(); + + if (text !is null && length > 0) + this.outer.setSelectedRange(s.x, length); + } catch (BadLocationException x) { + } + } + } + + /* + * @see IFindReplaceTarget#isEditable() + */ + public bool isEditable() { + return this.outer.isEditable(); + } + + /* + * @see IFindReplaceTarget#getSelection() + */ + public Point getSelection() { + Point modelSelection= this.outer.getSelectedRange(); + Point widgetSelection= modelSelection2WidgetSelection(modelSelection); + return widgetSelection !is null ? widgetSelection : new Point(-1, -1); + } + + /* + * @see IFindReplaceTarget#findAndSelect(int, String, bool, bool, bool) + */ + public int findAndSelect(int widgetOffset, String findString, bool searchForward, bool caseSensitive, bool wholeWord) { + try { + return findAndSelect(widgetOffset, findString, searchForward, caseSensitive, wholeWord, false); + } catch (PatternSyntaxException x) { + return -1; + } + } + + /* + * @see IFindReplaceTarget#findAndSelect(int, String, bool, bool, bool) + */ + public int findAndSelect(int widgetOffset, String findString, bool searchForward, bool caseSensitive, bool wholeWord, bool regExSearch) { + + int modelOffset= widgetOffset is -1 ? -1 : widgetOffset2ModelOffset(widgetOffset); + + if (fRange !is null) { + IRegion range= fRange.getRange(); + modelOffset= this.outer.findAndSelectInRange(modelOffset, findString, searchForward, caseSensitive, wholeWord, range.getOffset(), range.getLength(), regExSearch); + } else { + modelOffset= this.outer.findAndSelect(modelOffset, findString, searchForward, caseSensitive, wholeWord, regExSearch); + } + + widgetOffset= modelOffset is -1 ? -1 : modelOffset2WidgetOffset(modelOffset); + return widgetOffset; + } + + /* + * @see IFindReplaceTarget#canPerformFind() + */ + public bool canPerformFind() { + return this.outer.canPerformFind(); + } + + /* + * @see IFindReplaceTargetExtension#beginSession() + * @since 2.0 + */ + public void beginSession() { + fRange= null; + } + + /* + * @see IFindReplaceTargetExtension#endSession() + * @since 2.0 + */ + public void endSession() { + if (fRange !is null) { + fRange.uninstall(); + fRange= null; + } + } + + /* + * @see IFindReplaceTargetExtension#getScope() + * @since 2.0 + */ + public IRegion getScope() { + return fRange is null ? null : fRange.getRange(); + } + + /* + * @see IFindReplaceTargetExtension#getLineSelection() + * @since 2.0 + */ + public Point getLineSelection() { + Point point= this.outer.getSelectedRange(); + + try { + IDocument document= this.outer.getDocument(); + + // beginning of line + int line= document.getLineOfOffset(point.x); + int offset= document.getLineOffset(line); + + // end of line + IRegion lastLineInfo= document.getLineInformationOfOffset(point.x + point.y); + int lastLine= document.getLineOfOffset(point.x + point.y); + int length; + if (lastLineInfo.getOffset() is point.x + point.y && lastLine > 0) + length= document.getLineOffset(lastLine - 1) + document.getLineLength(lastLine - 1) - offset; + else + length= lastLineInfo.getOffset() + lastLineInfo.getLength() - offset; + + return new Point(offset, length); + + } catch (BadLocationException e) { + // should not happen + return new Point(point.x, 0); + } + } + + /* + * @see IFindReplaceTargetExtension#setSelection(int, int) + * @since 2.0 + */ + public void setSelection(int modelOffset, int modelLength) { + this.outer.setSelectedRange(modelOffset, modelLength); + } + + /* + * @see IFindReplaceTargetExtension#setScope(IRegion) + * @since 2.0 + */ + public void setScope(IRegion scope_) { + if (fRange !is null) + fRange.uninstall(); + + if (scope_ is null) { + fRange= null; + return; + } + + fRange= new FindReplaceRange(scope_); + fRange.setHighlightColor(fScopeHighlightColor); + fRange.install(); + } + + /* + * @see IFindReplaceTargetExtension#setScopeHighlightColor(Color) + * @since 2.0 + */ + public void setScopeHighlightColor(Color color) { + if (fRange !is null) + fRange.setHighlightColor(color); + fScopeHighlightColor= color; + } + + /* + * @see IFindReplaceTargetExtension#setReplaceAllMode(bool) + * @since 2.0 + */ + public void setReplaceAllMode(bool replaceAll) { + + // http://bugs.eclipse.org/bugs/show_bug.cgi?id=18232 + + IDocument document= this.outer.getDocument(); + + if (replaceAll) { + + if ( cast(IDocumentExtension4)document ) { + IDocumentExtension4 extension= cast(IDocumentExtension4) document; + fRewriteSession= extension.startRewriteSession(DocumentRewriteSessionType.SEQUENTIAL); + } else { + this.outer.setRedraw(false); + this.outer.startSequentialRewriteMode(false); + + if (fUndoManager !is null) + fUndoManager.beginCompoundChange(); + + fRememberedPartitioners= TextUtilities.removeDocumentPartitioners(document); + } + + } else { + + if ( cast(IDocumentExtension4)document ) { + IDocumentExtension4 extension= cast(IDocumentExtension4) document; + extension.stopRewriteSession(fRewriteSession); + } else { + this.outer.setRedraw(true); + this.outer.stopSequentialRewriteMode(); + + if (fUndoManager !is null) + fUndoManager.endCompoundChange(); + + if (fRememberedPartitioners !is null) + TextUtilities.addDocumentPartitioners(document, fRememberedPartitioners); + } + } + } + } + + + /** + * The viewer's rewrite target. + * @since 2.0 + */ + class RewriteTarget : IRewriteTarget { + + /* + * @see dwtx.jface.text.IRewriteTarget#beginCompoundChange() + */ + public void beginCompoundChange() { + if (fUndoManager !is null) + fUndoManager.beginCompoundChange(); + } + + /* + * @see dwtx.jface.text.IRewriteTarget#endCompoundChange() + */ + public void endCompoundChange() { + if (fUndoManager !is null) + fUndoManager.endCompoundChange(); + } + + /* + * @see dwtx.jface.text.IRewriteTarget#getDocument() + */ + public IDocument getDocument() { + return this.outer.getDocument(); + } + + /* + * @see dwtx.jface.text.IRewriteTarget#setRedraw(bool) + */ + public void setRedraw(bool redraw) { + this.outer.setRedraw(redraw); + } + } + + /** + * Value object used as key in the text hover configuration table. It is + * modifiable only inside this compilation unit to allow the reuse of created + * objects for efficiency reasons + * + * @since 2.1 + */ + protected class TextHoverKey { + + /** The content type this key belongs to */ + private String fContentType; + /** The state mask */ + private int fStateMask; + + /** + * Creates a new text hover key for the given content type and state mask. + * + * @param contentType the content type + * @param stateMask the state mask + */ + protected this(String contentType, int stateMask) { + //Assert.isNotNull(contentType); + fContentType= contentType; + fStateMask= stateMask; + } + + /* + * @see java.lang.Object#equals(java.lang.Object) + */ + public override int opEquals(Object obj) { + if (obj is null || obj.classinfo !is this.classinfo ) + return false; + TextHoverKey textHoverKey= cast(TextHoverKey)obj; + return textHoverKey.fContentType.equals(fContentType) && textHoverKey.fStateMask is fStateMask; + } + + /* + * @see java.lang.Object#hashCode() + */ + public override hash_t toHash() { + return fStateMask << 16 | .toHash(fContentType); + } + + /** + * Sets the state mask of this text hover key. + * + * @param stateMask the state mask + */ + private void setStateMask(int stateMask) { + fStateMask= stateMask; + } + } + + /** + * Captures and remembers the viewer state (selection and visual position). {@link TextViewer.ViewerState} + * instances are normally used once and then discarded, similar to the following snippet: + *
                +     * ViewerState state= new ViewerState(); // remember the state
                +     * doStuff(); // operation that may call setRedraw() and perform complex document modifications
                +     * state.restore(true); // restore the remembered state
                +     * 
                + * + * @since 3.3 + */ + private final class ViewerState { + /** The position tracking the selection. */ + private Position fSelection; + /** true if {@link #fSelection} was originally backwards. */ + private bool fReverseSelection; + /** true if the selection has been updated while in redraw(off) mode. */ + private bool fSelectionSet; + /** The position tracking the visually stable line. */ + private Position fStableLine; + /** The pixel offset of the stable line measured from the client area. */ + private int fStablePixel; + + /** The position updater for {@link #fSelection} and {@link #fStableLine}. */ + private IPositionUpdater fUpdater; + /** The document that the position updater and the positions are registered with. */ + private IDocument fUpdaterDocument; + /** The position category used by {@link #fUpdater}. */ + private String fUpdaterCategory; + + /** + * Creates a new viewer state instance and connects it to the current document. + */ + public this() { + IDocument document= getDocument(); + if (document !is null) + connect(document); + } + + /** + * Returns the normalized selection, i.e. the the selection length is always non-negative. + * + * @return the normalized selection + */ + public Point getSelection() { + if (fSelection is null) + return new Point(-1, -1); + return new Point(fSelection.getOffset(), fSelection.getLength()); + } + + /** + * Updates the selection. + * + * @param offset the new selection offset + * @param length the new selection length + */ + public void updateSelection(int offset, int length) { + fSelectionSet= true; + if (fSelection is null) + fSelection= new Position(offset, length); + else + updatePosition(fSelection, offset, length); + } + + /** + * Restores the state and disconnects it from the document. The selection is no longer + * tracked after this call. + * + * @param restoreViewport true to restore both selection and viewport, + * false to only restore the selection + */ + public void restore(bool restoreViewport) { + if (isConnected()) + disconnect(); + if (fSelection !is null) { + int offset= fSelection.getOffset(); + int length= fSelection.getLength(); + if (fReverseSelection) { + offset-= length; + length= -length; + } + setSelectedRange(offset, length); + if (restoreViewport) + updateViewport(); + } + } + + /** + * Updates the viewport, trying to keep the + * {@linkplain StyledText#getLinePixel(int) line pixel} of the caret line stable. If the + * selection has been updated while in redraw(false) mode, the new selection is revealed. + */ + private void updateViewport() { + if (fSelectionSet) { + revealRange(fSelection.getOffset(), fSelection.getLength()); + } else if (fStableLine !is null) { + int stableLine; + try { + stableLine= fUpdaterDocument.getLineOfOffset(fStableLine.getOffset()); + } catch (BadLocationException x) { + // ignore and return silently + return; + } + int stableWidgetLine= getClosestWidgetLineForModelLine(stableLine); + if (stableWidgetLine is -1) + return; + int linePixel= getTextWidget().getLinePixel(stableWidgetLine); + int delta= fStablePixel - linePixel; + int topPixel= getTextWidget().getTopPixel(); + getTextWidget().setTopPixel(topPixel - delta); + } + } + + /** + * Remembers the viewer state. + * + * @param document the document to remember the state of + */ + private void connect(IDocument document) { + Assert.isLegal(document !is null); + Assert.isLegal(!isConnected()); + fUpdaterDocument= document; + try { + fUpdaterCategory= SELECTION_POSITION_CATEGORY ~ Integer.toString(toHash()); + fUpdater= new NonDeletingPositionUpdater(fUpdaterCategory); + fUpdaterDocument.addPositionCategory(fUpdaterCategory); + fUpdaterDocument.addPositionUpdater(fUpdater); + + Point selectionRange= getSelectedRange(); + fReverseSelection= selectionRange.y < 0; + int offset, length; + if (fReverseSelection) { + offset= selectionRange.x + selectionRange.y; + length= -selectionRange.y; + } else { + offset= selectionRange.x; + length= selectionRange.y; + } + + fSelection= new Position(offset, length); + fSelectionSet= false; + fUpdaterDocument.addPosition(fUpdaterCategory, fSelection); + + int stableLine= getStableLine(); + int stableWidgetLine= modelLine2WidgetLine(stableLine); + fStablePixel= getTextWidget().getLinePixel(stableWidgetLine); + IRegion stableLineInfo= fUpdaterDocument.getLineInformation(stableLine); + fStableLine= new Position(stableLineInfo.getOffset(), stableLineInfo.getLength()); + fUpdaterDocument.addPosition(fUpdaterCategory, fStableLine); + } catch (BadPositionCategoryException e) { + // cannot happen + Assert.isTrue(false); + } catch (BadLocationException e) { + // should not happen except on concurrent modification + // ignore and disconnect + disconnect(); + } + } + + /** + * Updates a position with the given information and clears its deletion state. + * + * @param position the position to update + * @param offset the new selection offset + * @param length the new selection length + */ + private void updatePosition(Position position, int offset, int length) { + position.setOffset(offset); + position.setLength(length); + // http://bugs.eclipse.org/bugs/show_bug.cgi?id=32795 + position.isDeleted_= false; + } + + /** + * Returns the document line to keep visually stable. If the caret line is (partially) + * visible, it is returned, otherwise the topmost (partially) visible line is returned. + * + * @return the visually stable line of this viewer state + */ + private int getStableLine() { + int stableLine; // the model line that we try to keep stable + int caretLine= getTextWidget().getLineAtOffset(getTextWidget().getCaretOffset()); + if (caretLine < JFaceTextUtil.getPartialTopIndex(getTextWidget()) || caretLine > JFaceTextUtil.getPartialBottomIndex(getTextWidget())) { + stableLine= JFaceTextUtil.getPartialTopIndex(this.outer); + } else { + stableLine= widgetLine2ModelLine(caretLine); + } + return stableLine; + } + + /** + * Returns true if the viewer state is being tracked, false + * otherwise. + * + * @return the tracking state + */ + private bool isConnected() { + return fUpdater !is null; + } + + /** + * Disconnects from the document. + */ + private void disconnect() { + Assert.isTrue(isConnected()); + try { + fUpdaterDocument.removePosition(fUpdaterCategory, fSelection); + fUpdaterDocument.removePosition(fUpdaterCategory, fStableLine); + fUpdaterDocument.removePositionUpdater(fUpdater); + fUpdater= null; + fUpdaterDocument.removePositionCategory(fUpdaterCategory); + fUpdaterCategory= null; + } catch (BadPositionCategoryException x) { + // cannot happen + Assert.isTrue(false); + } + } + } + + /** + * Internal cursor listener i.e. aggregation of mouse and key listener. + * + * @since 3.0 + */ + private class CursorListener : KeyListener, MouseListener { + + /** + * Installs this cursor listener. + */ + private void install() { + if (fTextWidget !is null && !fTextWidget.isDisposed()) { + fTextWidget.addKeyListener(this); + fTextWidget.addMouseListener(this); + } + } + + /** + * Uninstalls this cursor listener. + */ + private void uninstall() { + if (fTextWidget !is null && !fTextWidget.isDisposed()) { + fTextWidget.removeKeyListener(this); + fTextWidget.removeMouseListener(this); + } + } + + /* + * @see KeyListener#keyPressed(dwt.events.KeyEvent) + */ + public void keyPressed(KeyEvent event) { + } + + /* + * @see KeyListener#keyPressed(dwt.events.KeyEvent) + */ + public void keyReleased(KeyEvent e) { + if (fTextWidget.getSelectionCount() is 0) { + fLastSentSelectionChange= null; + queuePostSelectionChanged(e.character is DWT.DEL); + } + } + + /* + * @see MouseListener#mouseDoubleClick(dwt.events.MouseEvent) + */ + public void mouseDoubleClick(MouseEvent e) { + } + + /* + * @see MouseListener#mouseDown(dwt.events.MouseEvent) + */ + public void mouseDown(MouseEvent e) { + } + + /* + * @see MouseListener#mouseUp(dwt.events.MouseEvent) + */ + public void mouseUp(MouseEvent event) { + if (fTextWidget.getSelectionCount() is 0) + queuePostSelectionChanged(false); + } + } + + /** + * Internal listener to document rewrite session state changes. + * @since 3.1 + */ + private class DocumentRewriteSessionListener : IDocumentRewriteSessionListener { + + /* + * @see dwtx.jface.text.IDocumentRewriteSessionListener#documentRewriteSessionChanged(dwtx.jface.text.DocumentRewriteSessionEvent) + */ + public void documentRewriteSessionChanged(DocumentRewriteSessionEvent event) { + IRewriteTarget target= this.outer.getRewriteTarget(); + // FIXME always use setRedraw to avoid flickering due to scrolling + // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=158746 + bool toggleRedraw= true || event.getSession().getSessionType() !is DocumentRewriteSessionType.UNRESTRICTED_SMALL; + final bool viewportStabilize= !toggleRedraw; + if (DocumentRewriteSessionEvent.SESSION_START is event.getChangeType()) { + if (toggleRedraw) + target.setRedraw(false); + target.beginCompoundChange(); + if (viewportStabilize && fViewerState is null) + fViewerState= new ViewerState(); + } else if (DocumentRewriteSessionEvent.SESSION_STOP is event.getChangeType()) { + if (viewportStabilize && fViewerState !is null) { + fViewerState.restore(true); + fViewerState= null; + } + target.endCompoundChange(); + if (toggleRedraw) + target.setRedraw(true); + } + } + } + + + /** + * Identifies the scrollbars as originators of a view port change. + */ + protected static final int SCROLLER= 1; + /** + * Identifies mouse moves as originators of a view port change. + */ + protected static final int MOUSE= 2; + /** + * Identifies mouse button up as originator of a view port change. + */ + protected static final int MOUSE_END= 3; + /** + * Identifies key strokes as originators of a view port change. + */ + protected static final int KEY= 4; + /** + * Identifies window resizing as originator of a view port change. + */ + protected static final int RESIZE= 5; + /** + * Identifies internal reasons as originators of a view port change. + */ + protected static final int INTERNAL= 6; + + /** Internal name of the position category used selection preservation during shift. */ + protected static final String SHIFTING= "__TextViewer_shifting"; //$NON-NLS-1$ + + /** + * Base position category name used by the selection updater + * @since 3.1 + */ + private static const String SELECTION_POSITION_CATEGORY= "_textviewer_selection_category"; //$NON-NLS-1$ + /** The viewer's text widget */ + private StyledText fTextWidget; + /** The viewer's input document */ + private IDocument fDocument; + /** The viewer's visible document */ + private IDocument fVisibleDocument; + /** The viewer's document adapter */ + private IDocumentAdapter fDocumentAdapter; + /** The slave document manager */ + private ISlaveDocumentManager fSlaveDocumentManager; + /** The text viewer's double click strategies connector */ + private TextDoubleClickStrategyConnector fDoubleClickStrategyConnector; + /** The text viewer's view port guard */ + private ViewportGuard fViewportGuard; + /** Caches the graphical coordinate of the first visible line */ + private int fTopInset= 0; + /** The most recent document modification as widget command */ + private WidgetCommand fWidgetCommand; + /** The DWT control's scrollbars */ + private ScrollBar fScroller; + /** Listener on the visible document */ + private VisibleDocumentListener fVisibleDocumentListener; + /** Verify listener */ + private TextVerifyListener fVerifyListener; + /** The most recent widget modification as document command */ + private DocumentCommand fDocumentCommand; + /** The viewer's find/replace target */ + private IFindReplaceTarget fFindReplaceTarget; + /** + * The text viewer's hovering controller + * @since 2.0 + */ + private TextViewerHoverManager fTextHoverManager; + /** + * The viewer widget token keeper + * @since 2.0 + */ + private IWidgetTokenKeeper fWidgetTokenKeeper; + /** + * The viewer's manager of verify key listeners + * @since 2.0 + */ + private VerifyKeyListenersManager fVerifyKeyListenersManager; + /** + * The mark position. + * @since 2.0 + */ + protected Position fMarkPosition; + /** + * The mark position category. + * @since 2.0 + */ + private /+const+/ String MARK_POSITION_CATEGORY; + /** + * The mark position updater + * @since 2.0 + */ + private /+const+/ IPositionUpdater fMarkPositionUpdater; + /** + * The flag indicating the redraw behavior + * @since 2.0 + */ + private int fRedrawCounter= 0; + /** + * The viewer's rewrite target + * @since 2.0 + */ + private IRewriteTarget fRewriteTarget; + /** + * The viewer's cursor listener. + * @since 3.0 + */ + private CursorListener fCursorListener; + /** + * Last selection range sent to selection change listeners. + * @since 3.0 + */ + private IRegion fLastSentSelectionChange; + /** + * The registered post selection changed listeners. + * @since 3.0 + */ + private List fPostSelectionChangedListeners; + /** + * Queued post selection changed events count. + * @since 3.0 + */ + private /+const+/ int[] fNumberOfPostSelectionChangedEvents; + /** + * Last selection range sent to post selection change listeners. + * @since 3.0 + */ + private IRegion fLastSentPostSelectionChange; + /** + * The set of registered editor helpers. + * @since 3.1 + */ + private Set fEditorHelpers; + /** + * The internal rewrite session listener. + * @since 3.1 + */ + private DocumentRewriteSessionListener fDocumentRewriteSessionListener; + + /** Should the auto indent strategies ignore the next edit operation */ + protected bool fIgnoreAutoIndent= false; + /** The strings a line is prefixed with on SHIFT_RIGHT and removed from each line on SHIFT_LEFT */ + protected Map fIndentChars; + /** The string a line is prefixed with on PREFIX and removed from each line on STRIP_PREFIX */ + protected Map fDefaultPrefixChars; + /** The text viewer's text double click strategies */ + protected Map fDoubleClickStrategies; + /** The text viewer's undo manager */ + protected IUndoManager fUndoManager; + /** The text viewer's auto indent strategies */ + protected Map fAutoIndentStrategies; + /** The text viewer's text hovers */ + protected Map fTextHovers; + /** All registered view port listeners> */ + protected List fViewportListeners; + /** The last visible vertical position of the top line */ + protected int fLastTopPixel; + /** All registered text listeners */ + protected List fTextListeners; + /** All registered text input listeners */ + protected List fTextInputListeners; + /** The text viewer's event consumer */ + protected IEventConsumer fEventConsumer; + /** Indicates whether the viewer's text presentation should be replaced are modified. */ + protected bool fReplaceTextPresentation= false; + /** + * The creator of the text hover control + * @since 2.0 + */ + protected IInformationControlCreator fHoverControlCreator; + /** + * The mapping between model and visible document. + * @since 2.1 + */ + protected IDocumentInformationMapping fInformationMapping; + /** + * The viewer's paint manager. + * @since 2.1 + */ + protected PaintManager fPaintManager; + /** + * The viewers partitioning. I.e. the partitioning name the viewer uses to access partitioning information of its input document. + * @since 3.0 + */ + protected String fPartitioning; + /** + * All registered text presentation listeners. + * since 3.0 + */ + protected List fTextPresentationListeners; + /** + * The find/replace document adapter. + * @since 3.0 + */ + protected FindReplaceDocumentAdapter fFindReplaceDocumentAdapter; + + /** + * The text viewer's hyperlink detectors. + * @since 3.1 + */ + protected IHyperlinkDetector[] fHyperlinkDetectors; + /** + * The text viewer's hyperlink presenter. + * @since 3.1 + */ + protected IHyperlinkPresenter fHyperlinkPresenter; + /** + * The text viewer's hyperlink manager. + * @since 3.1 + */ + protected HyperlinkManager fHyperlinkManager; + /** + * The DWT key modifier mask which in combination + * with the left mouse button triggers the hyperlink mode. + * @since 3.1 + */ + protected int fHyperlinkStateMask; + /** + * The viewer state when in non-redraw state, null otherwise. + * @since 3.3 + */ + private ViewerState fViewerState; + /** + * The editor's tab converter. + * @since 3.3 + */ + private IAutoEditStrategy fTabsToSpacesConverter; + + + //---- Construction and disposal ------------------ + + private void instanceInit(){ + fWidgetCommand= new WidgetCommand(); + fVisibleDocumentListener= new VisibleDocumentListener(); + fVerifyListener= new TextVerifyListener(); + fDocumentCommand= new DocumentCommand(); + fVerifyKeyListenersManager= new VerifyKeyListenersManager(); + MARK_POSITION_CATEGORY=Format("__mark_category_{}", toHash()); //$NON-NLS-1$ + fMarkPositionUpdater= new DefaultPositionUpdater(MARK_POSITION_CATEGORY); + fDocumentRewriteSessionListener= new DocumentRewriteSessionListener(); + fNumberOfPostSelectionChangedEvents= new int[1]; + fEditorHelpers= new HashSet(); + } + /** + * Internal use only + */ + protected this() { + instanceInit(); + } + + /** + * Create a new text viewer with the given DWT style bits. + * The viewer is ready to use but does not have any plug-in installed. + * + * @param parent the parent of the viewer's control + * @param styles the DWT style bits for the viewer's control, + * if DWT.WRAP is set then a custom document adapter needs to be provided, see {@link #createDocumentAdapter()} + */ + public this(Composite parent, int styles) { + instanceInit(); + createControl(parent, styles); + } + + /** + * Factory method to create the text widget to be used as the viewer's text widget. + * + * @param parent the parent of the styled text + * @param styles the styles for the styled text + * @return the text widget to be used + */ + protected StyledText createTextWidget(Composite parent, int styles) { + return new StyledText(parent, styles); + } + + /** + * Factory method to create the document adapter to be used by this viewer. + * + * @return the document adapter to be used + */ + protected IDocumentAdapter createDocumentAdapter() { + return new DefaultDocumentAdapter(); + } + + /** + * Creates the viewer's DWT control. The viewer's text widget either is + * the control or is a child of the control. + * + * @param parent the parent of the viewer's control + * @param styles the DWT style bits for the viewer's control + */ + protected void createControl(Composite parent, int styles) { + + fTextWidget= createTextWidget(parent, styles); + + // Support scroll page upon MOD1+MouseWheel + fTextWidget.addListener(DWT.MouseWheel, new class() Listener { + + public void handleEvent(Event event) { + if (((event.stateMask & DWT.MOD1) is 0)) + return; + + int topIndex= fTextWidget.getTopIndex(); + int bottomIndex= JFaceTextUtil.getBottomIndex(fTextWidget); + + if (event.count > 0) + fTextWidget.setTopIndex(2 * topIndex - bottomIndex); + else + fTextWidget.setTopIndex(bottomIndex); + + updateViewportListeners(INTERNAL); + } + }); + + fTextWidget.addDisposeListener( + new class() DisposeListener { + public void widgetDisposed(DisposeEvent e) { + handleDispose(); + } + } + ); + + fTextWidget.setFont(parent.getFont()); + fTextWidget.setDoubleClickEnabled(true); + + /* + * Disable DWT Shift+TAB traversal in this viewer + * 1GIYQ9K: ITPUI:WINNT - StyledText swallows Shift+TAB + */ + fTextWidget.addTraverseListener(new class() TraverseListener { + public void keyTraversed(TraverseEvent e) { + if ((DWT.SHIFT is e.stateMask) && ('\t' is e.character)) + e.doit= false; + } + }); + + // where does the first line start + fTopInset= -fTextWidget.computeTrim(0, 0, 0, 0).y; + + fVerifyListener.forward(true); + fTextWidget.addVerifyListener(fVerifyListener); + + fTextWidget.addSelectionListener(new class() SelectionListener { + public void widgetDefaultSelected(SelectionEvent event) { + selectionChanged(event.x, event.y - event.x); + } + public void widgetSelected(SelectionEvent event) { + selectionChanged(event.x, event.y - event.x); + } + }); + + fCursorListener= new CursorListener(); + fCursorListener.install(); + + initializeViewportUpdate(); + } + + /* + * @see Viewer#getControl() + */ + public Control getControl() { + return fTextWidget; + } + + /* + * @see ITextViewer#activatePlugins() + */ + public void activatePlugins() { + + if (fDoubleClickStrategies !is null && !fDoubleClickStrategies.isEmpty() && fDoubleClickStrategyConnector is null) { + fDoubleClickStrategyConnector= new TextDoubleClickStrategyConnector(); + fTextWidget.addWordMovementListener(fDoubleClickStrategyConnector); + fTextWidget.addMouseListener(fDoubleClickStrategyConnector); + } + + ensureHoverControlManagerInstalled(); + ensureHyperlinkManagerInstalled(); + + if (fUndoManager !is null) { + fUndoManager.connect(this); + fUndoManager.reset(); + } + } + + /** + * After this method has been executed the caller knows that any installed text hover has been installed. + */ + private void ensureHoverControlManagerInstalled() { + if (fTextHovers !is null && !fTextHovers.isEmpty() && fHoverControlCreator !is null && fTextHoverManager is null) { + fTextHoverManager= new TextViewerHoverManager(this, fHoverControlCreator); + fTextHoverManager.install(this.getTextWidget()); + fTextHoverManager.setSizeConstraints(TEXT_HOVER_WIDTH_CHARS, TEXT_HOVER_HEIGHT_CHARS, false, true); + fTextHoverManager.setInformationControlReplacer(new StickyHoverManager(this)); + } + } + + /* + * @see ITextViewer#resetPlugins() + */ + public void resetPlugins() { + if (fUndoManager !is null) + fUndoManager.reset(); + } + + /** + * Frees all resources allocated by this viewer. Internally called when the viewer's + * control has been disposed. + */ + protected void handleDispose() { + + setDocument(null); + + if (fPaintManager !is null) { + fPaintManager.dispose(); + fPaintManager= null; + } + + removeViewPortUpdate(); + fViewportGuard= null; + + if (fViewportListeners !is null) { + fViewportListeners.clear(); + fViewportListeners= null; + } + + if (fTextListeners !is null) { + fTextListeners.clear(); + fTextListeners= null; + } + + if (fTextInputListeners !is null) { + fTextInputListeners.clear(); + fTextInputListeners= null; + } + + if (fPostSelectionChangedListeners !is null) { + fPostSelectionChangedListeners.clear(); + fPostSelectionChangedListeners= null; + } + + if (fAutoIndentStrategies !is null) { + fAutoIndentStrategies.clear(); + fAutoIndentStrategies= null; + } + + if (fUndoManager !is null) { + fUndoManager.disconnect(); + fUndoManager= null; + } + + if (fDoubleClickStrategies !is null) { + fDoubleClickStrategies.clear(); + fDoubleClickStrategies= null; + } + + if (fTextHovers !is null) { + fTextHovers.clear(); + fTextHovers= null; + } + + fDoubleClickStrategyConnector= null; + + if (fTextHoverManager !is null) { + fTextHoverManager.dispose(); + fTextHoverManager= null; + } + + if (fVisibleDocumentListener !is null) { + if (fVisibleDocument !is null) + fVisibleDocument.removeDocumentListener(fVisibleDocumentListener); + fVisibleDocumentListener= null; + } + + if (fDocumentAdapter !is null) { + fDocumentAdapter.setDocument(null); + fDocumentAdapter= null; + } + + if (fSlaveDocumentManager !is null) { + if (fVisibleDocument !is null) + fSlaveDocumentManager.freeSlaveDocument(fVisibleDocument); + fSlaveDocumentManager= null; + } + + if (fCursorListener !is null) { + fCursorListener.uninstall(); + fCursorListener= null; + } + + if (fHyperlinkManager !is null) { + fHyperlinkManager.uninstall(); + fHyperlinkManager= null; + } + + fHyperlinkDetectors= null; + fVisibleDocument= null; + fDocument= null; + fScroller= null; + + fTextWidget= null; + } + + + //---- simple getters and setters + + /* + * @see dwtx.jface.text.ITextViewer#getTextWidget() + */ + public StyledText getTextWidget() { + return fTextWidget; + } + + /** + * The delay in milliseconds before an empty selection + * changed event is sent by the cursor listener. + *

                + * Note: The return value is used to initialize the cursor + * listener. To return a non-constant value has no effect.

                + *

                + * The same value (500) is used in OpenStrategy.TIME.

                + * + * @return delay in milliseconds + * @see dwtx.jface.util.OpenStrategy + * @since 3.0 + */ + protected int getEmptySelectionChangedEventDelay() { + return 500; + } + + /** + * {@inheritDoc} + * @deprecated since 3.1, use + * {@link ITextViewerExtension2#prependAutoEditStrategy(IAutoEditStrategy, String)} and + * {@link ITextViewerExtension2#removeAutoEditStrategy(IAutoEditStrategy, String)} instead + */ + public void setAutoIndentStrategy(IAutoIndentStrategy strategy, String contentType) { + setAutoEditStrategies([ strategy ], contentType); + } + + /** + * Sets the given edit strategy as the only strategy for the given content type. + * + * @param strategies the auto edit strategies + * @param contentType the content type + * @since 3.1 + */ + protected final void setAutoEditStrategies(IAutoEditStrategy[] strategies, String contentType) { + if (fAutoIndentStrategies is null) + fAutoIndentStrategies= new HashMap(); + + List autoEditStrategies= cast(List) fAutoIndentStrategies.get(contentType); + + if (strategies is null) { + if (autoEditStrategies is null) + return; + + fAutoIndentStrategies.put(contentType, cast(Object)null); + + } else { + if (autoEditStrategies is null) { + autoEditStrategies= new ArrayList(); + fAutoIndentStrategies.put(contentType, cast(Object)autoEditStrategies); + } + + autoEditStrategies.clear(); + autoEditStrategies.addAll(Arrays.asList(arraycast!(Object)(strategies))); + } + } + + /* + * @see dwtx.jface.text.ITextViewerExtension2#prependAutoEditStrategy(dwtx.jface.text.IAutoEditStrategy, java.lang.String) + * @since 2.1 + */ + public void prependAutoEditStrategy(IAutoEditStrategy strategy, String contentType) { + + if (strategy is null || contentType is null) + throw new IllegalArgumentException(""); + + if (fAutoIndentStrategies is null) + fAutoIndentStrategies= new HashMap(); + + List autoEditStrategies= cast(List) fAutoIndentStrategies.get(contentType); + if (autoEditStrategies is null) { + autoEditStrategies= new ArrayList(); + fAutoIndentStrategies.put(contentType,cast(Object) autoEditStrategies); + } + + autoEditStrategies.add(0, cast(Object)strategy); + } + + /* + * @see dwtx.jface.text.ITextViewerExtension2#removeAutoEditStrategy(dwtx.jface.text.IAutoEditStrategy, java.lang.String) + * @since 2.1 + */ + public void removeAutoEditStrategy(IAutoEditStrategy strategy, String contentType) { + if (fAutoIndentStrategies is null) + return; + + List autoEditStrategies= cast(List) fAutoIndentStrategies.get(contentType); + if (autoEditStrategies is null) + return; + + for (final Iterator iterator= autoEditStrategies.iterator(); iterator.hasNext(); ) { + if (iterator.next().opEquals(cast(Object)strategy)) { + iterator.remove(); + break; + } + } + + if (autoEditStrategies.isEmpty()) + fAutoIndentStrategies.put(contentType, cast(Object)null); + } + + /* + * @see ITextViewer#setEventConsumer(IEventConsumer) + */ + public void setEventConsumer(IEventConsumer consumer) { + fEventConsumer= consumer; + } + + /* + * @see ITextViewer#setIndentPrefixes(String[], String) + */ + public void setIndentPrefixes(String[] indentPrefixes, String contentType) { + + int i= -1; + bool ok= (indentPrefixes !is null); + while (ok && ++i < indentPrefixes.length) + ok= (indentPrefixes[i] !is null); + + if (ok) { + + if (fIndentChars is null) + fIndentChars= new HashMap(); + + fIndentChars.put(contentType, new ArrayWrapperObject( stringcast(indentPrefixes))); + + } else if (fIndentChars !is null) + fIndentChars.remove(contentType); + } + + /* + * @see ITextViewer#getTopInset() + */ + public int getTopInset() { + return fTopInset; + } + + /* + * @see ITextViewer#isEditable() + */ + public bool isEditable() { + if (fTextWidget is null) + return false; + return fTextWidget.getEditable(); + } + + /* + * @see ITextViewer#setEditable(bool) + */ + public void setEditable(bool editable) { + if (fTextWidget !is null) + fTextWidget.setEditable(editable); + } + + /* + * @see ITextViewer#setDefaultPrefixes + * @since 2.0 + */ + public void setDefaultPrefixes(String[] defaultPrefixes, String contentType) { + + if (defaultPrefixes !is null && defaultPrefixes.length > 0) { + if (fDefaultPrefixChars is null) + fDefaultPrefixChars= new HashMap(); + fDefaultPrefixChars.put(contentType, new ArrayWrapperObject( stringcast(defaultPrefixes))); + } else if (fDefaultPrefixChars !is null) + fDefaultPrefixChars.remove(contentType); + } + + /* + * @see ITextViewer#setUndoManager(IUndoManager) + */ + public void setUndoManager(IUndoManager undoManager) { + fUndoManager= undoManager; + } + + /* + * @see ITextViewerExtension6#getUndoManager() + * @since 3.1 + */ + public IUndoManager getUndoManager() { + return fUndoManager; + } + + /* + * @see ITextViewer#setTextHover(ITextHover, String) + */ + public void setTextHover(ITextHover hover, String contentType) { + setTextHover(hover, contentType, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK); + } + + /* + * @see ITextViewerExtension2#setTextHover(ITextHover, String, int) + * @since 2.1 + */ + public void setTextHover(ITextHover hover, String contentType, int stateMask) { + TextHoverKey key= new TextHoverKey(contentType, stateMask); + if (hover !is null) { + if (fTextHovers is null) { + fTextHovers= new HashMap(); + } + fTextHovers.put(key, cast(Object)hover); + } else if (fTextHovers !is null) + fTextHovers.remove(key); + + ensureHoverControlManagerInstalled(); + } + + /* + * @see ITextViewerExtension2#removeTextHovers(String) + * @since 2.1 + */ + public void removeTextHovers(String contentType) { + if (fTextHovers is null) + return; + + Iterator iter= (new HashSet(fTextHovers.keySet())).iterator(); + while (iter.hasNext()) { + TextHoverKey key= cast(TextHoverKey)iter.next(); + if (key.fContentType.equals(contentType)) + fTextHovers.remove(key); + } + } + + /** + * Returns the text hover for a given offset. + * + * @param offset the offset for which to return the text hover + * @return the text hover for the given offset + */ + protected ITextHover getTextHover(int offset) { + return getTextHover(offset, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK); + } + package ITextHover getTextHover_package(int offset) { + return getTextHover(offset); + } + + /** + * Returns the text hover for a given offset and a given state mask. + * + * @param offset the offset for which to return the text hover + * @param stateMask the DWT event state mask + * @return the text hover for the given offset and state mask + * @since 2.1 + */ + package ITextHover getTextHover_package(int offset, int stateMask) { + return getTextHover(offset,stateMask); + } + protected ITextHover getTextHover(int offset, int stateMask) { + if (fTextHovers is null) + return null; + + IDocument document= getDocument(); + if (document is null) + return null; + + try { + TextHoverKey key= new TextHoverKey(TextUtilities.getContentType(document, getDocumentPartitioning(), offset, true), stateMask); + Object textHover= fTextHovers.get(key); + if (textHover is null) { + // Use default text hover + key.setStateMask(ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK); + textHover= fTextHovers.get(key); + } + return cast(ITextHover) textHover; + } catch (BadLocationException x) { + if (TRACE_ERRORS) + System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.selectContentTypePlugin")); //$NON-NLS-1$ + } + return null; + } + + /** + * Returns the text hovering controller of this viewer. + * + * @return the text hovering controller of this viewer + * @since 2.0 + */ + protected AbstractInformationControlManager getTextHoveringController() { + return fTextHoverManager; + } + + /** + * Sets the creator for the hover controls. + * + * @param creator the hover control creator + * @since 2.0 + */ + public void setHoverControlCreator(IInformationControlCreator creator) { + fHoverControlCreator= creator; + } + + /** + * {@inheritDoc} + * + * @since 3.4 + */ + public void setHoverEnrichMode(ITextViewerExtension8_EnrichMode mode) { + if (fTextHoverManager is null) + return; + fTextHoverManager.setHoverEnrichMode(mode); + } + + /* + * @see IWidgetTokenOwner#requestWidgetToken(IWidgetTokenKeeper) + * @since 2.0 + */ + public bool requestWidgetToken(IWidgetTokenKeeper requester) { + if (fTextWidget !is null) { + if (fWidgetTokenKeeper !is null) { + if (fWidgetTokenKeeper is requester) + return true; + if (fWidgetTokenKeeper.requestWidgetToken(this)) { + fWidgetTokenKeeper= requester; + return true; + } + } else { + fWidgetTokenKeeper= requester; + return true; + } + } + return false; + } + + /* + * @see dwtx.jface.text.IWidgetTokenOwnerExtension#requestWidgetToken(dwtx.jface.text.IWidgetTokenKeeper, int) + * @since 3.0 + */ + public bool requestWidgetToken(IWidgetTokenKeeper requester, int priority) { + if (fTextWidget !is null) { + if (fWidgetTokenKeeper !is null) { + + if (fWidgetTokenKeeper is requester) + return true; + + bool accepted= false; + if ( cast(IWidgetTokenKeeperExtension)fWidgetTokenKeeper ) { + IWidgetTokenKeeperExtension extension= cast(IWidgetTokenKeeperExtension) fWidgetTokenKeeper; + accepted= extension.requestWidgetToken(this, priority); + } else { + accepted= fWidgetTokenKeeper.requestWidgetToken(this); + } + + if (accepted) { + fWidgetTokenKeeper= requester; + return true; + } + + } else { + fWidgetTokenKeeper= requester; + return true; + } + } + return false; + } + + /* + * @see IWidgetTokenOwner#releaseWidgetToken(IWidgetTokenKeeper) + * @since 2.0 + */ + public void releaseWidgetToken(IWidgetTokenKeeper tokenKeeper) { + if (fWidgetTokenKeeper is tokenKeeper) + fWidgetTokenKeeper= null; + } + + + //---- Selection + + /* + * @see ITextViewer#getSelectedRange() + */ + public Point getSelectedRange() { + + if (!redraws() && fViewerState !is null) + return fViewerState.getSelection(); + + if (fTextWidget !is null) { + Point p= fTextWidget.getSelectionRange(); + p= widgetSelection2ModelSelection(p); + if (p !is null) + return p; + } + + return new Point(-1, -1); + } + + /* + * @see ITextViewer#setSelectedRange(int, int) + */ + public void setSelectedRange(int selectionOffset, int selectionLength) { + + if (!redraws()) { + if (fViewerState !is null) + fViewerState.updateSelection(selectionOffset, selectionLength); + return; + } + + if (fTextWidget is null) + return; + + IRegion widgetSelection= modelRange2ClosestWidgetRange(new Region(selectionOffset, selectionLength)); + if (widgetSelection !is null) { + + int[] selectionRange= [ widgetSelection.getOffset(), widgetSelection.getLength() ]; + validateSelectionRange(selectionRange); + if (selectionRange[0] >= 0) { + fTextWidget.setSelectionRange(selectionRange[0], selectionRange[1]); + selectionChanged(selectionRange[0], selectionRange[1]); + } + } + } + + /** + * Validates and adapts the given selection range if it is not a valid + * widget selection. The widget selection is invalid if it starts or ends + * inside a multi-character line delimiter. If so, the selection is adapted to + * start after the divided line delimiter and to end before + * the divided line delimiter. The parameter passed in is changed in-place + * when being adapted. An adaptation to [-1, -1] indicates + * that the selection range could not be validated. + * Subclasses may reimplement this method. + * + * @param selectionRange selectionRange[0] is the offset, selectionRange[1] + * the length of the selection to validate. + * @since 2.0 + */ + protected void validateSelectionRange(int[] selectionRange) { + + IDocument document= getVisibleDocument(); + if (document is null) { + selectionRange[0]= -1; + selectionRange[1]= -1; + return; + } + + int documentLength= document.getLength(); + int offset= selectionRange[0]; + int length= selectionRange[1]; + + if (length < 0) { + length= - length; + offset -= length; + } + + if (offset <0) + offset= 0; + + if (offset > documentLength) + offset= documentLength; + + int delta= (offset + length) - documentLength; + if (delta > 0) + length -= delta; + + try { + + int lineNumber= document.getLineOfOffset(offset); + IRegion lineInformation= document.getLineInformation(lineNumber); + + int lineEnd= lineInformation.getOffset() + lineInformation.getLength(); + delta= offset - lineEnd; + if (delta > 0) { + // in the middle of a multi-character line delimiter + offset= lineEnd; + String delimiter= document.getLineDelimiter(lineNumber); + if (delimiter !is null) + offset += delimiter.length; + } + + int end= offset + length; + lineInformation= document.getLineInformationOfOffset(end); + lineEnd= lineInformation.getOffset() + lineInformation.getLength(); + delta= end - lineEnd; + if (delta > 0) { + // in the middle of a multi-character line delimiter + length -= delta; + } + + } catch (BadLocationException x) { + selectionRange[0]= -1; + selectionRange[1]= -1; + return; + } + + if (selectionRange[1] < 0) { + selectionRange[0]= offset + length; + selectionRange[1]= -length; + } else { + selectionRange[0]= offset; + selectionRange[1]= length; + } + } + + /* + * @see Viewer#setSelection(ISelection) + */ + public void setSelection(ISelection selection, bool reveal) { + if ( cast(ITextSelection)selection ) { + ITextSelection s= cast(ITextSelection) selection; + setSelectedRange(s.getOffset(), s.getLength()); + if (reveal) + revealRange(s.getOffset(), s.getLength()); + } + } + + /* + * @see Viewer#getSelection() + */ + public ISelection getSelection() { + Point p= getSelectedRange(); + if (p.x is -1 || p.y is -1) + return TextSelection.emptySelection(); + + return new TextSelection(getDocument(), p.x, p.y); + } + + /* + * @see ITextViewer#getSelectionProvider() + */ + public ISelectionProvider getSelectionProvider() { + return this; + } + + /* + * @see dwtx.jface.text.IPostSelectionProvider#addPostSelectionChangedListener(dwtx.jface.viewers.ISelectionChangedListener) + * @since 3.0 + */ + public void addPostSelectionChangedListener(ISelectionChangedListener listener) { + + Assert.isNotNull(cast(Object)listener); + + if (fPostSelectionChangedListeners is null) + fPostSelectionChangedListeners= new ArrayList(); + + if (!fPostSelectionChangedListeners.contains(cast(Object)listener)) + fPostSelectionChangedListeners.add(cast(Object)listener); + } + + /* + * @see dwtx.jface.text.IPostSelectionProvider#removePostSelectionChangedListener(dwtx.jface.viewers.ISelectionChangedListener) + * @since 3.0 + */ + public void removePostSelectionChangedListener(ISelectionChangedListener listener) { + + Assert.isNotNull(cast(Object)listener); + + if (fPostSelectionChangedListeners !is null) { + fPostSelectionChangedListeners.remove(cast(Object)listener); + if (fPostSelectionChangedListeners.size() is 0) + fPostSelectionChangedListeners= null; + } + } + + /** + * Get the text widget's display. + * + * @return the display or null if the display cannot be retrieved or if the display is disposed + * @since 3.0 + */ + private Display getDisplay() { + if (fTextWidget is null || fTextWidget.isDisposed()) + return null; + + Display display= fTextWidget.getDisplay(); + if (display !is null && display.isDisposed()) + return null; + + return display; + } + + /** + * Starts a timer to send out a post selection changed event. + * + * @param fireEqualSelection true iff the event must be fired if the selection does not change + * @since 3.0 + */ + private void queuePostSelectionChanged(bool fireEqualSelection) { + Display display= getDisplay(); + if (display is null) + return; + + fNumberOfPostSelectionChangedEvents[0]++; + display.timerExec(getEmptySelectionChangedEventDelay(), new class() Runnable { + const int id; + this(){ + id = fNumberOfPostSelectionChangedEvents[0]; + } + public void run() { + if (id is fNumberOfPostSelectionChangedEvents[0]) { + // Check again because this is executed after the delay + if (getDisplay() !is null) { + Point selection= fTextWidget.getSelectionRange(); + if (selection !is null) { + IRegion r= widgetRange2ModelRange(new Region(selection.x, selection.y)); + if (fireEqualSelection || (r !is null && !(cast(Object)r).opEquals(cast(Object)fLastSentPostSelectionChange)) || r is null) { + fLastSentPostSelectionChange= r; + firePostSelectionChanged(selection.x, selection.y); + } + } + } + } + } + }); + } + + /** + * Sends out a text selection changed event to all registered post selection changed listeners. + * + * @param offset the offset of the newly selected range in the visible document + * @param length the length of the newly selected range in the visible document + * @since 3.0 + */ + protected void firePostSelectionChanged(int offset, int length) { + if (redraws()) { + IRegion r= widgetRange2ModelRange(new Region(offset, length)); + ISelection selection= r !is null ? new TextSelection(getDocument(), r.getOffset(), r.getLength()) : TextSelection.emptySelection(); + SelectionChangedEvent event= new SelectionChangedEvent(this, selection); + firePostSelectionChanged(event); + } + } + + /** + * Sends out a text selection changed event to all registered listeners and + * registers the selection changed event to be sent out to all post selection + * listeners. + * + * @param offset the offset of the newly selected range in the visible document + * @param length the length of the newly selected range in the visible document + */ + protected void selectionChanged(int offset, int length) { + queuePostSelectionChanged(true); + fireSelectionChanged(offset, length); + } + + /** + * Sends out a text selection changed event to all registered listeners. + * + * @param offset the offset of the newly selected range in the visible document + * @param length the length of the newly selected range in the visible document + * @since 3.0 + */ + protected void fireSelectionChanged(int offset, int length) { + if (redraws()) { + IRegion r= widgetRange2ModelRange(new Region(offset, length)); + if ((r !is null && !(cast(Object)r).opEquals(cast(Object)fLastSentSelectionChange)) || r is null) { + fLastSentSelectionChange= r; + ISelection selection= r !is null ? new TextSelection(getDocument(), r.getOffset(), r.getLength()) : TextSelection.emptySelection(); + SelectionChangedEvent event= new SelectionChangedEvent(this, selection); + fireSelectionChanged(event); + } + } + } + + /** + * Sends the given event to all registered post selection changed listeners. + * + * @param event the selection event + * @since 3.0 + */ + private void firePostSelectionChanged(SelectionChangedEvent event) { + List listeners= fPostSelectionChangedListeners; + if (listeners !is null) { + listeners= new ArrayList(listeners); + for (int i= 0; i < listeners.size(); i++) { + ISelectionChangedListener l= cast(ISelectionChangedListener) listeners.get(i); + l.selectionChanged(event); + } + } + } + + /** + * Sends out a mark selection changed event to all registered listeners. + * + * @param offset the offset of the mark selection in the visible document, the offset is -1 if the mark was cleared + * @param length the length of the mark selection, may be negative if the caret is before the mark. + * @since 2.0 + */ + protected void markChanged(int offset, int length) { + if (redraws()) { + + if (offset !is -1) { + IRegion r= widgetRange2ModelRange(new Region(offset, length)); + offset= r.getOffset(); + length= r.getLength(); + } + + ISelection selection= new MarkSelection(getDocument(), offset, length); + SelectionChangedEvent event= new SelectionChangedEvent(this, selection); + fireSelectionChanged(event); + } + } + + + //---- Text listeners + + /* + * @see ITextViewer#addTextListener(ITextListener) + */ + public void addTextListener(ITextListener listener) { + + Assert.isNotNull(cast(Object)listener); + + if (fTextListeners is null) + fTextListeners= new ArrayList(); + + if (!fTextListeners.contains(cast(Object)listener)) + fTextListeners.add(cast(Object)listener); + } + + /* + * @see ITextViewer#removeTextListener(ITextListener) + */ + public void removeTextListener(ITextListener listener) { + + Assert.isNotNull(cast(Object)listener); + + if (fTextListeners !is null) { + fTextListeners.remove(cast(Object)listener); + if (fTextListeners.size() is 0) + fTextListeners= null; + } + } + + /** + * Informs all registered text listeners about the change specified by the + * widget command. This method does not use a robust iterator. + * + * @param cmd the widget command translated into a text event sent to all text listeners + */ + protected void updateTextListeners(WidgetCommand cmd) { + List textListeners= fTextListeners; + if (textListeners !is null) { + textListeners= new ArrayList(textListeners); + DocumentEvent event= cmd.event; + if ( cast(SlaveDocumentEvent)event ) + event= (cast(SlaveDocumentEvent) event).getMasterEvent(); + + TextEvent e= new TextEvent(cmd.start, cmd.length, cmd.text, cmd.preservedText, event, redraws()); + for (int i= 0; i < textListeners.size(); i++) { + ITextListener l= cast(ITextListener) textListeners.get(i); + l.textChanged(e); + } + } + } + + //---- Text input listeners + + /* + * @see ITextViewer#addTextInputListener(ITextInputListener) + */ + public void addTextInputListener(ITextInputListener listener) { + + Assert.isNotNull(cast(Object)listener); + + if (fTextInputListeners is null) + fTextInputListeners= new ArrayList(); + + if (!fTextInputListeners.contains(cast(Object)listener)) + fTextInputListeners.add(cast(Object)listener); + } + + /* + * @see ITextViewer#removeTextInputListener(ITextInputListener) + */ + public void removeTextInputListener(ITextInputListener listener) { + + Assert.isNotNull(cast(Object)listener); + + if (fTextInputListeners !is null) { + fTextInputListeners.remove(cast(Object)listener); + if (fTextInputListeners.size() is 0) + fTextInputListeners= null; + } + } + + /** + * Informs all registered text input listeners about the forthcoming input change, + * This method does not use a robust iterator. + * + * @param oldInput the old input document + * @param newInput the new input document + */ + protected void fireInputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { + List listener= fTextInputListeners; + if (listener !is null) { + for (int i= 0; i < listener.size(); i++) { + ITextInputListener l= cast(ITextInputListener) listener.get(i); + l.inputDocumentAboutToBeChanged(oldInput, newInput); + } + } + } + + /** + * Informs all registered text input listeners about the successful input change, + * This method does not use a robust iterator. + * + * @param oldInput the old input document + * @param newInput the new input document + */ + protected void fireInputDocumentChanged(IDocument oldInput, IDocument newInput) { + List listener= fTextInputListeners; + if (listener !is null) { + for (int i= 0; i < listener.size(); i++) { + ITextInputListener l= cast(ITextInputListener) listener.get(i); + l.inputDocumentChanged(oldInput, newInput); + } + } + } + + //---- Document + + /* + * @see Viewer#getInput() + */ + public Object getInput() { + return cast(Object)getDocument(); + } + + /* + * @see ITextViewer#getDocument() + */ + public IDocument getDocument() { + return fDocument; + } + + /* + * @see Viewer#setInput(Object) + */ + public void setInput(Object input) { + + IDocument document= null; + if ( cast(IDocument)input ) + document= cast(IDocument) input; + + setDocument(document); + } + + /* + * @see ITextViewer#setDocument(IDocument) + */ + public void setDocument(IDocument document) { + + fReplaceTextPresentation= true; + fireInputDocumentAboutToBeChanged(fDocument, document); + + IDocument oldDocument= fDocument; + fDocument= document; + + setVisibleDocument(fDocument); + + resetPlugins(); + inputChanged(cast(Object)fDocument, cast(Object)oldDocument); + + fireInputDocumentChanged(oldDocument, fDocument); + fLastSentSelectionChange= null; + fReplaceTextPresentation= false; + } + + /* + * @see ITextViewer#setDocument(IDocument, int, int) + */ + public void setDocument(IDocument document, int modelRangeOffset, int modelRangeLength) { + + fReplaceTextPresentation= true; + fireInputDocumentAboutToBeChanged(fDocument, document); + + IDocument oldDocument= fDocument; + fDocument= document; + + try { + + IDocument slaveDocument= createSlaveDocument(document); + updateSlaveDocument(slaveDocument, modelRangeOffset, modelRangeLength); + setVisibleDocument(slaveDocument); + + } catch (BadLocationException x) { + throw new IllegalArgumentException(JFaceTextMessages.getString("TextViewer.error.invalid_visible_region_1")); //$NON-NLS-1$ + } + + resetPlugins(); + inputChanged(cast(Object)fDocument, cast(Object)oldDocument); + + fireInputDocumentChanged(oldDocument, fDocument); + fLastSentSelectionChange= null; + fReplaceTextPresentation= false; + } + + /** + * Creates a slave document for the given document if there is a slave document manager + * associated with this viewer. + * + * @param document the master document + * @return the newly created slave document + * @since 2.1 + */ + protected IDocument createSlaveDocument(IDocument document) { + ISlaveDocumentManager manager= getSlaveDocumentManager(); + if (manager !is null) { + if (manager.isSlaveDocument(document)) + return document; + return manager.createSlaveDocument(document); + } + return document; + } + + /** + * Sets the given slave document to the specified range of its master document. + * + * @param visibleDocument the slave document + * @param visibleRegionOffset the offset of the master document range + * @param visibleRegionLength the length of the master document range + * @return true if the slave has been adapted successfully + * @throws BadLocationException in case the specified range is not valid in the master document + * @since 2.1 + * @deprecated use updateSlaveDocument instead + */ + protected bool updateVisibleDocument(IDocument visibleDocument, int visibleRegionOffset, int visibleRegionLength) { + if ( cast(ChildDocument)visibleDocument ) { + ChildDocument childDocument= cast(ChildDocument) visibleDocument; + + IDocument document= childDocument.getParentDocument(); + int line= document.getLineOfOffset(visibleRegionOffset); + int offset= document.getLineOffset(line); + int length= (visibleRegionOffset - offset) + visibleRegionLength; + + Position parentRange= childDocument.getParentDocumentRange(); + if (offset !is parentRange.getOffset() || length !is parentRange.getLength()) { + childDocument.setParentDocumentRange(offset, length); + return true; + } + } + return false; + } + + /** + * Updates the given slave document to show the specified range of its master document. + * + * @param slaveDocument the slave document + * @param modelRangeOffset the offset of the master document range + * @param modelRangeLength the length of the master document range + * @return true if the slave has been adapted successfully + * @throws BadLocationException in case the specified range is not valid in the master document + * @since 3.0 + */ + protected bool updateSlaveDocument(IDocument slaveDocument, int modelRangeOffset, int modelRangeLength) { + return updateVisibleDocument(slaveDocument, modelRangeOffset, modelRangeLength); + } + + + + //---- View ports + + /** + * Initializes all listeners and structures required to set up view port listeners. + */ + private void initializeViewportUpdate() { + + if (fViewportGuard !is null) + return; + + if (fTextWidget !is null) { + + fViewportGuard= new ViewportGuard(); + fLastTopPixel= -1; + + fTextWidget.addKeyListener(fViewportGuard); + fTextWidget.addMouseListener(fViewportGuard); + + fScroller= fTextWidget.getVerticalBar(); + if (fScroller !is null) + fScroller.addSelectionListener(fViewportGuard); + } + } + + /** + * Removes all listeners and structures required to set up view port listeners. + */ + private void removeViewPortUpdate() { + + if (fTextWidget !is null) { + + fTextWidget.removeKeyListener(fViewportGuard); + fTextWidget.removeMouseListener(fViewportGuard); + + if (fScroller !is null && !fScroller.isDisposed()) { + fScroller.removeSelectionListener(fViewportGuard); + fScroller= null; + } + + fViewportGuard= null; + } + } + + /* + * @see ITextViewer#addViewportListener(IViewportListener) + */ + public void addViewportListener(IViewportListener listener) { + + if (fViewportListeners is null) { + fViewportListeners= new ArrayList(); + initializeViewportUpdate(); + } + + if (!fViewportListeners.contains(cast(Object)listener)) + fViewportListeners.add(cast(Object)listener); + } + + /* + * @see ITextViewer#removeViewportListener(IVewportListener) + */ + public void removeViewportListener(IViewportListener listener) { + if (fViewportListeners !is null) + fViewportListeners.remove(cast(Object)listener); + } + + /** + * Checks whether the view port changed and if so informs all registered + * listeners about the change. + * + * @param origin describes under which circumstances this method has been called. + * + * @see IViewportListener + */ + protected void updateViewportListeners(int origin) { + + if (redraws()) { + int topPixel= fTextWidget.getTopPixel(); + if (topPixel >= 0 && topPixel !is fLastTopPixel) { + if (fViewportListeners !is null) { + for (int i= 0; i < fViewportListeners.size(); i++) { + IViewportListener l= cast(IViewportListener) fViewportListeners.get(i); + l.viewportChanged(topPixel); + } + } + fLastTopPixel= topPixel; + } + } + } + + //---- scrolling and revealing + + /* + * @see ITextViewer#getTopIndex() + */ + public int getTopIndex() { + + if (fTextWidget !is null) { + int top= fTextWidget.getTopIndex(); + return widgetLine2ModelLine(top); + } + + return -1; + } + + /* + * @see ITextViewer#setTopIndex(int) + */ + public void setTopIndex(int index) { + + if (fTextWidget !is null) { + + int widgetLine= modelLine2WidgetLine(index); + if (widgetLine is -1) + widgetLine= getClosestWidgetLineForModelLine(index); + + if (widgetLine > -1) { + fTextWidget.setTopIndex(widgetLine); + updateViewportListeners(INTERNAL); + } + } + } + + /** + * Returns the number of lines that can fully fit into the viewport. This is computed by + * dividing the widget's client area height by the widget's line height. The result is only + * accurate if the widget does not use variable line heights - for that reason, clients should + * not use this method any longer and use the client area height of the text widget to find out + * how much content fits into it. + * + * @return the view port height in lines + * @deprecated as of 3.2 + */ + protected int getVisibleLinesInViewport() { + if (fTextWidget !is null) { + Rectangle clArea= fTextWidget.getClientArea(); + if (!clArea.isEmpty()) + return clArea.height / fTextWidget.getLineHeight(); + } + return -1; + } + + /* + * @see ITextViewer#getBottomIndex() + */ + public int getBottomIndex() { + + if (fTextWidget is null) + return -1; + + int widgetBottom= JFaceTextUtil.getBottomIndex(fTextWidget); + return widgetLine2ModelLine(widgetBottom); + } + + /* + * @see ITextViewer#getTopIndexStartOffset() + */ + public int getTopIndexStartOffset() { + + if (fTextWidget !is null) { + int top= fTextWidget.getTopIndex(); + try { + top= getVisibleDocument().getLineOffset(top); + return widgetOffset2ModelOffset(top); + } catch (BadLocationException ex) { + if (TRACE_ERRORS) + System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.getTopIndexStartOffset")); //$NON-NLS-1$ + } + } + + return -1; + } + + /* + * @see ITextViewer#getBottomIndexEndOffset() + */ + public int getBottomIndexEndOffset() { + try { + + IRegion line= getDocument().getLineInformation(getBottomIndex()); + int bottomEndOffset= line.getOffset() + line.getLength() - 1; + + IRegion coverage= getModelCoverage(); + if (coverage is null) + return -1; + + int coverageEndOffset= coverage.getOffset() + coverage.getLength() - 1; + return Math.min(coverageEndOffset, bottomEndOffset); + + } catch (BadLocationException ex) { + if (TRACE_ERRORS) + System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.getBottomIndexEndOffset")); //$NON-NLS-1$ + return getDocument().getLength() - 1; + } + } + + /* + * @see ITextViewer#revealRange(int, int) + */ + public void revealRange(int start, int length) { + + if (fTextWidget is null || !redraws()) + return; + + IRegion modelRange= new Region(start, length); + IRegion widgetRange= modelRange2ClosestWidgetRange(modelRange); + if (widgetRange !is null) { + + int[] range= [ widgetRange.getOffset(), widgetRange.getLength() ]; + validateSelectionRange(range); + if (range[0] >= 0) + internalRevealRange(range[0], range[0] + range[1]); + + } else { + + IRegion coverage= getModelCoverage(); + int cursor= (coverage is null || start < coverage.getOffset()) ? 0 : getVisibleDocument().getLength(); + internalRevealRange(cursor, cursor); + } + } + + /** + * Reveals the given range of the visible document. + * + * @param start the start offset of the range + * @param end the end offset of the range + */ + protected void internalRevealRange(int start, int end) { + + try { + + IDocument doc= getVisibleDocument(); + + int startLine= doc.getLineOfOffset(start); + int endLine= doc.getLineOfOffset(end); + + int top= fTextWidget.getTopIndex(); + if (top > -1) { + + // scroll vertically + int bottom= JFaceTextUtil.getBottomIndex(fTextWidget); + int lines= bottom - top; + + // if the widget is not scrollable as it is displaying the entire content + // setTopIndex won't have any effect. + + if (startLine >= top && startLine <= bottom && endLine >= top && endLine <= bottom ) { + + // do not scroll at all as it is already visible + + } else { + + int delta= Math.max(0, lines - (endLine - startLine)); + fTextWidget.setTopIndex(startLine - delta/3); + updateViewportListeners(INTERNAL); + } + + // scroll horizontally + + if (endLine < startLine) { + endLine += startLine; + startLine= endLine - startLine; + endLine -= startLine; + } + + int startPixel= -1; + int endPixel= -1; + + if (endLine > startLine) { + // reveal the beginning of the range in the start line + IRegion extent= getExtent(start, start); + startPixel= extent.getOffset() + fTextWidget.getHorizontalPixel(); + endPixel= startPixel; + + } else { + IRegion extent= getExtent(start, end); + startPixel= extent.getOffset() + fTextWidget.getHorizontalPixel(); + endPixel= startPixel + extent.getLength(); + } + + int visibleStart= fTextWidget.getHorizontalPixel(); + int visibleEnd= visibleStart + fTextWidget.getClientArea().width; + + // scroll only if not yet visible + if (startPixel < visibleStart || visibleEnd < endPixel) { + + // set buffer zone to 10 pixels + int bufferZone= 10; + + int newOffset= visibleStart; + + int visibleWidth= visibleEnd - visibleStart; + int selectionPixelWidth= endPixel - startPixel; + + if (startPixel < visibleStart) + newOffset= startPixel; + else if (selectionPixelWidth + bufferZone < visibleWidth) + newOffset= endPixel + bufferZone - visibleWidth; + else + newOffset= startPixel; + + float index= (cast(float)newOffset) / (cast(float)getAverageCharWidth()); + + fTextWidget.setHorizontalIndex(cast(int)Math.round(index)); + } + + } + } catch (BadLocationException e) { + throw new IllegalArgumentException(JFaceTextMessages.getString("TextViewer.error.invalid_range")); //$NON-NLS-1$ + } + } + + /** + * Returns the width of the text when being drawn into this viewer's widget. + * + * @param text the string to measure + * @return the width of the presentation of the given string + * @deprecated use getWidthInPixels(int, int) instead + */ + final protected int getWidthInPixels(String text) { + GC gc= new GC(fTextWidget); + gc.setFont(fTextWidget.getFont()); + Point extent= gc.textExtent(text); + gc.dispose(); + return extent.x; + } + + /** + * Returns the region covered by the given start and end offset. + * The result is relative to the upper left corner of the widget + * client area. + * + * @param start offset relative to the start of this viewer's view port + * 0 <= offset <= getCharCount() + * @param end offset relative to the start of this viewer's view port + * 0 <= offset <= getCharCount() + * @return the region covered by start and end offset + */ + final protected IRegion getExtent(int start, int end) { + if (end > 0 && start < end) { + Rectangle bounds= fTextWidget.getTextBounds(start, end - 1); + return new Region(bounds.x, bounds.width); + } + + return new Region(fTextWidget.getLocationAtOffset(start).x, 0); + } + + /** + * Returns the width of the representation of a text range in the + * visible region of the viewer's document as drawn in this viewer's + * widget. + * + * @param offset the offset of the text range in the visible region + * @param length the length of the text range in the visible region + * @return the width of the presentation of the specified text range + * @since 2.0 + */ + final protected int getWidthInPixels(int offset, int length) { + return getExtent(offset, offset + length).getLength(); + } + + /** + * Returns the average character width of this viewer's widget. + * + * @return the average character width of this viewer's widget + */ + final protected int getAverageCharWidth() { + return JFaceTextUtil.getAverageCharWidth(getTextWidget()); + } + + /* + * @see Viewer#refresh() + */ + public void refresh() { + setDocument(getDocument()); + } + + //---- visible range support + + /** + * Returns the slave document manager + * + * @return the slave document manager + * @since 2.1 + */ + protected ISlaveDocumentManager getSlaveDocumentManager() { + if (fSlaveDocumentManager is null) + fSlaveDocumentManager= createSlaveDocumentManager(); + return fSlaveDocumentManager; + } + + /** + * Creates a new slave document manager. This implementation always + * returns a ChildDocumentManager. + * + * @return ISlaveDocumentManager + * @since 2.1 + */ + protected ISlaveDocumentManager createSlaveDocumentManager() { + return new ChildDocumentManager(); + } + + /* + * @see dwtx.jface.text.ITextViewer#invalidateTextPresentation() + */ + public final void invalidateTextPresentation() { + if (fVisibleDocument !is null) { + fWidgetCommand.event= null; + fWidgetCommand.start= 0; + fWidgetCommand.length= fVisibleDocument.getLength(); + fWidgetCommand.text= fVisibleDocument.get(); + updateTextListeners(fWidgetCommand); + } + } + + /** + * Invalidates the given range of the text presentation. + * + * @param offset the offset of the range to be invalidated + * @param length the length of the range to be invalidated + * @since 2.1 + */ + public final void invalidateTextPresentation(int offset, int length) { + if (fVisibleDocument !is null) { + + IRegion widgetRange= modelRange2WidgetRange(new Region(offset, length)); + if (widgetRange !is null) { + + fWidgetCommand.event= null; + fWidgetCommand.start= widgetRange.getOffset(); + fWidgetCommand.length= widgetRange.getLength(); + + try { + fWidgetCommand.text= fVisibleDocument.get(widgetRange.getOffset(), widgetRange.getLength()); + updateTextListeners(fWidgetCommand); + } catch (BadLocationException x) { + // can not happen because of previous checking + } + } + } + } + + /** + * Initializes the text widget with the visual document and + * invalidates the overall presentation. + */ + private void initializeWidgetContents() { + + if (fTextWidget !is null && fVisibleDocument !is null) { + + // set widget content + if (fDocumentAdapter is null) + fDocumentAdapter= createDocumentAdapter(); + + fDocumentAdapter.setDocument(fVisibleDocument); + fTextWidget.setContent(fDocumentAdapter); + + // invalidate presentation + invalidateTextPresentation(); + } + } + + /** + * Frees the given document if it is a slave document. + * + * @param slave the potential slave document + * @since 3.0 + */ + protected void freeSlaveDocument(IDocument slave) { + ISlaveDocumentManager manager= getSlaveDocumentManager(); + if (manager !is null && manager.isSlaveDocument(slave)) + manager.freeSlaveDocument(slave); + } + + /** + * Sets this viewer's visible document. The visible document represents the + * visible region of the viewer's input document. + * + * @param document the visible document + */ + protected void setVisibleDocument(IDocument document) { + + if (fVisibleDocument is document && cast(ChildDocument)fVisibleDocument ) { + // optimization for new child documents + return; + } + + if (fVisibleDocument !is null) { + if (fVisibleDocumentListener !is null) + fVisibleDocument.removeDocumentListener(fVisibleDocumentListener); + if (fVisibleDocument !is document) + freeSlaveDocument(fVisibleDocument); + } + + fVisibleDocument= document; + initializeDocumentInformationMapping(fVisibleDocument); + + initializeWidgetContents(); + + fFindReplaceDocumentAdapter= null; + if (fVisibleDocument !is null && fVisibleDocumentListener !is null) + fVisibleDocument.addDocumentListener(fVisibleDocumentListener); + } + + /** + * Hook method called when the visible document is about to be changed. + *

                + * Subclasses may override. + * + * @param event the document event + * @since 3.0 + */ + protected void handleVisibleDocumentAboutToBeChanged(DocumentEvent event) { + } + + /** + * Hook method called when the visible document has been changed. + *

                + * Subclasses may override. + * + * @param event the document event + * @since 3.0 + */ + protected void handleVisibleDocumentChanged(DocumentEvent event) { + } + + /** + * Initializes the document information mapping between the given slave document and + * its master document. + * + * @param visibleDocument the slave document + * @since 2.1 + */ + protected void initializeDocumentInformationMapping(IDocument visibleDocument) { + ISlaveDocumentManager manager= getSlaveDocumentManager(); + fInformationMapping= manager is null ? null : manager.createMasterSlaveMapping(visibleDocument); + } + + /** + * Returns the viewer's visible document. + * + * @return the viewer's visible document + */ + protected IDocument getVisibleDocument() { + return fVisibleDocument; + } + + /** + * Returns the offset of the visible region. + * + * @return the offset of the visible region + */ + protected int _getVisibleRegionOffset() { + + IDocument document= getVisibleDocument(); + if ( cast(ChildDocument)document ) { + ChildDocument cdoc= cast(ChildDocument) document; + return cdoc.getParentDocumentRange().getOffset(); + } + + return 0; + } + package int _getVisibleRegionOffset_package() { + return _getVisibleRegionOffset(); + } + + /* + * @see ITextViewer#getVisibleRegion() + */ + public IRegion getVisibleRegion() { + + IDocument document= getVisibleDocument(); + if ( cast(ChildDocument)document ) { + Position p= (cast(ChildDocument) document).getParentDocumentRange(); + return new Region(p.getOffset(), p.getLength()); + } + + return new Region(0, document is null ? 0 : document.getLength()); + } + + /* + * @see ITextViewer#overlapsWithVisibleRegion(int, int) + */ + public bool overlapsWithVisibleRegion(int start, int length) { + IDocument document= getVisibleDocument(); + if ( cast(ChildDocument)document ) { + ChildDocument cdoc= cast(ChildDocument) document; + return cdoc.getParentDocumentRange().overlapsWith(start, length); + } else if (document !is null) { + int size= document.getLength(); + return (start >= 0 && length >= 0 && start + length <= size); + } + return false; + } + + /* + * @see ITextViewer#setVisibleRegion(int, int) + */ + public void setVisibleRegion(int start, int length) { + + IRegion region= getVisibleRegion(); + if (start is region.getOffset() && length is region.getLength()) { + // nothing to change + return; + } + + setRedraw(false); + try { + + IDocument slaveDocument= createSlaveDocument(getVisibleDocument()); + if (updateSlaveDocument(slaveDocument, start, length)) + setVisibleDocument(slaveDocument); + + } catch (BadLocationException x) { + throw new IllegalArgumentException(JFaceTextMessages.getString("TextViewer.error.invalid_visible_region_2")); //$NON-NLS-1$ + } finally { + setRedraw(true); + } + } + + /* + * @see ITextViewer#resetVisibleRegion() + */ + public void resetVisibleRegion() { + ISlaveDocumentManager manager= getSlaveDocumentManager(); + if (manager !is null) { + IDocument slave= getVisibleDocument(); + IDocument master= manager.getMasterDocument(slave); + if (master !is null) { + setVisibleDocument(master); + manager.freeSlaveDocument(slave); + } + } + } + + + //-------------------------------------- + + /* + * @see ITextViewer#setTextDoubleClickStrategy(ITextDoubleClickStrategy, String) + */ + public void setTextDoubleClickStrategy(ITextDoubleClickStrategy strategy, String contentType) { + + if (strategy !is null) { + if (fDoubleClickStrategies is null) + fDoubleClickStrategies= new HashMap(); + fDoubleClickStrategies.put(stringcast(contentType), cast(Object)strategy); + } else if (fDoubleClickStrategies !is null) + fDoubleClickStrategies.remove(contentType); + } + + /** + * Selects from the given map the one which is registered under + * the content type of the partition in which the given offset is located. + * + * @param plugins the map from which to choose + * @param offset the offset for which to find the plug-in + * @return the plug-in registered under the offset's content type + */ + protected Object selectContentTypePlugin(int offset, Map plugins) { + try { + return selectContentTypePlugin(TextUtilities.getContentType(getDocument(), getDocumentPartitioning(), offset, true), plugins); + } catch (BadLocationException x) { + if (TRACE_ERRORS) + System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.selectContentTypePlugin")); //$NON-NLS-1$ + } + return null; + } + + /** + * Selects from the given plug-ins this one which is + * registered for the given content type. + * + * @param type the type to be used as lookup key + * @param plugins the table to be searched + * @return the plug-in in the map for the given content type + */ + private Object selectContentTypePlugin(String type, Map plugins) { + + if (plugins is null) + return null; + + return plugins.get(type); + } + + /** + * Hook called on receipt of a VerifyEvent. The event has + * been translated into a DocumentCommand which can now be + * manipulated by interested parties. By default, the hook forwards the command + * to the installed instances of IAutoEditStrategy. + * + * @param command the document command representing the verify event + */ + protected void customizeDocumentCommand(DocumentCommand command) { + if (isIgnoringAutoEditStrategies()) + return; + + IDocument document= getDocument(); + + if (fTabsToSpacesConverter !is null) + fTabsToSpacesConverter.customizeDocumentCommand(document, command); + + List strategies= cast(List) selectContentTypePlugin(command.offset, fAutoIndentStrategies); + if (strategies is null) + return; + + switch (strategies.size()) { + // optimization + case 0: + break; + + case 1: + (cast(IAutoEditStrategy) strategies.iterator().next()).customizeDocumentCommand(document, command); + break; + + // make iterator robust against adding/removing strategies from within strategies + default: + strategies= new ArrayList(strategies); + for (final Iterator iterator= strategies.iterator(); iterator.hasNext(); ) + (cast(IAutoEditStrategy) iterator.next()).customizeDocumentCommand(document, command); + + break; + } + } + + /** + * Handles the verify event issued by the viewer's text widget. + * + * @see VerifyListener#verifyText(VerifyEvent) + * @param e the verify event + */ + protected void handleVerifyEvent(VerifyEvent e) { + + if (fEventConsumer !is null) { + fEventConsumer.processEvent(e); + if (!e.doit) + return; + } + + IRegion modelRange= event2ModelRange(e); + fDocumentCommand.setEvent(e, modelRange); + customizeDocumentCommand(fDocumentCommand); + if (!fDocumentCommand.fillEvent(e, modelRange)) { + + bool compoundChange= fDocumentCommand.getCommandCount() > 1; + try { + + fVerifyListener.forward(false); + + if (compoundChange && fUndoManager !is null) + fUndoManager.beginCompoundChange(); + + fDocumentCommand.execute(getDocument()); + + if (fTextWidget !is null) { + int documentCaret= fDocumentCommand.caretOffset; + if (documentCaret is -1) { + // old behavior of document command + documentCaret= fDocumentCommand.offset + (fDocumentCommand.text is null ? 0 : fDocumentCommand.text.length()); + } + + int widgetCaret= modelOffset2WidgetOffset(documentCaret); + if (widgetCaret is -1) { + // try to move it to the closest spot + IRegion region= getModelCoverage(); + if (region !is null) { + if (documentCaret <= region.getOffset()) + widgetCaret= 0; + else if (documentCaret >= region.getOffset() + region.getLength()) + widgetCaret= getVisibleRegion().getLength(); + } + } + + if (widgetCaret !is -1) { + // there is a valid widget caret + fTextWidget.setCaretOffset(widgetCaret); + } + + fTextWidget.showSelection(); + } + } catch (BadLocationException x) { + + if (TRACE_ERRORS) + System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.verifyText")); //$NON-NLS-1$ + + } finally { + + if (compoundChange && fUndoManager !is null) + fUndoManager.endCompoundChange(); + + fVerifyListener.forward(true); + + } + } + } + + //---- text manipulation + + /** + * Returns whether the marked region of this viewer is empty. + * + * @return true if the marked region of this viewer is empty, otherwise false + * @since 2.0 + */ + private bool isMarkedRegionEmpty() { + return + fTextWidget is null || + fMarkPosition is null || + fMarkPosition.isDeleted() || + modelRange2WidgetRange(fMarkPosition) is null; + } + + /* + * @see ITextViewer#canDoOperation(int) + */ + public bool canDoOperation(int operation) { + + if (fTextWidget is null || !redraws()) + return false; + + switch (operation) { + case CUT: + return isEditable() &&(fTextWidget.getSelectionCount() > 0 || !isMarkedRegionEmpty()); + case COPY: + return fTextWidget.getSelectionCount() > 0 || !isMarkedRegionEmpty(); + case DELETE: + case PASTE: + return isEditable(); + case SELECT_ALL: + return true; + case SHIFT_LEFT: + case SHIFT_RIGHT: + return isEditable() && fIndentChars !is null && areMultipleLinesSelected(); + case PREFIX: + case STRIP_PREFIX: + return isEditable() && fDefaultPrefixChars !is null; + case UNDO: + return fUndoManager !is null && fUndoManager.undoable(); + case REDO: + return fUndoManager !is null && fUndoManager.redoable(); + case PRINT: + return isPrintable(); + } + + return false; + } + + /* + * @see ITextViewer#doOperation(int) + */ + public void doOperation(int operation) { + + if (fTextWidget is null || !redraws()) + return; + + Point selection= null; + + switch (operation) { + + case UNDO: + if (fUndoManager !is null) { + ignoreAutoEditStrategies(true); + fUndoManager.undo(); + ignoreAutoEditStrategies(false); + } + break; + case REDO: + if (fUndoManager !is null) { + ignoreAutoEditStrategies(true); + fUndoManager.redo(); + ignoreAutoEditStrategies(false); + } + break; + case CUT: + if (fTextWidget.getSelectionCount() is 0) + copyMarkedRegion(true); + else + fTextWidget.cut(); + + selection= fTextWidget.getSelectionRange(); + fireSelectionChanged(selection.x, selection.y); + + break; + case COPY: + if (fTextWidget.getSelectionCount() is 0) + copyMarkedRegion(false); + else + fTextWidget.copy(); + break; + case PASTE: +// ignoreAutoEditStrategies(true); + fTextWidget.paste(); + selection= fTextWidget.getSelectionRange(); + fireSelectionChanged(selection.x, selection.y); +// ignoreAutoEditStrategies(false); + break; + case DELETE: + fTextWidget.invokeAction(ST.DELETE_NEXT); + selection= fTextWidget.getSelectionRange(); + fireSelectionChanged(selection.x, selection.y); + break; + case SELECT_ALL: { + if (getDocument() !is null) + setSelectedRange(0, getDocument().getLength()); + break; + } + case SHIFT_RIGHT: + shift(false, true, false); + break; + case SHIFT_LEFT: + shift(false, false, false); + break; + case PREFIX: + shift(true, true, true); + break; + case STRIP_PREFIX: + shift(true, false, true); + break; + case PRINT: + print(); + break; + } + } + + /** + * Tells this viewer whether the registered auto edit strategies should be ignored. + * + * @param ignore true if the strategies should be ignored. + * @since 2.1 + */ + protected void ignoreAutoEditStrategies(bool ignore) { + if (fIgnoreAutoIndent is ignore) + return; + + fIgnoreAutoIndent= ignore; + + IDocument document= getDocument(); + if ( cast(IDocumentExtension2)document ) { + IDocumentExtension2 extension= cast(IDocumentExtension2) document; + if (ignore) + extension.ignorePostNotificationReplaces(); + else + extension.acceptPostNotificationReplaces(); + } + } + package void ignoreAutoEditStrategies_package(bool ignore) { + return ignoreAutoEditStrategies(ignore); + } + + /** + * Returns whether this viewer ignores the registered auto edit strategies. + * + * @return true if the strategies are ignored + * @since 2.1 + */ + protected bool isIgnoringAutoEditStrategies() { + return fIgnoreAutoIndent; + } + + /* + * @see ITextOperationTargetExtension#enableOperation(int, bool) + * @since 2.0 + */ + public void enableOperation(int operation, bool enable) { + /* + * NO-OP by default. + * Will be changed to regularly disable the known operations. + */ + } + + /** + * Copies/cuts the marked region. + * + * @param delete true if the region should be deleted rather than copied. + * @since 2.0 + */ + protected void copyMarkedRegion(bool delete_) { + + if (fTextWidget is null) + return; + + if (fMarkPosition is null || fMarkPosition.isDeleted() || modelRange2WidgetRange(fMarkPosition) is null) + return; + + int widgetMarkOffset= modelOffset2WidgetOffset(fMarkPosition.offset); + Point selection= fTextWidget.getSelection(); + if (selection.x <= widgetMarkOffset) + fTextWidget.setSelection(selection.x, widgetMarkOffset); + else + fTextWidget.setSelection(widgetMarkOffset, selection.x); + + if (delete_) { + fTextWidget.cut(); + } else { + fTextWidget.copy(); + fTextWidget.setSelection(selection.x); // restore old cursor position + } + } + + /** + * Deletes the current selection. If the selection has the length 0 + * the selection is automatically extended to the right - either by 1 + * or by the length of line delimiter if at the end of a line. + * + * @deprecated use StyledText.invokeAction instead + */ + protected void deleteText() { + fTextWidget.invokeAction(ST.DELETE_NEXT); + } + + /** + * A block is selected if the character preceding the start of the + * selection is a new line character. + * + * @return true if a block is selected + */ + protected bool isBlockSelected() { + + Point s= getSelectedRange(); + if (s.y is 0) + return false; + + try { + + IDocument document= getDocument(); + int line= document.getLineOfOffset(s.x); + int start= document.getLineOffset(line); + return (s.x is start); + + } catch (BadLocationException x) { + } + + return false; + } + + /** + * Returns true if one line is completely selected or if multiple lines are selected. + * Being completely selected means that all characters except the new line characters are + * selected. + * + * @return true if one or multiple lines are selected + * @since 2.0 + */ + protected bool areMultipleLinesSelected() { + Point s= getSelectedRange(); + if (s.y is 0) + return false; + + try { + + IDocument document= getDocument(); + int startLine= document.getLineOfOffset(s.x); + int endLine= document.getLineOfOffset(s.x + s.y); + IRegion line= document.getLineInformation(startLine); + return startLine !is endLine || (s.x is line.getOffset() && s.y is line.getLength()); + + } catch (BadLocationException x) { + } + + return false; + } + + /** + * Returns the index of the first line whose start offset is in the given text range. + * + * @param region the text range in characters where to find the line + * @return the first line whose start index is in the given range, -1 if there is no such line + */ + private int getFirstCompleteLineOfRegion(IRegion region) { + + try { + + IDocument d= getDocument(); + + int startLine= d.getLineOfOffset(region.getOffset()); + + int offset= d.getLineOffset(startLine); + if (offset >= region.getOffset()) + return startLine; + + offset= d.getLineOffset(startLine + 1); + return (offset > region.getOffset() + region.getLength() ? -1 : startLine + 1); + + } catch (BadLocationException x) { + if (TRACE_ERRORS) + System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.getFirstCompleteLineOfRegion")); //$NON-NLS-1$ + } + + return -1; + } + + + /** + * Creates a region describing the text block (something that starts at + * the beginning of a line) completely containing the current selection. + * + * @param selection the selection to use + * @return the region describing the text block comprising the given selection + * @since 2.0 + */ + private IRegion getTextBlockFromSelection(Point selection) { + + try { + IDocument document= getDocument(); + IRegion line= document.getLineInformationOfOffset(selection.x); + int length= selection.y is 0 ? line.getLength() : selection.y + (selection.x - line.getOffset()); + return new Region(line.getOffset(), length); + + } catch (BadLocationException x) { + } + + return null; + } + + /** + * Shifts a text block to the right or left using the specified set of prefix characters. + * The prefixes must start at the beginning of the line. + * + * @param useDefaultPrefixes says whether the configured default or indent prefixes should be used + * @param right says whether to shift to the right or the left + * + * @deprecated use shift(bool, bool, bool) instead + */ + protected void shift(bool useDefaultPrefixes, bool right) { + shift(useDefaultPrefixes, right, false); + } + + /** + * Shifts a text block to the right or left using the specified set of prefix characters. + * If white space should be ignored the prefix characters must not be at the beginning of + * the line when shifting to the left. There may be whitespace in front of the prefixes. + * + * @param useDefaultPrefixes says whether the configured default or indent prefixes should be used + * @param right says whether to shift to the right or the left + * @param ignoreWhitespace says whether whitespace in front of prefixes is allowed + * @since 2.0 + */ + protected void shift(bool useDefaultPrefixes, bool right, bool ignoreWhitespace) { + if (fUndoManager !is null) + fUndoManager.beginCompoundChange(); + + IDocument d= getDocument(); + Map partitioners= null; + DocumentRewriteSession rewriteSession= null; + try { + Point selection= getSelectedRange(); + IRegion block= getTextBlockFromSelection(selection); + ITypedRegion[] regions= TextUtilities.computePartitioning(d, getDocumentPartitioning(), block.getOffset(), block.getLength(), false); + + int lineCount= 0; + int[] lines= new int[regions.length * 2]; // [start line, end line, start line, end line, ...] + for (int i= 0, j= 0; i < regions.length; i++, j+= 2) { + // start line of region + lines[j]= getFirstCompleteLineOfRegion(regions[i]); + // end line of region + int length= regions[i].getLength(); + int offset= regions[i].getOffset() + length; + if (length > 0) + offset--; + lines[j + 1]= (lines[j] is -1 ? -1 : d.getLineOfOffset(offset)); + lineCount += lines[j + 1] - lines[j] + 1; + } + + if ( cast(IDocumentExtension4)d ) { + IDocumentExtension4 extension= cast(IDocumentExtension4) d; + rewriteSession= extension.startRewriteSession(DocumentRewriteSessionType.SEQUENTIAL); + } else { + setRedraw(false); + startSequentialRewriteMode(true); + } + if (lineCount >= 20) + partitioners= TextUtilities.removeDocumentPartitioners(d); + + // Perform the shift operation. + Map map= (useDefaultPrefixes ? fDefaultPrefixChars : fIndentChars); + for (int i= 0, j= 0; i < regions.length; i++, j += 2) { + String[] prefixes= stringArrayFromObject(selectContentTypePlugin(regions[i].getType(), map)); + if (prefixes !is null && prefixes.length > 0 && lines[j] >= 0 && lines[j + 1] >= 0) { + if (right) + shiftRight(lines[j], lines[j + 1], prefixes[0]); + else + shiftLeft(lines[j], lines[j + 1], prefixes, ignoreWhitespace); + } + } + + } catch (BadLocationException x) { + if (TRACE_ERRORS) + System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.shift_1")); //$NON-NLS-1$ + + } finally { + + if (partitioners !is null) + TextUtilities.addDocumentPartitioners(d, partitioners); + + if ( cast(IDocumentExtension4)d ) { + IDocumentExtension4 extension= cast(IDocumentExtension4) d; + extension.stopRewriteSession(rewriteSession); + } else { + stopSequentialRewriteMode(); + setRedraw(true); + } + + if (fUndoManager !is null) + fUndoManager.endCompoundChange(); + } + } + + /** + * Shifts the specified lines to the right inserting the given prefix + * at the beginning of each line + * + * @param prefix the prefix to be inserted + * @param startLine the first line to shift + * @param endLine the last line to shift + * @since 2.0 + */ + private void shiftRight(int startLine, int endLine, String prefix) { + + try { + + IDocument d= getDocument(); + while (startLine <= endLine) { + d.replace(d.getLineOffset(startLine++), 0, prefix); + } + + } catch (BadLocationException x) { + if (TRACE_ERRORS) + System.out_.println("TextViewer.shiftRight: BadLocationException"); //$NON-NLS-1$ + } + } + + /** + * Shifts the specified lines to the right or to the left. On shifting to the right + * it insert prefixes[0] at the beginning of each line. On shifting to the + * left it tests whether each of the specified lines starts with one of the specified + * prefixes and if so, removes the prefix. + * + * @param startLine the first line to shift + * @param endLine the last line to shift + * @param prefixes the prefixes to be used for shifting + * @param ignoreWhitespace true if whitespace should be ignored, false otherwise + * @since 2.0 + */ + private void shiftLeft(int startLine, int endLine, String[] prefixes, bool ignoreWhitespace) { + + IDocument d= getDocument(); + + try { + + IRegion[] occurrences= new IRegion[endLine - startLine + 1]; + + // find all the first occurrences of prefix in the given lines + for (int i= 0; i < occurrences.length; i++) { + + IRegion line= d.getLineInformation(startLine + i); + String text= d.get(line.getOffset(), line.getLength()); + + int index= -1; + int[] found= TextUtilities.indexOf(prefixes, text, 0); + if (found[0] !is -1) { + if (ignoreWhitespace) { + String s= d.get(line.getOffset(), found[0]); + s= s.trim(); + if (s.length() is 0) + index= line.getOffset() + found[0]; + } else if (found[0] is 0) + index= line.getOffset(); + } + + if (index > -1) { + // remember where prefix is in line, so that it can be removed + int length= prefixes[found[1]].length(); + if (length is 0 && !ignoreWhitespace && line.getLength() > 0) { + // found a non-empty line which cannot be shifted + return; + } + occurrences[i]= new Region(index, length); + } else { + // found a line which cannot be shifted + return; + } + } + + // OK - change the document + int decrement= 0; + for (int i= 0; i < occurrences.length; i++) { + IRegion r= occurrences[i]; + d.replace(r.getOffset() - decrement, r.getLength(), ""); //$NON-NLS-1$ + decrement += r.getLength(); + } + + } catch (BadLocationException x) { + if (TRACE_ERRORS) + System.out_.println("TextViewer.shiftLeft: BadLocationException"); //$NON-NLS-1$ + } + } + + /** + * Returns whether the shown text can be printed. + * + * @return the viewer's printable mode + */ + protected bool isPrintable() { + /* + * 1GK7Q10: ITPUI:WIN98 - internal error after invoking print at editor view + * Changed from returning true to testing the length of the printer queue + */ + PrinterData[] printerList= Printer.getPrinterList(); + return (printerList !is null && printerList.length > 0); + } + + /** + * {@inheritDoc} + * + * @since 3.4 + */ + public void print(StyledTextPrintOptions options) { + final PrintDialog dialog= new PrintDialog(fTextWidget.getShell(), DWT.PRIMARY_MODAL); + final PrinterData data= dialog.open(); + + if (data !is null) { + final Printer printer= new Printer(data); + final Runnable styledTextPrinter= fTextWidget.print(printer, options); + + void threadrun() { + styledTextPrinter.run(); + printer.dispose(); + } + Thread printingThread= new Thread( &threadrun ); + printingThread.name = "Printing"; //$NON-NLS-1$ + printingThread.start(); + } + } + + /** + * Brings up a print dialog and calls printContents(Printer) + * which performs the actual print. + */ + protected void print() { + StyledTextPrintOptions options= new StyledTextPrintOptions(); + options.printTextFontStyle= true; + options.printTextForeground= true; + print(options); + } + + //------ find support + + /** + * Adheres to the contract of {@link IFindReplaceTarget#canPerformFind()}. + * + * @return true if find can be performed, false otherwise + */ + protected bool canPerformFind() { + IDocument d= getVisibleDocument(); + return (fTextWidget !is null && d !is null && d.getLength() > 0); + } + + /** + * Adheres to the contract of {@link IFindReplaceTarget#findAndSelect(int, String, bool, bool, bool)}. + * + * @param startPosition the start position + * @param findString the find string specification + * @param forwardSearch the search direction + * @param caseSensitive true if case sensitive, false otherwise + * @param wholeWord true if match must be whole words, false otherwise + * @return the model offset of the first match + * @deprecated as of 3.0 use {@link #findAndSelect(int, String, bool, bool, bool, bool)} + */ + protected int findAndSelect(int startPosition, String findString, bool forwardSearch, bool caseSensitive, bool wholeWord) { + try { + return findAndSelect(startPosition, findString, forwardSearch, caseSensitive, wholeWord, false); + } catch (IllegalStateException ex) { + return -1; + } catch (PatternSyntaxException ex) { + return -1; + } + } + + /** + * Adheres to the contract of + * {@link dwtx.jface.text.IFindReplaceTargetExtension3#findAndSelect(int, String, bool, bool, bool, bool)}. + * + * @param startPosition the start position + * @param findString the find string specification + * @param forwardSearch the search direction + * @param caseSensitive true if case sensitive, false otherwise + * @param wholeWord true if matches must be whole words, false otherwise + * @param regExSearch true if findString is a regular expression, false otherwise + * @return the model offset of the first match + * + */ + protected int findAndSelect(int startPosition, String findString, bool forwardSearch, bool caseSensitive, bool wholeWord, bool regExSearch) { + if (fTextWidget is null) + return -1; + + try { + + int widgetOffset= (startPosition is -1 ? startPosition : modelOffset2WidgetOffset(startPosition)); + FindReplaceDocumentAdapter adapter= getFindReplaceDocumentAdapter(); + IRegion matchRegion= adapter.find(widgetOffset, findString, forwardSearch, caseSensitive, wholeWord, regExSearch); + if (matchRegion !is null) { + int widgetPos= matchRegion.getOffset(); + int length= matchRegion.getLength(); + + // Prevents setting of widget selection with line delimiters at beginning or end + char startChar= adapter.charAt(widgetPos); + char endChar= adapter.charAt(widgetPos+length-1); + bool borderHasLineDelimiter= startChar is '\n' || startChar is '\r' || endChar is '\n' || endChar is '\r'; + bool redraws_= redraws(); + if (borderHasLineDelimiter && redraws_) + setRedraw(false); + + if (redraws()) { + fTextWidget.setSelectionRange(widgetPos, length); + internalRevealRange(widgetPos, widgetPos + length); + selectionChanged(widgetPos, length); + } else { + setSelectedRange(widgetOffset2ModelOffset(widgetPos), length); + if (redraws_) + setRedraw(true); + } + + return widgetOffset2ModelOffset(widgetPos); + } + + } catch (BadLocationException x) { + if (TRACE_ERRORS) + System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.findAndSelect")); //$NON-NLS-1$ + } + + return -1; + } + + /** + * Adheres to the contract of {@link dwtx.jface.text.IFindReplaceTargetExtension3#findAndSelect(int, String, bool, bool, bool, bool)}. + * + * @param startPosition the start position + * @param findString the find string specification + * @param forwardSearch the search direction + * @param caseSensitive true if case sensitive, false otherwise + * @param wholeWord true if matches must be whole words, false otherwise + * @param rangeOffset the search scope offset + * @param rangeLength the search scope length + * @param regExSearch true if findString is a regular expression, false otherwise + * @return the model offset of the first match + * @since 3.0 + */ + protected int findAndSelectInRange(int startPosition, String findString, bool forwardSearch, bool caseSensitive, bool wholeWord, int rangeOffset, int rangeLength, bool regExSearch) { + if (fTextWidget is null) + return -1; + + try { + + int modelOffset; + if (forwardSearch && (startPosition is -1 || startPosition < rangeOffset)) { + modelOffset= rangeOffset; + } else if (!forwardSearch && (startPosition is -1 || startPosition > rangeOffset + rangeLength)) { + modelOffset= rangeOffset + rangeLength; + } else { + modelOffset= startPosition; + } + + int widgetOffset= modelOffset2WidgetOffset(modelOffset); + if (widgetOffset is -1) + return -1; + + FindReplaceDocumentAdapter adapter= getFindReplaceDocumentAdapter(); + IRegion matchRegion= adapter.find(widgetOffset, findString, forwardSearch, caseSensitive, wholeWord, regExSearch); + int widgetPos= -1; + int length= 0; + if (matchRegion !is null) { + widgetPos= matchRegion.getOffset(); + length= matchRegion.getLength(); + } + int modelPos= widgetPos is -1 ? -1 : widgetOffset2ModelOffset(widgetPos); + + if (widgetPos !is -1 && (modelPos < rangeOffset || modelPos + length > rangeOffset + rangeLength)) + widgetPos= -1; + + if (widgetPos > -1) { + + // Prevents setting of widget selection with line delimiters at beginning or end + char startChar= adapter.charAt(widgetPos); + char endChar= adapter.charAt(widgetPos+length-1); + bool borderHasLineDelimiter= startChar is '\n' || startChar is '\r' || endChar is '\n' || endChar is '\r'; + bool redraws_= redraws(); + if (borderHasLineDelimiter && redraws_) + setRedraw(false); + + if (redraws()) { + fTextWidget.setSelectionRange(widgetPos, length); + internalRevealRange(widgetPos, widgetPos + length); + selectionChanged(widgetPos, length); + } else { + setSelectedRange(modelPos, length); + if (redraws_) + setRedraw(true); + } + + return modelPos; + } + + + } catch (BadLocationException x) { + if (TRACE_ERRORS) + System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.findAndSelect")); //$NON-NLS-1$ + } + + return -1; + } + + //---------- text presentation support + + /* + * @see ITextViewer#setTextColor(Color) + */ + public void setTextColor(Color color) { + if (color !is null) + setTextColor(color, 0, getDocument().getLength(), true); + } + + /* + * @see ITextViewer#setTextColor(Color, start, length, bool) + */ + public void setTextColor(Color color, int start, int length, bool controlRedraw) { + if (fTextWidget !is null) { + + StyleRange s= new StyleRange(); + s.foreground= color; + s.start= start; + s.length= length; + + s= modelStyleRange2WidgetStyleRange(s); + if (s !is null) { + if (controlRedraw) + fTextWidget.setRedraw(false); + try { + fTextWidget.setStyleRange(s); + } finally { + if (controlRedraw) + fTextWidget.setRedraw(true); + } + } + } + } + + /** + * Adds the given presentation to the viewer's style information. + * + * @param presentation the presentation to be added + */ + private void addPresentation(TextPresentation presentation) { + + StyleRange range= presentation.getDefaultStyleRange(); + if (range !is null) { + + range= modelStyleRange2WidgetStyleRange(range); + if (range !is null) + fTextWidget.setStyleRange(range); + + ArrayList ranges= new ArrayList(presentation.getDenumerableRanges()); + Iterator e= presentation.getNonDefaultStyleRangeIterator(); + while (e.hasNext()) { + range= cast(StyleRange) e.next(); + range= modelStyleRange2WidgetStyleRange(range); + if (range !is null) + ranges.add(range); + } + + if (!ranges.isEmpty()) + fTextWidget.replaceStyleRanges(0, 0, arraycast!(StyleRange)(ranges.toArray())); + + } else { + IRegion region= modelRange2WidgetRange(presentation.getCoverage()); + if (region is null) + return; + + List list= new ArrayList(presentation.getDenumerableRanges()); + Iterator e= presentation.getAllStyleRangeIterator(); + while (e.hasNext()) { + range= cast(StyleRange) e.next(); + range= modelStyleRange2WidgetStyleRange(range); + if (range !is null) + list.add(range); + } + + if (!list.isEmpty()) { + StyleRange[] ranges= new StyleRange[list.size()]; + list.toArray(ranges); + fTextWidget.replaceStyleRanges(region.getOffset(), region.getLength(), ranges); + } + } + } + + /** + * Applies the given presentation to the given text widget. Helper method. + * + * @param presentation the style information + * @since 2.1 + */ + private void applyTextPresentation(TextPresentation presentation) { + + List list= new ArrayList(presentation.getDenumerableRanges()); + Iterator e= presentation.getAllStyleRangeIterator(); + while (e.hasNext()) { + StyleRange range= cast(StyleRange) e.next(); + range= modelStyleRange2WidgetStyleRange(range); + if (range !is null) + list.add(range); + } + + if (!list.isEmpty()) { + StyleRange[] ranges= new StyleRange[list.size()]; + list.toArray(ranges); + fTextWidget.setStyleRanges(ranges); + } + } + + /** + * Returns the visible region if it is not equal to the whole document. + * Otherwise returns null. + * + * @return the viewer's visible region if smaller than input document, otherwise null + */ + protected IRegion _internalGetVisibleRegion() { + + IDocument document= getVisibleDocument(); + if ( cast(ChildDocument)document ) { + Position p= (cast(ChildDocument) document).getParentDocumentRange(); + return new Region(p.getOffset(), p.getLength()); + } + + return null; + } + + /* + * @see ITextViewer#changeTextPresentation(TextPresentation, bool) + */ + public void changeTextPresentation(TextPresentation presentation, bool controlRedraw) { + + if (presentation is null || !redraws()) + return; + + if (fTextWidget is null) + return; + + + /* + * Call registered text presentation listeners + * and let them apply their presentation. + */ + if (fTextPresentationListeners !is null) { + ArrayList listeners= new ArrayList(fTextPresentationListeners); + for (int i= 0, size= listeners.size(); i < size; i++) { + ITextPresentationListener listener= cast(ITextPresentationListener)listeners.get(i); + listener.applyTextPresentation(presentation); + } + } + + if (presentation.isEmpty()) + return; + + if (controlRedraw) + fTextWidget.setRedraw(false); + + if (fReplaceTextPresentation) + applyTextPresentation(presentation); + else + addPresentation(presentation); + + if (controlRedraw) + fTextWidget.setRedraw(true); + } + + /* + * @see ITextViewer#getFindReplaceTarget() + */ + public IFindReplaceTarget getFindReplaceTarget() { + if (fFindReplaceTarget is null) + fFindReplaceTarget= new FindReplaceTarget(); + return fFindReplaceTarget; + } + + /** + * Returns the find/replace document adapter. + * + * @return the find/replace document adapter. + * @since 3.0 + */ + protected FindReplaceDocumentAdapter getFindReplaceDocumentAdapter() { + if (fFindReplaceDocumentAdapter is null) + fFindReplaceDocumentAdapter= new FindReplaceDocumentAdapter(getVisibleDocument()); + return fFindReplaceDocumentAdapter; + } + + /* + * @see ITextViewer#getTextOperationTarget() + */ + public ITextOperationTarget getTextOperationTarget() { + return this; + } + + /* + * @see ITextViewerExtension#appendVerifyKeyListener(VerifyKeyListener) + * @since 2.0 + */ + public void appendVerifyKeyListener(VerifyKeyListener listener) { + int index= fVerifyKeyListenersManager.numberOfListeners(); + fVerifyKeyListenersManager.insertListener(listener, index); + } + + /* + * @see ITextViewerExtension#prependVerifyKeyListener(VerifyKeyListener) + * @since 2.0 + */ + public void prependVerifyKeyListener(VerifyKeyListener listener) { + fVerifyKeyListenersManager.insertListener(listener, 0); + + } + + /* + * @see ITextViewerExtension#removeVerifyKeyListener(VerifyKeyListener) + * @since 2.0 + */ + public void removeVerifyKeyListener(VerifyKeyListener listener) { + fVerifyKeyListenersManager.removeListener(listener); + } + + /* + * @see ITextViewerExtension#getMark() + * @since 2.0 + */ + public int getMark() { + return fMarkPosition is null || fMarkPosition.isDeleted() ? -1 : fMarkPosition.getOffset(); + } + + /* + * @see ITextViewerExtension#setMark(int) + * @since 2.0 + */ + public void setMark(int offset) { + + // clear + if (offset is -1) { + if (fMarkPosition !is null && !fMarkPosition.isDeleted()) { + + IDocument document= getDocument(); + if (document !is null) + document.removePosition(fMarkPosition); + } + + fMarkPosition= null; + + markChanged(-1, 0); + + // set + } else { + + IDocument document= getDocument(); + if (document is null) { + fMarkPosition= null; + return; + } + + if (fMarkPosition !is null) + document.removePosition(fMarkPosition); + + fMarkPosition= null; + + try { + + Position position= new Position(offset); + document.addPosition(MARK_POSITION_CATEGORY, position); + fMarkPosition= position; + + } catch (BadLocationException e) { + return; + } catch (BadPositionCategoryException e) { + return; + } + + markChanged(modelOffset2WidgetOffset(fMarkPosition.offset), 0); + } + } + + /* + * @see Viewer#inputChanged(Object, Object) + * @since 2.0 + */ + protected void inputChanged(Object newInput, Object oldInput) { + + IDocument oldDocument= cast(IDocument) oldInput; + if (oldDocument !is null) { + + if (fMarkPosition !is null && !fMarkPosition.isDeleted()) + oldDocument.removePosition(fMarkPosition); + + try { + oldDocument.removePositionUpdater(fMarkPositionUpdater); + oldDocument.removePositionCategory(MARK_POSITION_CATEGORY); + + } catch (BadPositionCategoryException e) { + } + } + + fMarkPosition= null; + + if ( cast(IDocumentExtension4)oldDocument ) { + IDocumentExtension4 document= cast(IDocumentExtension4) oldDocument; + document.removeDocumentRewriteSessionListener(fDocumentRewriteSessionListener); + } + + super.inputChanged(newInput, oldInput); + + if ( cast(IDocumentExtension4)newInput ) { + IDocumentExtension4 document= cast(IDocumentExtension4) newInput; + document.addDocumentRewriteSessionListener(fDocumentRewriteSessionListener); + } + + IDocument newDocument= cast(IDocument) newInput; + if (newDocument !is null) { + newDocument.addPositionCategory(MARK_POSITION_CATEGORY); + newDocument.addPositionUpdater(fMarkPositionUpdater); + } + } + + /** + * Informs all text listeners about the change of the viewer's redraw state. + * @since 2.0 + */ + private void fireRedrawChanged() { + fWidgetCommand.start= 0; + fWidgetCommand.length= 0; + fWidgetCommand.text= null; + fWidgetCommand.event= null; + updateTextListeners(fWidgetCommand); + } + + /** + * Enables the redrawing of this text viewer. + * @since 2.0 + */ + protected void enabledRedrawing() { + enabledRedrawing(-1); + } + /** + * Enables the redrawing of this text viewer. + * + * @param topIndex the top index to be set or -1 + * @since 3.0 + */ + protected void enabledRedrawing(int topIndex) { + if ( cast(IDocumentAdapterExtension)fDocumentAdapter ) { + IDocumentAdapterExtension extension= cast(IDocumentAdapterExtension) fDocumentAdapter; + StyledText textWidget= getTextWidget(); + if (textWidget !is null && !textWidget.isDisposed()) { + extension.resumeForwardingDocumentChanges(); + if (topIndex > -1) { + try { + setTopIndex(topIndex); + } catch (IllegalArgumentException x) { + // changes don't allow for the previous top pixel + } + } + } + } + + if (fViewerState !is null) { + fViewerState.restore(topIndex is -1); + fViewerState= null; + } + + if (fTextWidget !is null && !fTextWidget.isDisposed()) + fTextWidget.setRedraw(true); + + fireRedrawChanged(); + } + + /** + * Disables the redrawing of this text viewer. Subclasses may extend. + * @since 2.0 + */ + protected void disableRedrawing() { + if (fViewerState is null) + fViewerState= new ViewerState(); + + if ( cast(IDocumentAdapterExtension)fDocumentAdapter ) { + IDocumentAdapterExtension extension= cast(IDocumentAdapterExtension) fDocumentAdapter; + extension.stopForwardingDocumentChanges(); + } + + if (fTextWidget !is null && !fTextWidget.isDisposed()) + fTextWidget.setRedraw(false); + + fireRedrawChanged(); + } + + /* + * @see ITextViewerExtension#setRedraw(bool) + * @since 2.0 + */ + public final void setRedraw(bool redraw) { + setRedraw(redraw, -1); + } + + /** + * Basically same functionality as + * ITextViewerExtension.setRedraw(bool). Adds a way for + * subclasses to pass in a desired top index that should be used when + * redraw is true. If topIndex + * is -1, this method is identical to + * ITextViewerExtension.setRedraw(bool). + * + * @see ITextViewerExtension#setRedraw(bool) + * + * @param redraw + * @param topIndex + * @since 3.0 + */ + protected final void setRedraw(bool redraw, int topIndex) { + if (!redraw) { + + ++ fRedrawCounter; + if (fRedrawCounter is 1) + disableRedrawing(); + + } else { + -- fRedrawCounter; + if (fRedrawCounter is 0) { + if (topIndex is -1) + enabledRedrawing(); + else + enabledRedrawing(topIndex); + } + } + } + + /** + * Returns whether this viewer redraws itself. + * + * @return true if this viewer redraws itself + * @since 2.0 + */ + protected final bool redraws() { + return fRedrawCounter <= 0; + } + + /** + * Starts the sequential rewrite mode of the viewer's document. + * + * @param normalized true if the rewrite is performed from the start to the end of the document + * @since 2.0 + * @deprecated since 3.1 use {@link IDocumentExtension4#startRewriteSession(DocumentRewriteSessionType)} instead + */ + protected final void startSequentialRewriteMode(bool normalized) { + IDocument document= getDocument(); + if ( cast(IDocumentExtension)document ) { + IDocumentExtension extension= cast(IDocumentExtension) document; + extension.startSequentialRewrite(normalized); + } + } + + /** + * Sets the sequential rewrite mode of the viewer's document. + * + * @since 2.0 + * @deprecated since 3.1 use {@link IDocumentExtension4#stopRewriteSession(DocumentRewriteSession)} instead + */ + protected final void stopSequentialRewriteMode() { + IDocument document= getDocument(); + if ( cast(IDocumentExtension)document ) { + IDocumentExtension extension= cast(IDocumentExtension) document; + extension.stopSequentialRewrite(); + } + } + + /* + * @see dwtx.jface.text.ITextViewerExtension#getRewriteTarget() + * @since 2.0 + */ + public IRewriteTarget getRewriteTarget() { + if (fRewriteTarget is null) + fRewriteTarget= new RewriteTarget(); + return fRewriteTarget; + } + + /* + * @see dwtx.jface.text.ITextViewerExtension2#getCurrentTextHover() + */ + public ITextHover getCurrentTextHover() { + if (fTextHoverManager is null) + return null; + return fTextHoverManager.getCurrentTextHover_package(); + } + + /* + * @see dwtx.jface.text.ITextViewerExtension2#getHoverEventLocation() + */ + public Point getHoverEventLocation() { + if (fTextHoverManager is null) + return null; + return fTextHoverManager.getHoverEventLocation_package(); + } + + /** + * Returns the paint manager of this viewer. + * + * @return the paint manager of this viewer + * @since 2.1 + */ + protected PaintManager getPaintManager() { + if (fPaintManager is null) + fPaintManager= new PaintManager(this); + return fPaintManager; + } + + /** + * Adds the given painter to this viewer. If the painter is already registered + * this method is without effect. + * + * @param painter the painter to be added + * @since 2.1 + */ + public void addPainter(IPainter painter) { + getPaintManager().addPainter(painter); + } + + /** + * Removes the given painter from this viewer. If the painter has previously not been + * added to this viewer this method is without effect. + * + * @param painter the painter to be removed + * @since 2.1 + */ + public void removePainter(IPainter painter) { + getPaintManager().removePainter(painter); + } + + // ----------------------------------- conversions ------------------------------------------------------- + + /** + * Implements the contract of {@link ITextViewerExtension5#modelLine2WidgetLine(int)}. + * + * @param modelLine the model line + * @return the corresponding widget line or -1 + * @since 2.1 + */ + public int modelLine2WidgetLine(int modelLine) { + if (fInformationMapping is null) + return modelLine; + + try { + return fInformationMapping.toImageLine(modelLine); + } catch (BadLocationException x) { + } + + return -1; + } + + /** + * Implements the contract of {@link ITextViewerExtension5#modelOffset2WidgetOffset(int)}. + * + * @param modelOffset the model offset + * @return the corresponding widget offset or -1 + * @since 2.1 + */ + public int modelOffset2WidgetOffset(int modelOffset) { + if (fInformationMapping is null) + return modelOffset; + + try { + return fInformationMapping.toImageOffset(modelOffset); + } catch (BadLocationException x) { + } + + return -1; + } + + /** + * Implements the contract of {@link ITextViewerExtension5#modelRange2WidgetRange(IRegion)}. + * + * @param modelRange the model range + * @return the corresponding widget range or null + * @since 2.1 + */ + public IRegion modelRange2WidgetRange(IRegion modelRange) { + if (fInformationMapping is null) + return modelRange; + + try { + + if (modelRange.getLength() < 0) { + Region reversed= new Region(modelRange.getOffset() + modelRange.getLength(), -modelRange.getLength()); + IRegion result= fInformationMapping.toImageRegion(reversed); + if (result !is null) + return new Region(result.getOffset() + result.getLength(), -result.getLength()); + } + return fInformationMapping.toImageRegion(modelRange); + + } catch (BadLocationException x) { + } + + return null; + } + + /** + * Similar to {@link #modelRange2WidgetRange(IRegion)}, but more forgiving: + * if modelRange describes a region entirely hidden in the + * image, then this method returns the zero-length region at the offset of + * the folded region. + * + * @param modelRange the model range + * @return the corresponding widget range, or null + * @since 3.1 + */ + protected IRegion modelRange2ClosestWidgetRange(IRegion modelRange) { + if (!( cast(IDocumentInformationMappingExtension2)fInformationMapping )) + return modelRange2WidgetRange(modelRange); + + try { + if (modelRange.getLength() < 0) { + Region reversed= new Region(modelRange.getOffset() + modelRange.getLength(), -modelRange.getLength()); + IRegion result= (cast(IDocumentInformationMappingExtension2) fInformationMapping).toClosestImageRegion(reversed); + if (result !is null) + return new Region(result.getOffset() + result.getLength(), -result.getLength()); + } + return (cast(IDocumentInformationMappingExtension2) fInformationMapping).toClosestImageRegion(modelRange); + + } catch (BadLocationException x) { + } + + return null; + } + + /** + * Implements the contract of {@link ITextViewerExtension5#widgetLine2ModelLine(int)}. + * + * @param widgetLine the widget line + * @return the corresponding model line + * @since 2.1 + */ + public int widgetlLine2ModelLine(int widgetLine) { + return widgetLine2ModelLine(widgetLine); + } + + /** + * Implements the contract of {@link ITextViewerExtension5#widgetLine2ModelLine(int)}. + * + * @param widgetLine the widget line + * @return the corresponding model line or -1 + * @since 3.0 + */ + public int widgetLine2ModelLine(int widgetLine) { + if (fInformationMapping is null) + return widgetLine; + + try { + return fInformationMapping.toOriginLine(widgetLine); + } catch (BadLocationException x) { + } + + return -1; + } + + /** + * Implements the contract of {@link ITextViewerExtension5#widgetOffset2ModelOffset(int)}. + * + * @param widgetOffset the widget offset + * @return the corresponding model offset or -1 + * @since 2.1 + */ + public int widgetOffset2ModelOffset(int widgetOffset) { + if (fInformationMapping is null) + return widgetOffset; + + try { + return fInformationMapping.toOriginOffset(widgetOffset); + } catch (BadLocationException x) { + if (widgetOffset is getVisibleDocument().getLength()) { + IRegion coverage= fInformationMapping.getCoverage(); + return coverage.getOffset() + coverage.getLength(); + } + } + + return -1; + } + + /** + * Implements the contract of {@link ITextViewerExtension5#widgetRange2ModelRange(IRegion)}. + * + * @param widgetRange the widget range + * @return the corresponding model range or null + * @since 2.1 + */ + public IRegion widgetRange2ModelRange(IRegion widgetRange) { + if (fInformationMapping is null) + return widgetRange; + + try { + + if (widgetRange.getLength() < 0) { + Region reveresed= new Region(widgetRange.getOffset() + widgetRange.getLength(), -widgetRange.getLength()); + IRegion result= fInformationMapping.toOriginRegion(reveresed); + return new Region(result.getOffset() + result.getLength(), -result.getLength()); + } + + return fInformationMapping.toOriginRegion(widgetRange); + + } catch (BadLocationException x) { + int modelOffset= widgetOffset2ModelOffset(widgetRange.getOffset()); + if (modelOffset > -1) { + int modelEndOffset= widgetOffset2ModelOffset(widgetRange.getOffset() + widgetRange.getLength()); + if (modelEndOffset > -1) + return new Region(modelOffset, modelEndOffset - modelOffset); + } + } + + return null; + } + + /** + * Implements the contract of {@link ITextViewerExtension5#getModelCoverage()}. + * + * @return the model coverage + * @since 2.1 + */ + public IRegion getModelCoverage() { + if (fInformationMapping is null) { + IDocument document= getDocument(); + if (document is null) + return null; + return new Region(0, document.getLength()); + } + + return fInformationMapping.getCoverage(); + } + + /** + * Returns the line of the widget whose corresponding line in the viewer's document + * is closest to the given line in the viewer's document or -1. + * + * @param modelLine the line in the viewer's document + * @return the line in the widget that corresponds best to the given line in the viewer's document or -1 + * @since 2.1 + */ + protected int getClosestWidgetLineForModelLine(int modelLine) { + if (fInformationMapping is null) + return modelLine; + + try { + return fInformationMapping.toClosestImageLine(modelLine); + } catch (BadLocationException x) { + } + + return -1; + } + + /** + * Translates a style range given relative to the viewer's document into style + * ranges relative to the viewer's widget or null. + * + * @param range the style range in the coordinates of the viewer's document + * @return the style range in the coordinates of the viewer's widget or null + * @since 2.1 + */ + protected StyleRange modelStyleRange2WidgetStyleRange(StyleRange range) { + IRegion region= modelRange2WidgetRange(new Region(range.start, range.length)); + if (region !is null) { + StyleRange result= cast(StyleRange) range.clone(); + result.start= region.getOffset(); + result.length= region.getLength(); + return result; + } + return null; + } + + /** + * Same as {@link #modelRange2WidgetRange(IRegion)} just for a {@link dwtx.jface.text.Position}. + * + * @param modelPosition the position describing a range in the viewer's document + * @return a region describing a range in the viewer's widget + * @since 2.1 + */ + protected IRegion modelRange2WidgetRange(Position modelPosition) { + return modelRange2WidgetRange(new Region(modelPosition.getOffset(), modelPosition.getLength())); + } + + /** + * Translates the widget region of the given verify event into + * the corresponding region of the viewer's document. + * + * @param event the verify event + * @return the region of the viewer's document corresponding to the verify event + * @since 2.1 + */ + protected IRegion event2ModelRange(VerifyEvent event) { + + Region region= null; + if (event.start <= event.end) + region= new Region(event.start, event.end - event.start); + else + region= new Region(event.end, event.start - event.end); + + return widgetRange2ModelRange(region); + } + + /** + * Translates the given widget selection into the corresponding region + * of the viewer's document or returns null if this fails. + * + * @param widgetSelection the widget selection + * @return the region of the viewer's document corresponding to the widget selection or null + * @since 2.1 + */ + protected Point widgetSelection2ModelSelection(Point widgetSelection) { + IRegion region= new Region(widgetSelection.x, widgetSelection.y); + region= widgetRange2ModelRange(region); + return region is null ? null : new Point(region.getOffset(), region.getLength()); + } + + /** + * Translates the given selection range of the viewer's document into + * the corresponding widget range or returns null of this fails. + * + * @param modelSelection the selection range of the viewer's document + * @return the widget range corresponding to the selection range or null + * @since 2.1 + */ + protected Point modelSelection2WidgetSelection(Point modelSelection) { + if (fInformationMapping is null) + return modelSelection; + + try { + IRegion region= new Region(modelSelection.x, modelSelection.y); + region= fInformationMapping.toImageRegion(region); + if (region !is null) + return new Point(region.getOffset(), region.getLength()); + } catch (BadLocationException x) { + } + + return null; + } + + /** + * Implements the contract of {@link ITextViewerExtension5#widgetLineOfWidgetOffset(int)}. + * + * @param widgetOffset the widget offset + * @return the corresponding widget line or -1 + * @since 2.1 + */ + public int widgetLineOfWidgetOffset(int widgetOffset) { + IDocument document= getVisibleDocument(); + if (document !is null) { + try { + return document.getLineOfOffset(widgetOffset); + } catch (BadLocationException e) { + } + } + return -1; + } + + /* + * @see dwtx.jface.text.ITextViewerExtension4#moveFocusToWidgetToken() + * @since 3.0 + */ + public bool moveFocusToWidgetToken() { + if ( cast(IWidgetTokenKeeperExtension)fWidgetTokenKeeper ) { + IWidgetTokenKeeperExtension extension= cast(IWidgetTokenKeeperExtension) fWidgetTokenKeeper; + return extension.setFocus(this); + } + return false; + } + + /** + * Sets the document partitioning of this viewer. The partitioning is used by this viewer to + * access partitioning information of the viewers input document. + * + * @param partitioning the partitioning name + * @since 3.0 + */ + public void setDocumentPartitioning(String partitioning) { + fPartitioning= partitioning; + } + + /** + * Returns the document partitioning for this viewer. + * + * @return the document partitioning for this viewer + * @since 3.0 + */ + protected String getDocumentPartitioning() { + return fPartitioning; + } + + //---- Text presentation listeners ---- + + /* + * @see ITextViewerExtension4#addTextPresentationListener(ITextPresentationListener) + * @since 3.0 + */ + public void addTextPresentationListener(ITextPresentationListener listener) { + + Assert.isNotNull(cast(Object)listener); + + if (fTextPresentationListeners is null) + fTextPresentationListeners= new ArrayList(); + + if (!fTextPresentationListeners.contains(cast(Object)listener)) + fTextPresentationListeners.add(cast(Object)listener); + } + + /* + * @see ITextViewerExtension4#removeTextPresentationListener(ITextPresentationListener) + * @since 3.0 + */ + public void removeTextPresentationListener(ITextPresentationListener listener) { + + Assert.isNotNull(cast(Object)listener); + + if (fTextPresentationListeners !is null) { + fTextPresentationListeners.remove(cast(Object)listener); + if (fTextPresentationListeners.size() is 0) + fTextPresentationListeners= null; + } + } + + /* + * @see dwtx.jface.text.IEditingSupportRegistry#registerHelper(dwtx.jface.text.IEditingSupport) + * @since 3.1 + */ + public void register(IEditingSupport helper) { + Assert.isLegal(helper !is null); + fEditorHelpers.add(cast(Object)helper); + } + + /* + * @see dwtx.jface.text.IEditingSupportRegistry#deregisterHelper(dwtx.jface.text.IEditingSupport) + * @since 3.1 + */ + public void unregister(IEditingSupport helper) { + fEditorHelpers.remove(cast(Object)helper); + } + + /* + * @see dwtx.jface.text.IEditingSupportRegistry#getCurrentHelpers() + * @since 3.1 + */ + public IEditingSupport[] getRegisteredSupports() { + return arraycast!(IEditingSupport)( fEditorHelpers.toArray()); + } + + /* + * @see dwtx.jface.text.ITextViewerExtension6#setHyperlinkDetectors(dwtx.jface.text.hyperlink.IHyperlinkDetector[], int) + * @since 3.1 + */ + public void setHyperlinkDetectors(IHyperlinkDetector[] hyperlinkDetectors, int eventStateMask) { + if (fHyperlinkDetectors !is null) { + for (int i= 0; i < fHyperlinkDetectors.length; i++) { + if (cast(IHyperlinkDetectorExtension)fHyperlinkDetectors[i] ) + (cast(IHyperlinkDetectorExtension)fHyperlinkDetectors[i]).dispose(); + } + } + + bool enable= hyperlinkDetectors !is null && hyperlinkDetectors.length > 0; + fHyperlinkStateMask= eventStateMask; + fHyperlinkDetectors= hyperlinkDetectors; + if (enable) { + if (fHyperlinkManager !is null) { + fHyperlinkManager.setHyperlinkDetectors(fHyperlinkDetectors); + fHyperlinkManager.setHyperlinkStateMask(fHyperlinkStateMask); + } + ensureHyperlinkManagerInstalled(); + } else { + if (fHyperlinkManager !is null) + fHyperlinkManager.uninstall(); + fHyperlinkManager= null; + } + } + + /** + * Sets the hyperlink presenter. + *

                + * This is only valid as long as the hyperlink manager hasn't + * been created yet. + *

                + * + * @param hyperlinkPresenter the hyperlink presenter + * @throws IllegalStateException if the hyperlink manager has already been created + * @since 3.1 + */ + public void setHyperlinkPresenter(IHyperlinkPresenter hyperlinkPresenter) { + if (fHyperlinkManager !is null) + throw new IllegalStateException(); + + fHyperlinkPresenter= hyperlinkPresenter; + ensureHyperlinkManagerInstalled(); + } + + /** + * Ensures that the hyperlink manager has been + * installed if a hyperlink detector is available. + * + * @since 3.1 + */ + private void ensureHyperlinkManagerInstalled() { + if (fHyperlinkDetectors !is null && fHyperlinkDetectors.length > 0 && fHyperlinkPresenter !is null && fHyperlinkManager is null) { + HyperlinkManager.DETECTION_STRATEGY strategy= fHyperlinkPresenter.canShowMultipleHyperlinks() ? HyperlinkManager.ALL : HyperlinkManager.FIRST; + fHyperlinkManager= new HyperlinkManager(strategy); + fHyperlinkManager.install(this, fHyperlinkPresenter, fHyperlinkDetectors, fHyperlinkStateMask); + } + } + + /* + * @see dwtx.jface.text.ITextViewerExtension7#setTabsToSpacesConverter(dwtx.jface.text.IAutoEditStrategy) + * @since 3.3 + */ + public void setTabsToSpacesConverter(IAutoEditStrategy converter) { + fTabsToSpacesConverter= converter; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/TextViewerHoverManager.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/TextViewerHoverManager.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,541 @@ +/******************************************************************************* + * 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 + * 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.text.TextViewerHoverManager; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; +import tango.core.Thread; + +import dwt.custom.StyledText; +import dwt.events.MouseEvent; +import dwt.events.MouseMoveListener; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Display; +import dwtx.core.runtime.ILog; +import dwtx.core.runtime.IStatus; +import dwtx.core.runtime.Platform; +import dwtx.core.runtime.Status; + + +/** + * This manager controls the layout, content, and visibility of an information + * control in reaction to mouse hover events issued by the text widget of a + * text viewer. It overrides computeInformation, so that the + * computation is performed in a dedicated background thread. This implies + * that the used ITextHover objects must be capable of + * operating in a non-UI thread. + * + * @since 2.0 + */ +class TextViewerHoverManager : AbstractHoverInformationControlManager , IWidgetTokenKeeper, IWidgetTokenKeeperExtension { + + + /** + * Priority of the hovers managed by this manager. + * Default value: 0; + * @since 3.0 + */ + public const static int WIDGET_PRIORITY= 0; + + + /** The text viewer */ + private TextViewer fTextViewer; + /** The hover information computation thread */ + private Thread fThread; + /** The stopper of the computation thread */ + private ITextListener fStopper; + /** Internal monitor */ + private Object fMutex; + /** The currently shown text hover. */ + private /+volatile+/ ITextHover fTextHover; + /** + * Tells whether the next mouse hover event + * should be processed. + * @since 3.0 + */ + private bool fProcessMouseHoverEvent= true; + /** + * Internal mouse move listener. + * @since 3.0 + */ + private MouseMoveListener fMouseMoveListener; + /** + * Internal view port listener. + * @since 3.0 + */ + private IViewportListener fViewportListener; + + + /** + * Creates a new text viewer hover manager specific for the given text viewer. + * The manager uses the given information control creator. + * + * @param textViewer the viewer for which the controller is created + * @param creator the information control creator + */ + public this(TextViewer textViewer, IInformationControlCreator creator) { + fMutex= new Object(); + super(creator); + fTextViewer= textViewer; + fStopper= new class() ITextListener { + public void textChanged(TextEvent event) { + synchronized (fMutex) { + if (fThread !is null) { +implMissing(__FILE__,__LINE__); +// DWT FIXME: how to handle Thread.interrupt? +// fThread.interrupt(); + fThread= null; + } + } + } + }; + fViewportListener= new class() IViewportListener { + /* + * @see dwtx.jface.text.IViewportListener#viewportChanged(int) + */ + public void viewportChanged(int verticalOffset) { + fProcessMouseHoverEvent= false; + } + }; + fTextViewer.addViewportListener(fViewportListener); + fMouseMoveListener= new class() MouseMoveListener { + /* + * @see MouseMoveListener#mouseMove(MouseEvent) + */ + public void mouseMove(MouseEvent event) { + fProcessMouseHoverEvent= true; + } + }; + fTextViewer.getTextWidget().addMouseMoveListener(fMouseMoveListener); + } + + /** + * Determines all necessary details and delegates the computation into + * a background thread. + */ + protected void computeInformation() { + + if (!fProcessMouseHoverEvent) { + setInformation(cast(Object)null, null); + return; + } + + Point location= getHoverEventLocation(); + int offset= computeOffsetAtLocation(location.x, location.y); + if (offset is -1) { + setInformation(cast(Object)null, null); + return; + } + + final ITextHover hover= fTextViewer.getTextHover_package(offset, getHoverEventStateMask()); + if (hover is null) { + setInformation(cast(Object)null, null); + return; + } + + final IRegion region= hover.getHoverRegion(fTextViewer, offset); + if (region is null) { + setInformation(cast(Object)null, null); + return; + } + + final Rectangle area= JFaceTextUtil.computeArea(region, fTextViewer); + if (area is null || area.isEmpty()) { + setInformation(cast(Object)null, null); + return; + } + + if (fThread !is null) { + setInformation(cast(Object)null, null); + return; + } + + void threadrun() { + // http://bugs.eclipse.org/bugs/show_bug.cgi?id=17693 + bool hasFinished= false; + try { + if (fThread !is null) { + Object information; + try { + if ( cast(ITextHoverExtension2)hover ) + information= (cast(ITextHoverExtension2)hover).getHoverInfo2(fTextViewer, region); + else + information= stringcast(hover.getHoverInfo(fTextViewer, region)); + } catch (ArrayIndexOutOfBoundsException x) { + /* + * This code runs in a separate thread which can + * lead to text offsets being out of bounds when + * computing the hover info (see bug 32848). + */ + information= null; + } + + if ( cast(ITextHoverExtension)hover ) + setCustomInformationControlCreator((cast(ITextHoverExtension) hover).getHoverControlCreator()); + else + setCustomInformationControlCreator(null); + + setInformation(information, area); + if (information !is null) + fTextHover= hover; + } else { + setInformation(cast(Object)null, null); + } + hasFinished= true; + } catch (RuntimeException ex) { + String PLUGIN_ID= "dwtx.jface.text"; //$NON-NLS-1$ + ILog log= Platform.getLog(Platform.getBundle(PLUGIN_ID)); + log.log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.OK, "Unexpected runtime error while computing a text hover", ex)); //$NON-NLS-1$ + } finally { + synchronized (fMutex) { + if (fTextViewer !is null) + fTextViewer.removeTextListener(fStopper); + fThread= null; + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=44756 + if (!hasFinished) + setInformation(cast(Object)null, null); + } + } + } + fThread= new Thread( &threadrun ); + fThread.name = "Text Viewer Hover Presenter"; //$NON-NLS-1$ + + fThread.isDaemon(true); + fThread.priority(Thread.PRIORITY_MIN); + synchronized (fMutex) { + fTextViewer.addTextListener(fStopper); + fThread.start(); + } + } + + /** + * As computation is done in the background, this method is + * also called in the background thread. Delegates the control + * flow back into the UI thread, in order to allow displaying the + * information in the information control. + */ + protected void presentInformation() { + if (fTextViewer is null) + return; + + StyledText textWidget= fTextViewer.getTextWidget(); + if (textWidget !is null && !textWidget.isDisposed()) { + Display display= textWidget.getDisplay(); + if (display is null) + return; + + display.asyncExec(new class() Runnable { + public void run() { + doPresentInformation(); + } + }); + } + } + + /* + * @see AbstractInformationControlManager#presentInformation() + */ + protected void doPresentInformation() { + super.presentInformation(); + } + + /** + * Computes the document offset underlying the given text widget coordinates. + * This method uses a linear search as it cannot make any assumption about + * how the document is actually presented in the widget. (Covers cases such + * as bidirectional text.) + * + * @param x the horizontal coordinate inside the text widget + * @param y the vertical coordinate inside the text widget + * @return the document offset corresponding to the given point + */ + private int computeOffsetAtLocation(int x, int y) { + + try { + + StyledText styledText= fTextViewer.getTextWidget(); + int widgetOffset= styledText.getOffsetAtLocation(new Point(x, y)); + Point p= styledText.getLocationAtOffset(widgetOffset); + if (p.x > x) + widgetOffset--; + + if ( cast(ITextViewerExtension5)fTextViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) fTextViewer; + return extension.widgetOffset2ModelOffset(widgetOffset); + } + + return widgetOffset + fTextViewer._getVisibleRegionOffset_package(); + + } catch (IllegalArgumentException e) { + return -1; + } + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#showInformationControl(dwt.graphics.Rectangle) + */ + protected void showInformationControl(Rectangle subjectArea) { + if (fTextViewer !is null && fTextViewer.requestWidgetToken(this, WIDGET_PRIORITY)) + super.showInformationControl(subjectArea); + else + if (DEBUG) + System.out_.println("TextViewerHoverManager#showInformationControl(..) did not get widget token"); //$NON-NLS-1$ + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#hideInformationControl() + */ + protected void hideInformationControl() { + try { + fTextHover= null; + super.hideInformationControl(); + } finally { + if (fTextViewer !is null) + fTextViewer.releaseWidgetToken(this); + } + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#replaceInformationControl(bool) + * @since 3.4 + */ + void replaceInformationControl(bool takeFocus) { + if (fTextViewer !is null) + fTextViewer.releaseWidgetToken(this); + super.replaceInformationControl(takeFocus); + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#handleInformationControlDisposed() + */ + protected void handleInformationControlDisposed() { + try { + super.handleInformationControlDisposed(); + } finally { + if (fTextViewer !is null) + fTextViewer.releaseWidgetToken(this); + } + } + + /* + * @see dwtx.jface.text.IWidgetTokenKeeper#requestWidgetToken(dwtx.jface.text.IWidgetTokenOwner) + */ + public bool requestWidgetToken(IWidgetTokenOwner owner) { + fTextHover= null; + super.hideInformationControl(); + return true; + } + + /* + * @see dwtx.jface.text.IWidgetTokenKeeperExtension#requestWidgetToken(dwtx.jface.text.IWidgetTokenOwner, int) + * @since 3.0 + */ + public bool requestWidgetToken(IWidgetTokenOwner owner, int priority) { + if (priority > WIDGET_PRIORITY) { + fTextHover= null; + super.hideInformationControl(); + return true; + } + return false; + } + + /* + * @see dwtx.jface.text.IWidgetTokenKeeperExtension#setFocus(dwtx.jface.text.IWidgetTokenOwner) + * @since 3.0 + */ + public bool setFocus(IWidgetTokenOwner owner) { + if (! hasInformationControlReplacer()) + return false; + + IInformationControl iControl= getCurrentInformationControl(); + if (canReplace(iControl)) { + if (cancelReplacingDelay()) + replaceInformationControl(true); + + return true; + } + + return false; + } + + /** + * Returns the currently shown text hover or null if no text + * hover is shown. + * + * @return the currently shown text hover or null + */ + protected ITextHover getCurrentTextHover() { + return fTextHover; + } + package ITextHover getCurrentTextHover_package() { + return getCurrentTextHover(); + } + + /* + * @see dwtx.jface.text.AbstractHoverInformationControlManager#dispose() + * @since 3.0 + */ + public void dispose() { + if (fTextViewer !is null) { + fTextViewer.removeViewportListener(fViewportListener); + fViewportListener= null; + + StyledText st= fTextViewer.getTextWidget(); + if (st !is null && !st.isDisposed()) + st.removeMouseMoveListener(fMouseMoveListener); + fMouseMoveListener= null; + } + super.dispose(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/TextViewerUndoManager.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/TextViewerUndoManager.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,588 @@ +/******************************************************************************* + * 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 + * 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.text.TextViewerUndoManager; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; + + + + + +import dwt.DWT; +import dwt.custom.StyledText; +import dwt.events.KeyEvent; +import dwt.events.KeyListener; +import dwt.events.MouseEvent; +import dwt.events.MouseListener; +import dwt.widgets.Display; +import dwt.widgets.Shell; +import dwtx.core.commands.ExecutionException; +import dwtx.core.commands.operations.IUndoContext; +import dwtx.jface.dialogs.MessageDialog; +import dwtx.text.undo.DocumentUndoEvent; +import dwtx.text.undo.DocumentUndoManager; +import dwtx.text.undo.DocumentUndoManagerRegistry; +import dwtx.text.undo.IDocumentUndoListener; +import dwtx.text.undo.IDocumentUndoManager; + + +/** + * Implementation of {@link dwtx.jface.text.IUndoManager} using the shared + * document undo manager. + *

                + * It registers with the connected text viewer as text input listener, and obtains + * its undo manager from the current document. It also monitors mouse and keyboard + * activities in order to partition the stream of text changes into undo-able + * edit commands. + *

                + * This class is not intended to be subclassed. + *

                + * + * @see ITextViewer + * @see ITextInputListener + * @see IDocumentUndoManager + * @see MouseListener + * @see KeyListener + * @see DocumentUndoManager + * + * @since 3.2 + * @noextend This class is not intended to be subclassed by clients. + */ +public class TextViewerUndoManager : IUndoManager, IUndoManagerExtension { + + + /** + * Internal listener to mouse and key events. + */ + private class KeyAndMouseListener : MouseListener, KeyListener { + + /* + * @see MouseListener#mouseDoubleClick + */ + public void mouseDoubleClick(MouseEvent e) { + } + + /* + * If the right mouse button is pressed, the current editing command is closed + * @see MouseListener#mouseDown + */ + public void mouseDown(MouseEvent e) { + if (e.button is 1) + if (isConnected()) + fDocumentUndoManager.commit(); + } + + /* + * @see MouseListener#mouseUp + */ + public void mouseUp(MouseEvent e) { + } + + /* + * @see KeyListener#keyPressed + */ + public void keyReleased(KeyEvent e) { + } + + /* + * On cursor keys, the current editing command is closed + * @see KeyListener#keyPressed + */ + public void keyPressed(KeyEvent e) { + switch (e.keyCode) { + case DWT.ARROW_UP: + case DWT.ARROW_DOWN: + case DWT.ARROW_LEFT: + case DWT.ARROW_RIGHT: + if (isConnected()) { + fDocumentUndoManager.commit(); + } + break; + } + } + } + + + /** + * Internal text input listener. + */ + private class TextInputListener : ITextInputListener { + + /* + * @see dwtx.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument) + */ + public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { + disconnectDocumentUndoManager(); + } + + /* + * @see dwtx.jface.text.ITextInputListener#inputDocumentChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument) + */ + public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { + connectDocumentUndoManager(newInput); + } + } + + + /** + * Internal document undo listener. + */ + private class DocumentUndoListener : IDocumentUndoListener { + + /* + * @see dwtx.jface.text.IDocumentUndoListener#documentUndoNotification(DocumentUndoEvent) + */ + public void documentUndoNotification(DocumentUndoEvent event ){ + if (!isConnected()) return; + + int eventType= event.getEventType(); + if (((eventType & DocumentUndoEvent.ABOUT_TO_UNDO) !is 0) || ((eventType & DocumentUndoEvent.ABOUT_TO_REDO) !is 0)) { + if (event.isCompound()) { + ITextViewerExtension extension= null; + if ( cast(ITextViewerExtension)fTextViewer ) + extension= cast(ITextViewerExtension) fTextViewer; + + if (extension !is null) + extension.setRedraw(false); + } + fTextViewer.getTextWidget().getDisplay().syncExec(new class() Runnable { + public void run() { + if ( cast(TextViewer)fTextViewer ) + (cast(TextViewer)fTextViewer).ignoreAutoEditStrategies_package(true); + } + }); + + } else if (((eventType & DocumentUndoEvent.UNDONE) !is 0) || ((eventType & DocumentUndoEvent.REDONE) !is 0)) { + fTextViewer.getTextWidget().getDisplay().syncExec(new class() Runnable { + public void run() { + if ( cast(TextViewer)fTextViewer ) + (cast(TextViewer)fTextViewer).ignoreAutoEditStrategies_package(false); + } + }); + if (event.isCompound()) { + ITextViewerExtension extension= null; + if ( cast(ITextViewerExtension)fTextViewer ) + extension= cast(ITextViewerExtension) fTextViewer; + + if (extension !is null) + extension.setRedraw(true); + } + + // Reveal the change if this manager's viewer has the focus. + if (fTextViewer !is null) { + StyledText widget= fTextViewer.getTextWidget(); + if (widget !is null && !widget.isDisposed() && (widget.isFocusControl()))// || fTextViewer.getTextWidget() is control)) + selectAndReveal(event.getOffset(), event.getText() is null ? 0 : event.getText().length()); + } + } + } + + } + + /** The internal key and mouse event listener */ + private KeyAndMouseListener fKeyAndMouseListener; + /** The internal text input listener */ + private TextInputListener fTextInputListener; + + + /** The text viewer the undo manager is connected to */ + private ITextViewer fTextViewer; + + /** The undo level */ + private int fUndoLevel; + + /** The document undo manager that is active. */ + private IDocumentUndoManager fDocumentUndoManager; + + /** The document that is active. */ + private IDocument fDocument; + + /** The document undo listener */ + private IDocumentUndoListener fDocumentUndoListener; + + /** + * Creates a new undo manager who remembers the specified number of edit commands. + * + * @param undoLevel the length of this manager's history + */ + public this(int undoLevel) { + fUndoLevel= undoLevel; + } + + /** + * Returns whether this undo manager is connected to a text viewer. + * + * @return true if connected, false otherwise + */ + private bool isConnected() { + return fTextViewer !is null && fDocumentUndoManager !is null; + } + + /* + * @see IUndoManager#beginCompoundChange + */ + public void beginCompoundChange() { + if (isConnected()) { + fDocumentUndoManager.beginCompoundChange(); + } + } + + + /* + * @see IUndoManager#endCompoundChange + */ + public void endCompoundChange() { + if (isConnected()) { + fDocumentUndoManager.endCompoundChange(); + } + } + + /** + * Registers all necessary listeners with the text viewer. + */ + private void addListeners() { + StyledText text= fTextViewer.getTextWidget(); + if (text !is null) { + fKeyAndMouseListener= new KeyAndMouseListener(); + text.addMouseListener(fKeyAndMouseListener); + text.addKeyListener(fKeyAndMouseListener); + fTextInputListener= new TextInputListener(); + fTextViewer.addTextInputListener(fTextInputListener); + } + } + + /** + * Unregister all previously installed listeners from the text viewer. + */ + private void removeListeners() { + StyledText text= fTextViewer.getTextWidget(); + if (text !is null) { + if (fKeyAndMouseListener !is null) { + text.removeMouseListener(fKeyAndMouseListener); + text.removeKeyListener(fKeyAndMouseListener); + fKeyAndMouseListener= null; + } + if (fTextInputListener !is null) { + fTextViewer.removeTextInputListener(fTextInputListener); + fTextInputListener= null; + } + } + } + + /** + * Shows the given exception in an error dialog. + * + * @param title the dialog title + * @param ex the exception + */ + private void openErrorDialog(String title, Exception ex) { + Shell shell= null; + if (isConnected()) { + StyledText st= fTextViewer.getTextWidget(); + if (st !is null && !st.isDisposed()) + shell= st.getShell(); + } + if (Display.getCurrent() !is null) + MessageDialog.openError(shell, title, ex.msg/+getLocalizedMessage()+/); + else { + Display display; + Shell finalShell= shell; + if (finalShell !is null) + display= finalShell.getDisplay(); + else + display= Display.getDefault(); + display.syncExec(dgRunnable((Shell finalShell_, String title_, Exception ex_ ) { + MessageDialog.openError(finalShell_, title_, ex_.msg/+getLocalizedMessage()+/); + },finalShell, title, ex )); + } + } + + /* + * @see dwtx.jface.text.IUndoManager#setMaximalUndoLevel(int) + */ + public void setMaximalUndoLevel(int undoLevel) { + fUndoLevel= Math.max(0, undoLevel); + if (isConnected()) { + fDocumentUndoManager.setMaximalUndoLevel(fUndoLevel); + } + } + + /* + * @see dwtx.jface.text.IUndoManager#connect(dwtx.jface.text.ITextViewer) + */ + public void connect(ITextViewer textViewer) { + if (fTextViewer is null && textViewer !is null) { + fTextViewer= textViewer; + addListeners(); + } + IDocument doc= fTextViewer.getDocument(); + connectDocumentUndoManager(doc); + } + + /* + * @see dwtx.jface.text.IUndoManager#disconnect() + */ + public void disconnect() { + if (fTextViewer !is null) { + removeListeners(); + fTextViewer= null; + } + disconnectDocumentUndoManager(); + } + + /* + * @see dwtx.jface.text.IUndoManager#reset() + */ + public void reset() { + if (isConnected()) + fDocumentUndoManager.reset(); + + } + + /* + * @see dwtx.jface.text.IUndoManager#redoable() + */ + public bool redoable() { + if (isConnected()) + return fDocumentUndoManager.redoable(); + return false; + } + + /* + * @see dwtx.jface.text.IUndoManager#undoable() + */ + public bool undoable() { + if (isConnected()) + return fDocumentUndoManager.undoable(); + return false; + } + + /* + * @see dwtx.jface.text.IUndoManager#redo() + */ + public void redo() { + if (isConnected()) { + try { + fDocumentUndoManager.redo(); + } catch (ExecutionException ex) { + openErrorDialog(JFaceTextMessages.getString("DefaultUndoManager.error.redoFailed.title"), ex); //$NON-NLS-1$ + } + } + } + + /* + * @see dwtx.jface.text.IUndoManager#undo() + */ + public void undo() { + if (isConnected()) { + try { + fDocumentUndoManager.undo(); + } catch (ExecutionException ex) { + openErrorDialog(JFaceTextMessages.getString("DefaultUndoManager.error.undoFailed.title"), ex); //$NON-NLS-1$ + } + } + } + + /** + * Selects and reveals the specified range. + * + * @param offset the offset of the range + * @param length the length of the range + */ + private void selectAndReveal(int offset, int length) { + if ( cast(ITextViewerExtension5)fTextViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) fTextViewer; + extension.exposeModelRange(new Region(offset, length)); + } else if (!fTextViewer.overlapsWithVisibleRegion(offset, length)) + fTextViewer.resetVisibleRegion(); + + fTextViewer.setSelectedRange(offset, length); + fTextViewer.revealRange(offset, length); + } + + /* + * @see dwtx.jface.text.IUndoManagerExtension#getUndoContext() + */ + public IUndoContext getUndoContext() { + if (isConnected()) { + return fDocumentUndoManager.getUndoContext(); + } + return null; + } + + private void connectDocumentUndoManager(IDocument document) { + disconnectDocumentUndoManager(); + if (document !is null) { + fDocument= document; + DocumentUndoManagerRegistry.connect(fDocument); + fDocumentUndoManager= DocumentUndoManagerRegistry.getDocumentUndoManager(fDocument); + fDocumentUndoManager.connect(this); + setMaximalUndoLevel(fUndoLevel); + fDocumentUndoListener= new DocumentUndoListener(); + fDocumentUndoManager.addDocumentUndoListener(fDocumentUndoListener); + } + } + + private void disconnectDocumentUndoManager() { + if (fDocumentUndoManager !is null) { + fDocumentUndoManager.disconnect(this); + DocumentUndoManagerRegistry.disconnect(fDocument); + fDocumentUndoManager.removeDocumentUndoListener(fDocumentUndoListener); + fDocumentUndoListener= null; + fDocumentUndoManager= null; + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/TreeLineTracker.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/TreeLineTracker.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,1531 @@ +/******************************************************************************* + * Copyright (c) 2005, 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 + *******************************************************************************/ +module dwtx.jface.text.TreeLineTracker; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; +import tango.text.convert.Format; +import tango.core.Exception; + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.AbstractLineTracker; + +/** + * Abstract implementation of ILineTracker. It lets the definition of line + * delimiters to subclasses. Assuming that '\n' is the only line delimiter, this abstract + * implementation defines the following line scheme: + *
                  + *
                • "" -> [0,0] + *
                • "a" -> [0,1] + *
                • "\n" -> [0,1], [1,0] + *
                • "a\n" -> [0,2], [2,0] + *
                • "a\nb" -> [0,2], [2,1] + *
                • "a\nbc\n" -> [0,2], [2,3], [5,0] + *
                + *

                + * This class must be subclassed. + *

                + *

                + * Performance: The query operations perform in O(log n) where n + * is the number of lines in the document. The modification operations roughly perform in O(l * + * log n) where n is the number of lines in the document and l is the + * sum of the number of removed, added or modified lines. + *

                + * + * @since 3.2 + */ +abstract class TreeLineTracker : ILineTracker { + /* + * Differential Balanced Binary Tree + * + * Assumption: lines cannot overlap => there exists a total ordering of the lines by their offset, + * which is the same as the ordering by line number + * + * Base idea: store lines in a binary search tree + * - the key is the line number / line offset + * -> lookup_line is O(log n) + * -> lookup_offset is O(log n) + * - a change in a line somewhere will change any succeeding line numbers / line offsets + * -> replace is O(n) + * + * Differential tree: instead of storing the key (line number, line offset) directly, every node + * stores the difference between its key and its parent's key + * - the sort key is still the line number / line offset, but it remains "virtual" + * - inserting a node (a line) really increases the virtual key of all succeeding nodes (lines), but this + * fact will not be realized in the key information encoded in the nodes. + * -> any change only affects the nodes in the node's parent chain, although more bookkeeping + * has to be done when changing a node or balancing the tree + * -> replace is O(log n) + * -> line offsets and line numbers have to be computed when walking the tree from the root / + * from a node + * -> still O(log n) + * + * The balancing algorithm chosen does not depend on the differential tree property. An AVL tree + * implementation has been chosen for simplicity. + */ + + /* + * Turns assertions on/off. Don't make this a a debug option for performance reasons - this way + * the compiler can optimize the asserts away. + */ + private static const bool ASSERT= false; + + /** + * The empty delimiter of the last line. The last line and only the last line must have this + * zero-length delimiter. + */ + private static const String NO_DELIM= ""; //$NON-NLS-1$ + + /** + * A node represents one line. Its character and line offsets are 0-based and relative to the + * subtree covered by the node. All nodes under the left subtree represent lines before, all + * nodes under the right subtree lines after the current node. + */ + private static final class Node { + this(int length, String delimiter) { + this.length= length; + this.delimiter= delimiter; + } + /** + * The line index in this node's line tree, or equivalently, the number of lines in the left + * subtree. + */ + int line; + /** + * The line offset in this node's line tree, or equivalently, the number of characters in + * the left subtree. + */ + int offset; + /** The number of characters in this line. */ + int length; + /** The line delimiter of this line, needed to answer the delimiter query. */ + String delimiter; + /** The parent node, null if this is the root node. */ + Node parent; + /** The left subtree, possibly null. */ + Node left; + /** The right subtree, possibly null. */ + Node right; + /** The balance factor. */ + byte balance; + + /* + * @see java.lang.Object#toString() + */ + public final override String toString() { + String bal; + switch (balance) { + case 0: + bal= "="; //$NON-NLS-1$ + break; + case 1: + bal= "+"; //$NON-NLS-1$ + break; + case 2: + bal= "++"; //$NON-NLS-1$ + break; + case -1: + bal= "-"; //$NON-NLS-1$ + break; + case -2: + bal= "--"; //$NON-NLS-1$ + break; + default: + bal= Byte.toString(balance); + } + return Format("[{}+{}+{}|{}|{}]", offset, pureLength(), delimiter.length, line, bal ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ + } + + /** + * Returns the pure (without the line delimiter) length of this line. + * + * @return the pure line length + */ + int pureLength() { + return length - delimiter.length; + } + } + + /** + * The root node of the tree, never null. + */ + private Node fRoot; + + /** + * Creates a new line tracker. + */ + protected this() { + fRoot= new Node(0, NO_DELIM); + } + + /** + * Package visible constructor for creating a tree tracker from a list tracker. + * + * @param tracker + */ + this(ListLineTracker tracker) { + fRoot= new Node(0, NO_DELIM); + final List lines= tracker.getLines(); + final int n= lines.size(); + if (n is 0) + return; + + Line line= cast(Line) lines.get(0); + String delim= line.delimiter; + if (delim is null) + delim= NO_DELIM; + int length= line.length; + fRoot= new Node(length, delim); + Node node= fRoot; + + for (int i= 1; i < n; i++) { + line= cast(Line) lines.get(i); + delim= line.delimiter; + if (delim is null) + delim= NO_DELIM; + length= line.length; + node= insertAfter(node, length, delim); + } + + if (node.delimiter !is NO_DELIM) + insertAfter(node, 0, NO_DELIM); + + if (ASSERT) checkTree(); + } + + /** + * Returns the node (line) including a certain offset. If the offset is between two + * lines, the line starting at offset is returned. + *

                + * This means that for offsets smaller than the length, the following holds: + *

                + *

                + * line.offset <= offset < line.offset + offset.length. + *

                + *

                + * If offset is the document length, then this is true: + *

                + *

                + * offset= line.offset + line.length. + *

                + * + * @param offset a document offset + * @return the line starting at or containing offset + * @throws BadLocationException if the offset is invalid + */ + private Node nodeByOffset(int offset) { + /* + * Works for any binary search tree. + */ + int remaining= offset; + Node node= fRoot; + int line= 0; + + while (true) { + if (node is null) + fail(offset); + + if (remaining < node.offset) { + node= node.left; + } else { + remaining -= node.offset; + line+= node.line; + if (remaining < node.length + || remaining is node.length && node.right is null) { // last line + break; + } + remaining -= node.length; + line ++; + node= node.right; + } + } + + return node; + } + /** + * Returns the line number for the given offset. If the offset is between two lines, the line + * starting at offset is returned. The last line is returned if + * offset is equal to the document length. + * + * @param offset a document offset + * @return the line number starting at or containing offset + * @throws BadLocationException if the offset is invalid + */ + private int lineByOffset(int offset) { + /* + * Works for any binary search tree. + */ + int remaining= offset; + Node node= fRoot; + int line= 0; + + while (true) { + if (node is null) + fail(offset); + + if (remaining < node.offset) { + node= node.left; + } else { + remaining -= node.offset; + line+= node.line; + if (remaining < node.length || remaining is node.length && node.right is null) // last line + return line; + + remaining -= node.length; + line ++; + node= node.right; + } + } + } + + /** + * Returns the node (line) with the given line number. Note that the last line is always + * incomplete, i.e. has the {@link #NO_DELIM} delimiter. + * + * @param line a line number + * @return the line with the given line number + * @throws BadLocationException if the line is invalid + */ + private Node nodeByLine(int line) { + /* + * Works for any binary search tree. + */ + int remaining= line; + int offset= 0; + Node node= fRoot; + + while (true) { + if (node is null) + fail(line); + + if (remaining is node.line) + break; + if (remaining < node.line) { + node= node.left; + } else { + remaining -= node.line + 1; + offset += node.offset + node.length; + node= node.right; + } + } + + return node; + } + + /** + * Returns the offset for the given line number. Note that the + * last line is always incomplete, i.e. has the {@link #NO_DELIM} delimiter. + * + * @param line a line number + * @return the line offset with the given line number + * @throws BadLocationException if the line is invalid + */ + private int offsetByLine(int line) { + /* + * Works for any binary search tree. + */ + int remaining= line; + int offset= 0; + Node node= fRoot; + + while (true) { + if (node is null) + fail(line); + + if (remaining is node.line) + return offset + node.offset; + + if (remaining < node.line) { + node= node.left; + } else { + remaining -= node.line + 1; + offset += node.offset + node.length; + node= node.right; + } + } + } + + /** + * Left rotation - the given node is rotated down, its right child is rotated up, taking the + * previous structural position of node. + * + * @param node the node to rotate around + */ + private void rotateLeft(Node node) { + if (ASSERT) Assert.isNotNull(node); + Node child= node.right; + if (ASSERT) Assert.isNotNull(child); + bool leftChild= node.parent is null || node is node.parent.left; + + // restructure + setChild(node.parent, child, leftChild); + + setChild(node, child.left, false); + setChild(child, node, true); + + // update relative info + // child becomes the new parent, its line and offset counts increase as the former parent + // moves under child's left subtree + child.line += node.line + 1; + child.offset += node.offset + node.length; + } + + /** + * Right rotation - the given node is rotated down, its left child is rotated up, taking the + * previous structural position of node. + * + * @param node the node to rotate around + */ + private void rotateRight(Node node) { + if (ASSERT) Assert.isNotNull(node); + Node child= node.left; + if (ASSERT) Assert.isNotNull(child); + bool leftChild= node.parent is null || node is node.parent.left; + + setChild(node.parent, child, leftChild); + + setChild(node, child.right, true); + setChild(child, node, false); + + // update relative info + // node loses its left subtree, except for what it keeps in its new subtree + // this is exactly the amount in child + node.line -= child.line + 1; + node.offset -= child.offset + child.length; + } + + /** + * Helper method for moving a child, ensuring that parent pointers are set correctly. + * + * @param parent the new parent of child, null to replace the + * root node + * @param child the new child of parent, may be null + * @param isLeftChild true if child shall become + * parent's left child, false if it shall become + * parent's right child + */ + private void setChild(Node parent, Node child, bool isLeftChild) { + if (parent is null) { + if (child is null) + fRoot= new Node(0, NO_DELIM); + else + fRoot= child; + } else { + if (isLeftChild) + parent.left= child; + else + parent.right= child; + } + if (child !is null) + child.parent= parent; + } + + /** + * A left rotation around parent, whose structural position is replaced by + * node. + * + * @param node the node moving up and left + * @param parent the node moving left and down + */ + private void singleLeftRotation(Node node, Node parent) { + rotateLeft(parent); + node.balance= 0; + parent.balance= 0; + } + + /** + * A right rotation around parent, whose structural position is replaced by + * node. + * + * @param node the node moving up and right + * @param parent the node moving right and down + */ + private void singleRightRotation(Node node, Node parent) { + rotateRight(parent); + node.balance= 0; + parent.balance= 0; + } + + /** + * A double left rotation, first rotating right around node, then left around + * parent. + * + * @param node the node that will be rotated right + * @param parent the node moving left and down + */ + private void rightLeftRotation(Node node, Node parent) { + Node child= node.left; + rotateRight(node); + rotateLeft(parent); + if (child.balance is 1) { + node.balance= 0; + parent.balance= -1; + child.balance= 0; + } else if (child.balance is 0) { + node.balance= 0; + parent.balance= 0; + } else if (child.balance is -1) { + node.balance= 1; + parent.balance= 0; + child.balance= 0; + } + } + + /** + * A double right rotation, first rotating left around node, then right around + * parent. + * + * @param node the node that will be rotated left + * @param parent the node moving right and down + */ + private void leftRightRotation(Node node, Node parent) { + Node child= node.right; + rotateLeft(node); + rotateRight(parent); + if (child.balance is -1) { + node.balance= 0; + parent.balance= 1; + child.balance= 0; + } else if (child.balance is 0) { + node.balance= 0; + parent.balance= 0; + } else if (child.balance is 1) { + node.balance= -1; + parent.balance= 0; + child.balance= 0; + } + } + + /** + * Inserts a line with the given length and delimiter after node. + * + * @param node the predecessor of the inserted node + * @param length the line length of the inserted node + * @param delimiter the delimiter of the inserted node + * @return the inserted node + */ + private Node insertAfter(Node node, int length, String delimiter) { + /* + * An insertion really shifts the key of all succeeding nodes. Hence we insert the added node + * between node and the successor of node. The added node becomes either the right child + * of the predecessor node, or the left child of the successor node. + */ + Node added= new Node(length, delimiter); + + if (node.right is null) + setChild(node, added, false); + else + setChild(successorDown(node.right), added, true); + + // parent chain update + updateParentChain(added, length, 1); + updateParentBalanceAfterInsertion(added); + + return added; + } + + /** + * Updates the balance information in the parent chain of node until it reaches the root or + * finds a node whose balance violates the AVL constraint, which is the re-balanced. + * + * @param node the child of the first node that needs balance updating + */ + private void updateParentBalanceAfterInsertion(Node node) { + Node parent= node.parent; + while (parent !is null) { + if (node is parent.left) + parent.balance--; + else + parent.balance++; + + switch (parent.balance) { + case 1: + case -1: + node= parent; + parent= node.parent; + continue; + case -2: + rebalanceAfterInsertionLeft(node); + break; + case 2: + rebalanceAfterInsertionRight(node); + break; + case 0: + break; + default: + if (ASSERT) + Assert.isTrue(false); + } + return; + } + } + + /** + * Re-balances a node whose parent has a double positive balance. + * + * @param node the node to re-balance + */ + private void rebalanceAfterInsertionRight(Node node) { + Node parent= node.parent; + if (node.balance is 1) { + singleLeftRotation(node, parent); + } else if (node.balance is -1) { + rightLeftRotation(node, parent); + } else if (ASSERT) { + Assert.isTrue(false); + } + } + + /** + * Re-balances a node whose parent has a double negative balance. + * + * @param node the node to re-balance + */ + private void rebalanceAfterInsertionLeft(Node node) { + Node parent= node.parent; + if (node.balance is -1) { + singleRightRotation(node, parent); + } else if (node.balance is 1) { + leftRightRotation(node, parent); + } else if (ASSERT) { + Assert.isTrue(false); + } + } + + /* + * @see dwtx.jface.text.ILineTracker#replace(int, int, java.lang.String) + */ + public final void replace(int offset, int length, String text) { + if (ASSERT) checkTree(); + + // Inlined nodeByOffset as we need both node and offset + int remaining= offset; + Node first= fRoot; + int firstNodeOffset; + + while (true) { + if (first is null) + fail(offset); + + if (remaining < first.offset) { + first= first.left; + } else { + remaining -= first.offset; + if (remaining < first.length + || remaining is first.length && first.right is null) { // last line + firstNodeOffset= offset - remaining; + break; + } + remaining -= first.length; + first= first.right; + } + } + // Inline nodeByOffset end + if (ASSERT) Assert.isTrue(first !is null); + + Node last; + if (offset + length < firstNodeOffset + first.length) + last= first; + else + last= nodeByOffset(offset + length); + if (ASSERT) Assert.isTrue(last !is null); + + int firstLineDelta= firstNodeOffset + first.length - offset; + if (first is last) + replaceInternal(first, text, length, firstLineDelta); + else + replaceFromTo(first, last, text, length, firstLineDelta); + + if (ASSERT) checkTree(); + } + + /** + * Replace happening inside a single line. + * + * @param node the affected node + * @param text the added text + * @param length the replace length, < firstLineDelta + * @param firstLineDelta the number of characters from the replacement offset to the end of + * node > length + */ + private void replaceInternal(Node node, String text, int length, int firstLineDelta) { + // 1) modification on a single line + + AbstractLineTracker_DelimiterInfo info= text is null ? null : nextDelimiterInfo(text, 0); + + if (info is null || info.delimiter is null) { + // a) trivial case: insert into a single node, no line mangling + int added= text is null ? 0 : text.length; + updateLength(node, added - length); + } else { + // b) more lines to add between two chunks of the first node + // remember what we split off the first line + int remainder= firstLineDelta - length; + String remDelim= node.delimiter; + + // join the first line with the first added + int consumed= info.delimiterIndex + info.delimiterLength; + int delta= consumed - firstLineDelta; + updateLength(node, delta); + node.delimiter= info.delimiter; + + // Inline addlines start + info= nextDelimiterInfo(text, consumed); + while (info !is null) { + int lineLen= info.delimiterIndex - consumed + info.delimiterLength; + node= insertAfter(node, lineLen, info.delimiter); + consumed += lineLen; + info= nextDelimiterInfo(text, consumed); + } + // Inline addlines end + + // add remaining chunk merged with last (incomplete) additional line + insertAfter(node, remainder + text.length - consumed, remDelim); + } + } + + /** + * Replace spanning from one node to another. + * + * @param node the first affected node + * @param last the last affected node + * @param text the added text + * @param length the replace length, >= firstLineDelta + * @param firstLineDelta the number of characters removed from the replacement offset to the end + * of node, <= length + */ + private void replaceFromTo(Node node, Node last, String text, int length, int firstLineDelta) { + // 2) modification covers several lines + + // delete intermediate nodes + // TODO could be further optimized: replace intermediate lines with intermediate added lines + // to reduce re-balancing + Node successor_= successor(node); + while (successor_ !is last) { + length -= successor_.length; + Node toDelete= successor_; + successor_= successor(successor_); + updateLength(toDelete, -toDelete.length); + } + + AbstractLineTracker_DelimiterInfo info= text is null ? null : nextDelimiterInfo(text, 0); + + if (info is null || info.delimiter is null) { + int added= text is null ? 0 : text.length; + + // join the two lines if there are no lines added + join(node, last, added - length); + + } else { + + // join the first line with the first added + int consumed= info.delimiterIndex + info.delimiterLength; + updateLength(node, consumed - firstLineDelta); + node.delimiter= info.delimiter; + length -= firstLineDelta; + + // Inline addLines start + info= nextDelimiterInfo(text, consumed); + while (info !is null) { + int lineLen= info.delimiterIndex - consumed + info.delimiterLength; + node= insertAfter(node, lineLen, info.delimiter); + consumed += lineLen; + info= nextDelimiterInfo(text, consumed); + } + // Inline addLines end + + updateLength(last, text.length - consumed - length); + } + } + + /** + * Joins two consecutive node lines, additionally adjusting the resulting length of the combined + * line by delta. The first node gets deleted. + * + * @param one the first node to join + * @param two the second node to join + * @param delta the delta to apply to the remaining single node + */ + private void join(Node one, Node two, int delta) { + int oneLength= one.length; + updateLength(one, -oneLength); + updateLength(two, oneLength + delta); + } + + /** + * Adjusts the length of a node by delta, also adjusting the parent chain of + * node. If the node's length becomes zero and is not the last (incomplete) + * node, it is deleted after the update. + * + * @param node the node to adjust + * @param delta the character delta to add to the node's length + */ + private void updateLength(Node node, int delta) { + if (ASSERT) Assert.isTrue(node.length + delta >= 0); + + // update the node itself + node.length += delta; + + // check deletion + int lineDelta; + bool delete__= node.length is 0 && node.delimiter !is NO_DELIM; + if (delete__) + lineDelta= -1; + else + lineDelta= 0; + + // update parent chain + if (delta !is 0 || lineDelta !is 0) + updateParentChain(node, delta, lineDelta); + + if (delete__) + delete_(node); + } + + /** + * Updates the differential indices following the parent chain. All nodes from + * from.parent to the root are updated. + * + * @param node the child of the first node to update + * @param deltaLength the character delta + * @param deltaLines the line delta + */ + private void updateParentChain(Node node, int deltaLength, int deltaLines) { + updateParentChain(node, null, deltaLength, deltaLines); + } + + /** + * Updates the differential indices following the parent chain. All nodes from + * from.parent to to (exclusive) are updated. + * + * @param from the child of the first node to update + * @param to the first node not to update + * @param deltaLength the character delta + * @param deltaLines the line delta + */ + private void updateParentChain(Node from, Node to, int deltaLength, int deltaLines) { + Node parent= from.parent; + while (parent !is to) { + // only update node if update comes from left subtree + if (from is parent.left) { + parent.offset += deltaLength; + parent.line += deltaLines; + } + from= parent; + parent= from.parent; + } + } + + /** + * Deletes a node from the tree, re-balancing it if necessary. The differential indices in the + * node's parent chain have to be updated in advance to calling this method. Generally, don't + * call delete directly, but call + * {@link #updateLength(Node, int) update_length(node, -node.length)} to properly remove a + * node. + * + * @param node the node to delete. + */ + private void delete_(Node node) { + if (ASSERT) Assert.isTrue(node !is null); + if (ASSERT) Assert.isTrue(node.length is 0); + + Node parent= node.parent; + Node toUpdate; // the parent of the node that lost a child + bool lostLeftChild; + bool isLeftChild= parent is null || node is parent.left; + + if (node.left is null || node.right is null) { + // 1) node has one child at max - replace parent's pointer with the only child + // also handles the trivial case of no children + Node replacement= node.left is null ? node.right : node.left; + setChild(parent, replacement, isLeftChild); + toUpdate= parent; + lostLeftChild= isLeftChild; + // no updates to do - subtrees stay as they are + } else if (node.right.left is null) { + // 2a) node's right child has no left child - replace node with right child, giving node's + // left subtree to the right child + Node replacement= node.right; + setChild(parent, replacement, isLeftChild); + setChild(replacement, node.left, true); + replacement.line= node.line; + replacement.offset= node.offset; + replacement.balance= node.balance; + toUpdate= replacement; + lostLeftChild= false; +// } else if (node.left.right is null) { +// // 2b) symmetric case +// Node replacement= node.left; +// set_child(parent, replacement, isLeftChild); +// set_child(replacement, node.right, false); +// replacement.balance= node.balance; +// toUpdate= replacement; +// lostLeftChild= true; + } else { + // 3) hard case - replace node with its successor + Node successor_= successor(node); + + // successor exists (otherwise node would not have right child, case 1) + if (ASSERT) Assert.isNotNull(successor_); + // successor has no left child (a left child would be the real successor of node) + if (ASSERT) Assert.isTrue(successor_.left is null); + if (ASSERT) Assert.isTrue(successor_.line is 0); + // successor is the left child of its parent (otherwise parent would be smaller and + // hence the real successor) + if (ASSERT) Assert.isTrue(successor_ is successor_.parent.left); + // successor is not a child of node (would have been covered by 2a) + if (ASSERT) Assert.isTrue(successor_.parent !is node); + + toUpdate= successor_.parent; + lostLeftChild= true; + + // update relative indices + updateParentChain(successor_, node, -successor_.length, -1); + + // delete successor from its current place - like 1) + setChild(toUpdate, successor_.right, true); + + // move node's subtrees to its successor + setChild(successor_, node.right, false); + setChild(successor_, node.left, true); + + // replace node by successor in its parent + setChild(parent, successor_, isLeftChild); + + // update the successor + successor_.line= node.line; + successor_.offset= node.offset; + successor_.balance= node.balance; + } + + updateParentBalanceAfterDeletion(toUpdate, lostLeftChild); + } + + /** + * Updates the balance information in the parent chain of node. + * + * @param node the first node that needs balance updating + * @param wasLeftChild true if the deletion happened on node's + * left subtree, false if it occurred on node's right + * subtree + */ + private void updateParentBalanceAfterDeletion(Node node, bool wasLeftChild) { + while (node !is null) { + if (wasLeftChild) + node.balance++; + else + node.balance--; + + Node parent= node.parent; + if (parent !is null) + wasLeftChild= node is parent.left; + + switch (node.balance) { + case 1: + case -1: + return; // done, no tree change + case -2: + if (rebalanceAfterDeletionRight(node.left)) + return; + break; // propagate up + case 2: + if (rebalanceAfterDeletionLeft(node.right)) + return; + break; // propagate up + case 0: + break; // propagate up + default: + if (ASSERT) + Assert.isTrue(false); + } + + node= parent; + } + } + + /** + * Re-balances a node whose parent has a double positive balance. + * + * @param node the node to re-balance + * @return true if the re-balancement leaves the height at + * node.parent constant, false if the height changed + */ + private bool rebalanceAfterDeletionLeft(Node node) { + Node parent= node.parent; + if (node.balance is 1) { + singleLeftRotation(node, parent); + return false; + } else if (node.balance is -1) { + rightLeftRotation(node, parent); + return false; + } else if (node.balance is 0) { + rotateLeft(parent); + node.balance= -1; + parent.balance= 1; + return true; + } else { + if (ASSERT) Assert.isTrue(false); + return true; + } + } + + /** + * Re-balances a node whose parent has a double negative balance. + * + * @param node the node to re-balance + * @return true if the re-balancement leaves the height at + * node.parent constant, false if the height changed + */ + private bool rebalanceAfterDeletionRight(Node node) { + Node parent= node.parent; + if (node.balance is -1) { + singleRightRotation(node, parent); + return false; + } else if (node.balance is 1) { + leftRightRotation(node, parent); + return false; + } else if (node.balance is 0) { + rotateRight(parent); + node.balance= 1; + parent.balance= -1; + return true; + } else { + if (ASSERT) Assert.isTrue(false); + return true; + } + } + + /** + * Returns the successor of a node, null if node is the last node. + * + * @param node a node + * @return the successor of node, null if there is none + */ + private Node successor(Node node) { + if (node.right !is null) + return successorDown(node.right); + + return successorUp(node); + } + + /** + * Searches the successor of node in its parent chain. + * + * @param node a node + * @return the first node in node's parent chain that is reached from its left + * subtree, null if there is none + */ + private Node successorUp(Node node) { + Node child= node; + Node parent= child.parent; + while (parent !is null) { + if (child is parent.left) + return parent; + child= parent; + parent= child.parent; + } + if (ASSERT) Assert.isTrue(node.delimiter is NO_DELIM); + return null; + } + + /** + * Searches the left-most node in a given subtree. + * + * @param node a node + * @return the left-most node in the given subtree + */ + private Node successorDown(Node node) { + Node child= node.left; + while (child !is null) { + node= child; + child= node.left; + } + return node; + } + + /* miscellaneous */ + + /** + * Throws an exception. + * + * @param offset the illegal character or line offset that caused the exception + * @throws BadLocationException always + */ + private void fail(int offset) { + throw new BadLocationException(); + } + + /** + * Returns the information about the first delimiter found in the given + * text starting at the given offset. + * + * @param text the text to be searched + * @param offset the offset in the given text + * @return the information of the first found delimiter or null + */ + protected abstract AbstractLineTracker_DelimiterInfo nextDelimiterInfo(String text, int offset); + + /* + * @see dwtx.jface.text.ILineTracker#getLineDelimiter(int) + */ + public final String getLineDelimiter(int line) { + Node node= nodeByLine(line); + return node.delimiter is NO_DELIM ? null : node.delimiter; + } + + /* + * @see dwtx.jface.text.ILineTracker#computeNumberOfLines(java.lang.String) + */ + public final int computeNumberOfLines(String text) { + int count= 0; + int start= 0; + AbstractLineTracker_DelimiterInfo delimiterInfo= nextDelimiterInfo(text, start); + while (delimiterInfo !is null && delimiterInfo.delimiterIndex > -1) { + ++count; + start= delimiterInfo.delimiterIndex + delimiterInfo.delimiterLength; + delimiterInfo= nextDelimiterInfo(text, start); + } + return count; + } + + /* + * @see dwtx.jface.text.ILineTracker#getNumberOfLines() + */ + public final int getNumberOfLines() { + // TODO track separately? + Node node= fRoot; + int lines= 0; + while (node !is null) { + lines += node.line + 1; + node= node.right; + } + return lines; + } + + /* + * @see dwtx.jface.text.ILineTracker#getNumberOfLines(int, int) + */ + public final int getNumberOfLines(int offset, int length) { + if (length is 0) + return 1; + + int startLine= lineByOffset(offset); + int endLine= lineByOffset(offset + length); + + return endLine - startLine + 1; + } + + /* + * @see dwtx.jface.text.ILineTracker#getLineOffset(int) + */ + public final int getLineOffset(int line) { + return offsetByLine(line); + } + + /* + * @see dwtx.jface.text.ILineTracker#getLineLength(int) + */ + public final int getLineLength(int line) { + Node node= nodeByLine(line); + return node.length; + } + + /* + * @see dwtx.jface.text.ILineTracker#getLineNumberOfOffset(int) + */ + public final int getLineNumberOfOffset(int offset) { + return lineByOffset(offset); + } + + /* + * @see dwtx.jface.text.ILineTracker#getLineInformationOfOffset(int) + */ + public final IRegion getLineInformationOfOffset(int offset) { + // Inline nodeByOffset start as we need both node and offset + int remaining= offset; + Node node= fRoot; + int lineOffset; + + while (true) { + if (node is null) + fail(offset); + + if (remaining < node.offset) { + node= node.left; + } else { + remaining -= node.offset; + if (remaining < node.length + || remaining is node.length && node.right is null) { // last line + lineOffset= offset - remaining; + break; + } + remaining -= node.length; + node= node.right; + } + } + // Inline nodeByOffset end + return new Region(lineOffset, node.pureLength()); + } + + /* + * @see dwtx.jface.text.ILineTracker#getLineInformation(int) + */ + public final IRegion getLineInformation(int line) { + try { + // Inline nodeByLine start + int remaining= line; + int offset= 0; + Node node= fRoot; + + while (true) { + if (node is null) + fail(line); + + if (remaining is node.line) { + offset += node.offset; + break; + } + if (remaining < node.line) { + node= node.left; + } else { + remaining -= node.line + 1; + offset += node.offset + node.length; + node= node.right; + } + } + // Inline nodeByLine end + return new Region(offset, node.pureLength()); + } catch (BadLocationException x) { + /* + * FIXME: this really strange behavior is mandated by the previous line tracker + * implementation and included here for compatibility. See + * LineTrackerTest3#testFunnyLastLineCompatibility(). + */ + if (line > 0 && line is getNumberOfLines()) { + line= line - 1; + // Inline nodeByLine start + int remaining= line; + int offset= 0; + Node node= fRoot; + + while (true) { + if (node is null) + fail(line); + + if (remaining is node.line) { + offset+= node.offset; + break; + } + if (remaining < node.line) { + node= node.left; + } else { + remaining -= node.line + 1; + offset += node.offset + node.length; + node= node.right; + } + } + Node last= node; + // Inline nodeByLine end + if (last.length > 0) + return new Region(offset + last.length, 0); + } + throw x; + } + } + + /* + * @see dwtx.jface.text.ILineTracker#set(java.lang.String) + */ + public final void set(String text) { + fRoot= new Node(0, NO_DELIM); + try { + replace(0, 0, text); + } catch (BadLocationException x) { + throw new AssertException(__FILE__,__LINE__); + } + } + + /* + * @see java.lang.Object#toString() + */ + public override String toString() { + int depth= computeDepth(fRoot); + int WIDTH= 30; + int leaves= cast(int) Math.pow( cast(real)2, cast(uint) depth - 1); + int width= WIDTH * leaves; + String empty= "."; //$NON-NLS-1$ + + List roots= new LinkedList(); + roots.add(fRoot); + StringBuffer buf= new StringBuffer((width + 1) * depth); + int nodes= 1; + int indents= leaves; + char[] space= new char[leaves * WIDTH / 2]; + Arrays.fill(space, ' '); + for(int d= 0; d < depth; d++) { + // compute indent + indents /= 2; + int spaces= Math.max(0, indents * WIDTH - WIDTH / 2); + // print nodes + for (ListIterator it= roots.listIterator(); it.hasNext();) { + // pad before + buf.append(space[ 0 .. spaces]); + + Node node= cast(Node) it.next(); + String box; + // replace the node with its children + if (node is null) { + it.add(cast(Object)null); + box= empty; + } else { + it.set(node.left); + it.add(node.right); + box= node.toString(); + } + + // draw the node, pad to WIDTH + int pad_left= (WIDTH - box.length() + 1) / 2; + int pad_right= WIDTH - box.length() - pad_left; + buf.append(space[ 0 .. pad_left]); + buf.append(box); + buf.append(space[ 0 .. pad_right]); + + // pad after + buf.append(space[ 0 .. spaces]); + } + + buf.append('\n'); + nodes *= 2; + } + + return buf.toString(); + } + + /** + * Recursively computes the depth of the tree. Only used by {@link #toString()}. + * + * @param root the subtree to compute the depth of, may be null + * @return the depth of the given tree, 0 if it is null + */ + private byte computeDepth(Node root) { + if (root is null) + return 0; + + return cast(byte) (Math.max(computeDepth(root.left), computeDepth(root.right)) + 1); + } + + /** + * Debug-only method that checks the tree structure and the differential offsets. + */ + private void checkTree() { + checkTreeStructure(fRoot); + + try { + checkTreeOffsets(nodeByOffset(0), [0, 0], null); + } catch (BadLocationException x) { + throw new AssertException(__FILE__,__LINE__); + } + } + + /** + * Debug-only method that validates the tree structure below node. I.e. it + * checks whether all parent/child pointers are consistent and whether the AVL balance + * information is correct. + * + * @param node the node to validate + * @return the depth of the tree under node + */ + private byte checkTreeStructure(Node node) { + if (node is null) + return 0; + + byte leftDepth= checkTreeStructure(node.left); + byte rightDepth= checkTreeStructure(node.right); + Assert.isTrue(node.balance is rightDepth - leftDepth); + Assert.isTrue(node.left is null || node.left.parent is node); + Assert.isTrue(node.right is null || node.right.parent is node); + + return cast(byte) (Math.max(rightDepth, leftDepth) + 1); + } + + /** + * Debug-only method that checks the differential offsets of the tree, starting at + * node and continuing until last. + * + * @param node the first Node to check, may be null + * @param offLen an array of length 2, with offLen[0] the expected offset of + * node and offLen[1] the expected line of + * node + * @param last the last Node to check, may be null + * @return an int[] of length 2, with the first element being the character + * length of node's subtree, and the second element the number of lines + * in node's subtree + */ + private int[] checkTreeOffsets(Node node, int[] offLen, Node last) { + if (node is last) + return offLen; + + Assert.isTrue(node.offset is offLen[0]); + Assert.isTrue(node.line is offLen[1]); + + if (node.right !is null) { + int[] result= checkTreeOffsets(successorDown(node.right), new int[2], node); + offLen[0] += result[0]; + offLen[1] += result[1]; + } + + offLen[0] += node.length; + offLen[1]++; + return checkTreeOffsets(node.parent, offLen, last); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/TypedPosition.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/TypedPosition.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,224 @@ +/******************************************************************************* + * 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.text.TypedPosition; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Convenience class for positions that have a type, similar to + * {@link dwtx.jface.text.ITypedRegion}. + *

                + * As {@link dwtx.jface.text.Position},TypedPosition can + * not be used as key in hash tables as it overrides equals and + * hashCode as it would be a value object. + */ +public class TypedPosition : Position { + + /** The type of the region described by this position */ + private String fType; + + /** + * Creates a position along the given specification. + * + * @param offset the offset of this position + * @param length the length of this position + * @param type the content type of this position + */ + public this(int offset, int length, String type) { + super(offset, length); + fType= type; + } + + /** + * Creates a position based on the typed region. + * + * @param region the typed region + */ + public this(ITypedRegion region) { + super(region.getOffset(), region.getLength()); + fType= region.getType(); + } + + /** + * Returns the content type of the region. + * + * @return the content type of the region + */ + public String getType() { + return fType; + } + + /* + * @see java.lang.Object#equals(java.lang.Object) + */ + public override int opEquals(Object o) { + if ( cast(TypedPosition)o ) { + if (super.opEquals(o)) { + TypedPosition p= cast(TypedPosition) o; + return (fType is null && p.getType() is null) || fType.equals(p.getType()); + } + } + return false; + } + + /* + * @see java.lang.Object#hashCode() + */ + public override hash_t toHash() { + int type= fType is null ? 0 : .toHash(fType); + return super.toHash() | type; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/TypedRegion.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/TypedRegion.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,206 @@ +/******************************************************************************* + * 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 + * 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.text.TypedRegion; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Default implementation of {@link dwtx.jface.text.ITypedRegion}. A + * TypedRegion is a value object. + */ +public class TypedRegion : Region , ITypedRegion { + + /** The region's type */ + private String fType; + + /** + * Creates a typed region based on the given specification. + * + * @param offset the region's offset + * @param length the region's length + * @param type the region's type + */ + public this(int offset, int length, String type) { + super(offset, length); + fType= type; + } + + /* + * @see dwtx.jface.text.ITypedRegion#getType() + */ + public String getType() { + return fType; + } + + /* + * @see java.lang.Object#equals(java.lang.Object) + */ + public override int opEquals(Object o) { + if ( cast(TypedRegion)o ) { + TypedRegion r= cast(TypedRegion) o; + return super.opEquals(r) && ((fType is null && r.getType() is null) || fType ==/+eq+/r.getType()); + } + return false; + } + + /* + * @see java.lang.Object#hashCode() + */ + public override hash_t toHash() { + int type= fType is null ? 0 : .toHash(fType); + return super.toHash() | type; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/WhitespaceCharacterPainter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/WhitespaceCharacterPainter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,522 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Wind River Systems, Inc. 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: + * Anton Leherbauer (Wind River Systems) - initial API and implementation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=22712 + * Anton Leherbauer (Wind River Systems) - [painting] Long lines take too long to display when "Show Whitespace Characters" is enabled - https://bugs.eclipse.org/bugs/show_bug.cgi?id=196116 + * Anton Leherbauer (Wind River Systems) - [painting] Whitespace characters not drawn when scrolling to right slowly - https://bugs.eclipse.org/bugs/show_bug.cgi?id=206633 + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.text.WhitespaceCharacterPainter; + +import dwtx.jface.text.IDocumentPartitioningListener; // packageimport +import dwtx.jface.text.DefaultTextHover; // packageimport +import dwtx.jface.text.AbstractInformationControl; // packageimport +import dwtx.jface.text.TextUtilities; // packageimport +import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport +import dwtx.jface.text.AbstractInformationControlManager; // packageimport +import dwtx.jface.text.ITextViewerExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitioner; // packageimport +import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport +import dwtx.jface.text.ITextSelection; // packageimport +import dwtx.jface.text.Document; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport +import dwtx.jface.text.ITextListener; // packageimport +import dwtx.jface.text.BadPartitioningException; // packageimport +import dwtx.jface.text.ITextViewerExtension5; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport +import dwtx.jface.text.IUndoManager; // packageimport +import dwtx.jface.text.ITextHoverExtension2; // packageimport +import dwtx.jface.text.IRepairableDocument; // packageimport +import dwtx.jface.text.IRewriteTarget; // packageimport +import dwtx.jface.text.DefaultPositionUpdater; // packageimport +import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport +import dwtx.jface.text.TextViewerHoverManager; // packageimport +import dwtx.jface.text.DocumentRewriteSession; // packageimport +import dwtx.jface.text.TextViewer; // packageimport +import dwtx.jface.text.ITextViewerExtension8; // packageimport +import dwtx.jface.text.RegExMessages; // packageimport +import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport +import dwtx.jface.text.ITextOperationTargetExtension; // packageimport +import dwtx.jface.text.IWidgetTokenOwner; // packageimport +import dwtx.jface.text.IViewportListener; // packageimport +import dwtx.jface.text.GapTextStore; // packageimport +import dwtx.jface.text.MarkSelection; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapterExtension; // packageimport +import dwtx.jface.text.IInformationControlExtension; // packageimport +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport +import dwtx.jface.text.DefaultDocumentAdapter; // packageimport +import dwtx.jface.text.ITextViewerExtension3; // packageimport +import dwtx.jface.text.IInformationControlCreator; // packageimport +import dwtx.jface.text.TypedRegion; // packageimport +import dwtx.jface.text.ISynchronizable; // packageimport +import dwtx.jface.text.IMarkRegionTarget; // packageimport +import dwtx.jface.text.TextViewerUndoManager; // packageimport +import dwtx.jface.text.IRegion; // packageimport +import dwtx.jface.text.IInformationControlExtension2; // packageimport +import dwtx.jface.text.IDocumentExtension4; // packageimport +import dwtx.jface.text.IDocumentExtension2; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport +import dwtx.jface.text.Assert; // packageimport +import dwtx.jface.text.DefaultInformationControl; // packageimport +import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport +import dwtx.jface.text.DocumentClone; // packageimport +import dwtx.jface.text.DefaultUndoManager; // packageimport +import dwtx.jface.text.IFindReplaceTarget; // packageimport +import dwtx.jface.text.IAutoEditStrategy; // packageimport +import dwtx.jface.text.ILineTrackerExtension; // packageimport +import dwtx.jface.text.IUndoManagerExtension; // packageimport +import dwtx.jface.text.TextSelection; // packageimport +import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport +import dwtx.jface.text.IAutoIndentStrategy; // packageimport +import dwtx.jface.text.IPainter; // packageimport +import dwtx.jface.text.IInformationControl; // packageimport +import dwtx.jface.text.IInformationControlExtension3; // packageimport +import dwtx.jface.text.ITextViewerExtension6; // packageimport +import dwtx.jface.text.IInformationControlExtension4; // packageimport +import dwtx.jface.text.DefaultLineTracker; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport +import dwtx.jface.text.IRepairableDocumentExtension; // packageimport +import dwtx.jface.text.ITextHover; // packageimport +import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport +import dwtx.jface.text.ILineTracker; // packageimport +import dwtx.jface.text.Line; // packageimport +import dwtx.jface.text.ITextViewerExtension; // packageimport +import dwtx.jface.text.IDocumentAdapter; // packageimport +import dwtx.jface.text.TextEvent; // packageimport +import dwtx.jface.text.BadLocationException; // packageimport +import dwtx.jface.text.AbstractDocument; // packageimport +import dwtx.jface.text.AbstractLineTracker; // packageimport +import dwtx.jface.text.TreeLineTracker; // packageimport +import dwtx.jface.text.ITextPresentationListener; // packageimport +import dwtx.jface.text.Region; // packageimport +import dwtx.jface.text.ITextViewer; // packageimport +import dwtx.jface.text.IDocumentInformationMapping; // packageimport +import dwtx.jface.text.MarginPainter; // packageimport +import dwtx.jface.text.IPaintPositionManager; // packageimport +import dwtx.jface.text.TextPresentation; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport +import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport +import dwtx.jface.text.ISelectionValidator; // packageimport +import dwtx.jface.text.IDocumentExtension; // packageimport +import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport +import dwtx.jface.text.ConfigurableLineTracker; // packageimport +import dwtx.jface.text.SlaveDocumentEvent; // packageimport +import dwtx.jface.text.IDocumentListener; // packageimport +import dwtx.jface.text.PaintManager; // packageimport +import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport +import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport +import dwtx.jface.text.IDocumentExtension3; // packageimport +import dwtx.jface.text.Position; // packageimport +import dwtx.jface.text.TextMessages; // packageimport +import dwtx.jface.text.CopyOnWriteTextStore; // packageimport +import dwtx.jface.text.IPositionUpdater; // packageimport +import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport +import dwtx.jface.text.ListLineTracker; // packageimport +import dwtx.jface.text.ITextInputListener; // packageimport +import dwtx.jface.text.BadPositionCategoryException; // packageimport +import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport +import dwtx.jface.text.IInputChangedListener; // packageimport +import dwtx.jface.text.ITextOperationTarget; // packageimport +import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport +import dwtx.jface.text.ITextViewerExtension7; // packageimport +import dwtx.jface.text.IInformationControlExtension5; // packageimport +import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport +import dwtx.jface.text.JFaceTextUtil; // packageimport +import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport +import dwtx.jface.text.TabsToSpacesConverter; // packageimport +import dwtx.jface.text.CursorLinePainter; // packageimport +import dwtx.jface.text.ITextHoverExtension; // packageimport +import dwtx.jface.text.IEventConsumer; // packageimport +import dwtx.jface.text.IDocument; // packageimport +import dwtx.jface.text.IWidgetTokenKeeper; // packageimport +import dwtx.jface.text.DocumentCommand; // packageimport +import dwtx.jface.text.TypedPosition; // packageimport +import dwtx.jface.text.IEditingSupportRegistry; // packageimport +import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport +import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport +import dwtx.jface.text.IEditingSupport; // packageimport +import dwtx.jface.text.IMarkSelection; // packageimport +import dwtx.jface.text.ISlaveDocumentManager; // packageimport +import dwtx.jface.text.DocumentEvent; // packageimport +import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport +import dwtx.jface.text.ITextStore; // packageimport +import dwtx.jface.text.JFaceTextMessages; // packageimport +import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport +import dwtx.jface.text.SequentialRewriteTextStore; // packageimport +import dwtx.jface.text.DocumentRewriteSessionType; // packageimport +import dwtx.jface.text.TextAttribute; // packageimport +import dwtx.jface.text.ITextViewerExtension4; // packageimport +import dwtx.jface.text.ITypedRegion; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.custom.StyleRange; +import dwt.custom.StyledText; +import dwt.custom.StyledTextContent; +import dwt.events.PaintEvent; +import dwt.events.PaintListener; +import dwt.graphics.Color; +import dwt.graphics.FontMetrics; +import dwt.graphics.GC; +import dwt.graphics.Point; + + +/** + * A painter for drawing visible characters for (invisible) whitespace + * characters. + * + * @since 3.3 + */ +public class WhitespaceCharacterPainter : IPainter, PaintListener { + + private static const char SPACE_SIGN= '\u00b7'; + private static const char IDEOGRAPHIC_SPACE_SIGN= '\u00b0'; + private static const char TAB_SIGN= '\u00bb'; + private static const char CARRIAGE_RETURN_SIGN= '\u00a4'; + private static const char LINE_FEED_SIGN= '\u00b6'; + + /** Indicates whether this painter is active. */ + private bool fIsActive= false; + /** The source viewer this painter is attached to. */ + private ITextViewer fTextViewer; + /** The viewer's widget. */ + private StyledText fTextWidget; + /** Tells whether the advanced graphics sub system is available. */ + private bool fIsAdvancedGraphicsPresent; + + /** + * Creates a new painter for the given text viewer. + * + * @param textViewer the text viewer the painter should be attached to + */ + public this(ITextViewer textViewer) { +// super(); + fTextViewer= textViewer; + fTextWidget= textViewer.getTextWidget(); + GC gc= new GC(fTextWidget); + gc.setAdvanced(true); + fIsAdvancedGraphicsPresent= gc.getAdvanced(); + gc.dispose(); + } + + /* + * @see dwtx.jface.text.IPainter#dispose() + */ + public void dispose() { + fTextViewer= null; + fTextWidget= null; + } + + /* + * @see dwtx.jface.text.IPainter#paint(int) + */ + public void paint(int reason) { + IDocument document= fTextViewer.getDocument(); + if (document is null) { + deactivate(false); + return; + } + if (!fIsActive) { + fIsActive= true; + fTextWidget.addPaintListener(this); + redrawAll(); + } else if (reason is CONFIGURATION || reason is INTERNAL) { + redrawAll(); + } else if (reason is TEXT_CHANGE) { + // redraw current line only + try { + IRegion lineRegion = + document.getLineInformationOfOffset(getDocumentOffset(fTextWidget.getCaretOffset())); + int widgetOffset= getWidgetOffset(lineRegion.getOffset()); + int charCount= fTextWidget.getCharCount(); + int redrawLength= Math.min(lineRegion.getLength(), charCount - widgetOffset); + if (widgetOffset >= 0 && redrawLength > 0) { + fTextWidget.redrawRange(widgetOffset, redrawLength, true); + } + } catch (BadLocationException e) { + // ignore + } + } + } + + /* + * @see dwtx.jface.text.IPainter#deactivate(bool) + */ + public void deactivate(bool redraw) { + if (fIsActive) { + fIsActive= false; + fTextWidget.removePaintListener(this); + if (redraw) { + redrawAll(); + } + } + } + + /* + * @see dwtx.jface.text.IPainter#setPositionManager(dwtx.jface.text.IPaintPositionManager) + */ + public void setPositionManager(IPaintPositionManager manager) { + // no need for a position manager + } + + /* + * @see dwt.events.PaintListener#paintControl(dwt.events.PaintEvent) + */ + public void paintControl(PaintEvent event) { + if (fTextWidget !is null) { + handleDrawRequest(event.gc, event.x, event.y, event.width, event.height); + } + } + + /** + * Draw characters in view range. + * + * @param gc + * @param x + * @param y + * @param w + * @param h + */ + private void handleDrawRequest(GC gc, int x, int y, int w, int h) { + int startLine= fTextWidget.getLineIndex(y); + int endLine= fTextWidget.getLineIndex(y + h - 1); + if (startLine <= endLine && startLine < fTextWidget.getLineCount()) { + if (fIsAdvancedGraphicsPresent) { + int alpha= gc.getAlpha(); + gc.setAlpha(100); + drawLineRange(gc, startLine, endLine, x, w); + gc.setAlpha(alpha); + } else + drawLineRange(gc, startLine, endLine, x, w); + } + } + + /** + * Draw the given line range. + * + * @param gc + * @param startLine first line number + * @param endLine last line number (inclusive) + * @param x the X-coordinate of the drawing range + * @param w the width of the drawing range + */ + private void drawLineRange(GC gc, int startLine, int endLine, int x, int w) { + final int viewPortWidth= fTextWidget.getClientArea().width; + for (int line= startLine; line <= endLine; line++) { + int lineOffset= fTextWidget.getOffsetAtLine(line); + // line end offset including line delimiter + int lineEndOffset; + if (line < fTextWidget.getLineCount() - 1) { + lineEndOffset= fTextWidget.getOffsetAtLine(line + 1); + } else { + lineEndOffset= fTextWidget.getCharCount(); + } + // line length excluding line delimiter + int lineLength= lineEndOffset - lineOffset; + while (lineLength > 0) { + char c= fTextWidget.getTextRange(lineOffset + lineLength - 1, 1).charAt(0); + if (c !is '\r' && c !is '\n') { + break; + } + --lineLength; + } + // compute coordinates of last character on line + Point endOfLine= fTextWidget.getLocationAtOffset(lineOffset + lineLength); + if (x - endOfLine.x > viewPortWidth) { + // line is not visible + continue; + } + // Y-coordinate of line + int y= fTextWidget.getLinePixel(line); + // compute first visible char offset + int startOffset; + try { + startOffset= fTextWidget.getOffsetAtLocation(new Point(x, y)) - 1; + if (startOffset - 2 <= lineOffset) { + startOffset= lineOffset; + } + } catch (IllegalArgumentException iae) { + startOffset= lineOffset; + } + // compute last visible char offset + int endOffset; + if (x + w >= endOfLine.x) { + // line end is visible + endOffset= lineEndOffset; + } else { + try { + endOffset= fTextWidget.getOffsetAtLocation(new Point(x + w - 1, y)) + 1; + if (endOffset + 2 >= lineEndOffset) { + endOffset= lineEndOffset; + } + } catch (IllegalArgumentException iae) { + endOffset= lineEndOffset; + } + } + // draw character range + if (endOffset > startOffset) { + drawCharRange(gc, startOffset, endOffset); + } + } + } + + /** + * Draw characters of content range. + * + * @param gc the GC + * @param startOffset inclusive start index + * @param endOffset exclusive end index + */ + private void drawCharRange(GC gc, int startOffset, int endOffset) { + StyledTextContent content= fTextWidget.getContent(); + int length= endOffset - startOffset; + String text= content.getTextRange(startOffset, length); + StyleRange styleRange= null; + Color fg= null; + Point selection= fTextWidget.getSelection(); + StringBuffer visibleChar= new StringBuffer(10); + for (int textOffset= 0; textOffset <= length; ++textOffset) { + int delta= 0; + bool eol= false; + if (textOffset < length) { + delta= 1; + char c= text.charAt(textOffset); + switch (c) { + case ' ' : + visibleChar.append(SPACE_SIGN); + // 'continue' would improve performance but may produce drawing errors + // for long runs of space if width of space and dot differ + break; + case '\u3000' : // ideographic whitespace + visibleChar.append(IDEOGRAPHIC_SPACE_SIGN); + // 'continue' would improve performance but may produce drawing errors + // for long runs of space if width of space and dot differ + break; + case '\t' : + visibleChar.append(TAB_SIGN); + break; + case '\r' : + visibleChar.append(CARRIAGE_RETURN_SIGN); + if (textOffset >= length - 1 || text.charAt(textOffset + 1) !is '\n') { + eol= true; + break; + } + continue; + case '\n' : + visibleChar.append(LINE_FEED_SIGN); + eol= true; + break; + default : + delta= 0; + break; + } + } + if (visibleChar.length() > 0) { + int widgetOffset= startOffset + textOffset - visibleChar.length() + delta; + if (!eol || !isFoldedLine(content.getLineAtOffset(widgetOffset))) { + if (widgetOffset >= selection.x && widgetOffset < selection.y) { + fg= fTextWidget.getSelectionForeground(); + } else if (styleRange is null || styleRange.start + styleRange.length <= widgetOffset) { + styleRange= fTextWidget.getStyleRangeAtOffset(widgetOffset); + if (styleRange is null || styleRange.foreground is null) { + fg= fTextWidget.getForeground(); + } else { + fg= styleRange.foreground; + } + } + draw(gc, widgetOffset, visibleChar.toString(), fg); + } + visibleChar.truncate(0); + } + } + } + + /** + * Check if the given widget line is a folded line. + * + * @param widgetLine the widget line number + * @return true if the line is folded + */ + private bool isFoldedLine(int widgetLine) { + if ( cast(ITextViewerExtension5)fTextViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5)fTextViewer; + int modelLine= extension.widgetLine2ModelLine(widgetLine); + int widgetLine2= extension.modelLine2WidgetLine(modelLine + 1); + return widgetLine2 is -1; + } + return false; + } + + /** + * Redraw all of the text widgets visible content. + */ + private void redrawAll() { + fTextWidget.redraw(); + } + + /** + * Draw string at widget offset. + * + * @param gc + * @param offset the widget offset + * @param s the string to be drawn + * @param fg the foreground color + */ + private void draw(GC gc, int offset, String s, Color fg) { + // Compute baseline delta (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=165640) + int baseline= fTextWidget.getBaseline(offset); + FontMetrics fontMetrics= gc.getFontMetrics(); + int fontBaseline= fontMetrics.getAscent() + fontMetrics.getLeading(); + int baslineDelta= baseline - fontBaseline; + + Point pos= fTextWidget.getLocationAtOffset(offset); + gc.setForeground(fg); + gc.drawString(s, pos.x, pos.y + baslineDelta, true); + } + + /** + * Convert a document offset to the corresponding widget offset. + * + * @param documentOffset + * @return widget offset + */ + private int getWidgetOffset(int documentOffset) { + if ( cast(ITextViewerExtension5)fTextViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5)fTextViewer; + return extension.modelOffset2WidgetOffset(documentOffset); + } + IRegion visible= fTextViewer.getVisibleRegion(); + int widgetOffset= documentOffset - visible.getOffset(); + if (widgetOffset > visible.getLength()) { + return -1; + } + return widgetOffset; + } + + /** + * Convert a widget offset to the corresponding document offset. + * + * @param widgetOffset + * @return document offset + */ + private int getDocumentOffset(int widgetOffset) { + if ( cast(ITextViewerExtension5)fTextViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5)fTextViewer; + return extension.widgetOffset2ModelOffset(widgetOffset); + } + IRegion visible= fTextViewer.getVisibleRegion(); + if (widgetOffset > visible.getLength()) { + return -1; + } + return widgetOffset + visible.getOffset(); + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/AdditionalInfoController.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/AdditionalInfoController.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,658 @@ +/******************************************************************************* + * 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 + * 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.text.contentassist.AdditionalInfoController; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + +import dwt.dwthelper.utils; +import tango.core.Thread; + +import dwt.events.SelectionEvent; +import dwt.events.SelectionListener; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Shell; +import dwt.widgets.Table; +import dwt.widgets.TableItem; +import dwtx.core.runtime.Assert; +import dwtx.core.runtime.IProgressMonitor; +import dwtx.core.runtime.IStatus; +import dwtx.core.runtime.Status; +import dwtx.core.runtime.jobs.Job; +import dwtx.jface.internal.text.InformationControlReplacer; +import dwtx.jface.text.AbstractInformationControlManager; +import dwtx.jface.text.AbstractReusableInformationControlCreator; +import dwtx.jface.text.DefaultInformationControl; +import dwtx.jface.text.IInformationControl; +import dwtx.jface.text.IInformationControlCreator; +import dwtx.jface.text.IInformationControlExtension3; + + +/** + * Displays the additional information available for a completion proposal. + * + * @since 2.0 + */ +class AdditionalInfoController : AbstractInformationControlManager { + + /** + * A timer thread. + * + * @since 3.2 + */ + private static abstract class Timer { + private static const int DELAY_UNTIL_JOB_IS_SCHEDULED= 50; + + /** + * A Task is {@link Task#run() run} when {@link #delay()} milliseconds have + * elapsed after it was scheduled without a {@link #reset(ICompletionProposal) reset} + * to occur. + */ + private static abstract class Task : Runnable { + /** + * @return the delay in milliseconds before this task should be run + */ + public abstract long delay(); + /** + * Runs this task. + */ + public abstract void run(); + /** + * @return the task to be scheduled after this task has been run + */ + public abstract Task nextTask(); + } + + /** + * IDLE: the initial task, and active whenever the info has been shown. It cannot be run, + * but specifies an infinite delay. + */ + private Task IDLE; + private void IDLE_init(){ + IDLE = new class() Task { + public void run() { + Assert.isTrue(false); + } + + public Task nextTask() { + Assert.isTrue(false); + return null; + } + + public long delay() { + return Long.MAX_VALUE; + } + + public override String toString() { + return "IDLE"; //$NON-NLS-1$ + } + }; + } + /** + * FIRST_WAIT: Schedules a platform {@link Job} to fetch additional info from an {@link ICompletionProposalExtension5}. + */ + private Task FIRST_WAIT; + private void FIRST_WAIT_init() { + FIRST_WAIT = new class() Task { + public void run() { + final ICompletionProposalExtension5 proposal= getCurrentProposalEx(); + Job job= new class(JFaceTextMessages.getString("AdditionalInfoController.job_name")) Job { //$NON-NLS-1$ + this( String txt ){ + super( txt ); + } + protected IStatus run(IProgressMonitor monitor) { + Object info; + try { + info= proposal.getAdditionalProposalInfo(monitor); + } catch (RuntimeException x) { + /* + * XXX: This is the safest fix at this point so close to end of 3.2. + * Will be revisited when fixing https://bugs.eclipse.org/bugs/show_bug.cgi?id=101033 + */ + return new Status(IStatus.WARNING, "dwtx.jface.text", IStatus.OK, "", x); //$NON-NLS-1$ //$NON-NLS-2$ + } + setInfo(cast(ICompletionProposal) proposal, info); + return new Status(IStatus.OK, "dwtx.jface.text", IStatus.OK, "", null); //$NON-NLS-1$ //$NON-NLS-2$ + } + }; + job.schedule(); + } + + public Task nextTask() { + return SECOND_WAIT; + } + + public long delay() { + return DELAY_UNTIL_JOB_IS_SCHEDULED; + } + + public override String toString() { + return "FIRST_WAIT"; //$NON-NLS-1$ + } + }; + } + /** + * SECOND_WAIT: Allows display of additional info obtained from an + * {@link ICompletionProposalExtension5}. + */ + private Task SECOND_WAIT; + private void SECOND_WAIT_init() { + SECOND_WAIT = new class() Task { + public void run() { + // show the info + allowShowing(); + } + + public Task nextTask() { + return IDLE; + } + + public long delay() { + return fDelay - DELAY_UNTIL_JOB_IS_SCHEDULED; + } + + public override String toString() { + return "SECOND_WAIT"; //$NON-NLS-1$ + } + }; + } + /** + * LEGACY_WAIT: Posts a runnable into the display thread to fetch additional info from non-{@link ICompletionProposalExtension5}s. + */ + private Task LEGACY_WAIT; + private void LEGACY_WAIT_init() { + LEGACY_WAIT = new class() Task { + public void run() { + final ICompletionProposal proposal= getCurrentProposal(); + if (!fDisplay.isDisposed()) { + fDisplay.asyncExec(new class() Runnable { + public void run() { + synchronized (this.outer) { + if (proposal is getCurrentProposal()) { + Object info= stringcast(proposal.getAdditionalProposalInfo()); + showInformation(proposal, info); + } + } + } + }); + } + } + + public Task nextTask() { + return IDLE; + } + + public long delay() { + return fDelay; + } + + public override String toString() { + return "LEGACY_WAIT"; //$NON-NLS-1$ + } + }; + } + /** + * EXIT: The task that triggers termination of the timer thread. + */ + private Task EXIT; + private void EXIT_init() { + EXIT = new class() Task { + public long delay() { + return 1; + } + + public Task nextTask() { + Assert.isTrue(false); + return EXIT; + } + + public void run() { + Assert.isTrue(false); + } + + public override String toString() { + return "EXIT"; //$NON-NLS-1$ + } + }; + } + + /** The timer thread. */ + private const Thread fThread; + + /** The currently waiting / active task. */ + private Task fTask; + /** The next wake up time. */ + private long fNextWakeup; + + private ICompletionProposal fCurrentProposal= null; + private Object fCurrentInfo= null; + private bool fAllowShowing= false; + + private const Display fDisplay; + private const int fDelay; + + /** + * Creates a new timer. + * + * @param display the display to use for display thread posting. + * @param delay the delay until to show additional info + */ + public this(Display display, int delay) { + // DWT instance init + IDLE_init(); + FIRST_WAIT_init(); + SECOND_WAIT_init(); + LEGACY_WAIT_init(); + EXIT_init(); + + fDisplay= display; + fDelay= delay; + long current= System.currentTimeMillis(); + schedule(IDLE, current); + + void threadrun() { + try { + loop(); + } catch (InterruptedException x) { + } + } + fThread= new Thread( &threadrun ); + fThread.name = JFaceTextMessages.getString("InfoPopup.info_delay_timer_name"); //$NON-NLS-1$ + fThread.start(); + } + + /** + * Terminates the timer thread. + */ + public synchronized final void terminate() { + schedule(EXIT, System.currentTimeMillis()); + notifyAll(); + } + + /** + * Resets the timer thread as the selection has changed to a new proposal. + * + * @param p the new proposal + */ + public final synchronized void reset(ICompletionProposal p) { + if (fCurrentProposal !is p) { + fCurrentProposal= p; + fCurrentInfo= null; + fAllowShowing= false; + + long oldWakeup= fNextWakeup; + Task task= taskOnReset(p); + schedule(task, System.currentTimeMillis()); + if (fNextWakeup < oldWakeup) + notifyAll(); + } + } + + private Task taskOnReset(ICompletionProposal p) { + if (p is null) + return IDLE; + if (isExt5(p)) + return FIRST_WAIT; + return LEGACY_WAIT; + } + + private synchronized void loop() { + long current= System.currentTimeMillis(); + Task task= currentTask(); + + while (task !is EXIT) { + long delay= fNextWakeup - current; + if (delay <= 0) { + task.run(); + task= task.nextTask(); + schedule(task, current); + } else { + wait(delay); + current= System.currentTimeMillis(); + task= currentTask(); + } + } + } + + private Task currentTask() { + return fTask; + } + + private void schedule(Task task, long current) { + fTask= task; + long nextWakeup= current + task.delay(); + if (nextWakeup <= current) + fNextWakeup= Long.MAX_VALUE; + else + fNextWakeup= nextWakeup; + } + + private bool isExt5(ICompletionProposal p) { + return cast(ICompletionProposalExtension5)p; + } + + ICompletionProposal getCurrentProposal() { + return fCurrentProposal; + } + + ICompletionProposalExtension5 getCurrentProposalEx() { + Assert.isTrue( cast(ICompletionProposalExtension5)fCurrentProposal ); + return cast(ICompletionProposalExtension5) fCurrentProposal; + } + + synchronized void setInfo(ICompletionProposal proposal, Object info) { + if (proposal is fCurrentProposal) { + fCurrentInfo= info; + if (fAllowShowing) { + triggerShowing(); + } + } + } + + private void triggerShowing() { + final Object info= fCurrentInfo; + if (!fDisplay.isDisposed()) { + fDisplay.asyncExec(new class() Runnable { + public void run() { + synchronized (this.outer) { + if (info is fCurrentInfo) { + showInformation(fCurrentProposal, info); + } + } + } + }); + } + } + + /** + * Called in the display thread to show additional info. + * + * @param proposal the proposal to show information about + * @param info the information about proposal + */ + protected abstract void showInformation(ICompletionProposal proposal, Object info); + + void allowShowing() { + fAllowShowing= true; + triggerShowing(); + } + } + /** + * Internal table selection listener. + */ + private class TableSelectionListener : SelectionListener { + + /* + * @see SelectionListener#widgetSelected(SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + handleTableSelectionChanged(); + } + + /* + * @see SelectionListener#widgetDefaultSelected(SelectionEvent) + */ + public void widgetDefaultSelected(SelectionEvent e) { + } + } + + /** + * Default control creator for the information control replacer. + * @since 3.4 + */ + private static class DefaultPresenterControlCreator : AbstractReusableInformationControlCreator { + public IInformationControl doCreateInformationControl(Shell shell) { + return new DefaultInformationControl(shell, true); + } + } + + /** The proposal table. */ + private Table fProposalTable; + /** The table selection listener */ + private SelectionListener fSelectionListener; + /** The delay after which additional information is displayed */ + private const int fDelay; + /** + * The timer thread. + * @since 3.2 + */ + private Timer fTimer; + /** + * The proposal most recently set by {@link #showInformation(ICompletionProposal, Object)}, + * possibly null. + * @since 3.2 + */ + private ICompletionProposal fProposal; + /** + * The information most recently set by {@link #showInformation(ICompletionProposal, Object)}, + * possibly null. + * @since 3.2 + */ + private Object fInformation; + + /** + * Creates a new additional information controller. + * + * @param creator the information control creator to be used by this controller + * @param delay time in milliseconds after which additional info should be displayed + */ + this(IInformationControlCreator creator, int delay) { + + fSelectionListener= new TableSelectionListener(); + + super(creator); + fDelay= delay; + setAnchor(ANCHOR_RIGHT); + setFallbackAnchors([ ANCHOR_RIGHT, ANCHOR_LEFT, ANCHOR_BOTTOM ]); + + /* + * Adjust the location by one pixel towards the proposal popup, so that the single pixel + * border of the additional info popup overlays with the border of the popup. This avoids + * having a double black line. + */ + int spacing= -1; + setMargins(spacing, spacing); // see also adjustment in #computeLocation + + InformationControlReplacer replacer= new InformationControlReplacer(new DefaultPresenterControlCreator()); + getInternalAccessor().setInformationControlReplacer(replacer); + } + + /* + * @see AbstractInformationControlManager#install(Control) + */ + public void install(Control control) { + + if (fProposalTable is control) { + // already installed + return; + } + + super.install(control.getShell()); + + Assert.isTrue( cast(Table)control ); + fProposalTable= cast(Table) control; + fProposalTable.addSelectionListener(fSelectionListener); + getInternalAccessor().getInformationControlReplacer().install(fProposalTable); + + fTimer= new class(fProposalTable.getDisplay(), fDelay) Timer { + protected void showInformation(ICompletionProposal proposal, Object info) { + InformationControlReplacer replacer= getInternalAccessor().getInformationControlReplacer(); + if (replacer !is null) + replacer.hideInformationControl(); + this.outer.showInformation(proposal, info); + } + }; + } + + /* + * @see AbstractInformationControlManager#disposeInformationControl() + */ + public void disposeInformationControl() { + + if (fTimer !is null) { + fTimer.terminate(); + fTimer= null; + } + + fProposal= null; + fInformation= null; + + if (fProposalTable !is null && !fProposalTable.isDisposed()) { + fProposalTable.removeSelectionListener(fSelectionListener); + fProposalTable= null; + } + + super.disposeInformationControl(); + } + + /** + *Handles a change of the line selected in the associated selector. + */ + public void handleTableSelectionChanged() { + + if (fProposalTable !is null && !fProposalTable.isDisposed() && fProposalTable.isVisible()) { + TableItem[] selection= fProposalTable.getSelection(); + if (selection !is null && selection.length > 0) { + + TableItem item= selection[0]; + + Object d= item.getData(); + if ( cast(ICompletionProposal)d ) { + ICompletionProposal p= cast(ICompletionProposal) d; + fTimer.reset(p); + } + } + } + } + + void showInformation(ICompletionProposal proposal, Object info) { + if (fProposalTable is null || fProposalTable.isDisposed()) + return; + + if (fProposal is proposal && ((info is null && fInformation is null) || (info !is null && info.equals(fInformation)))) + return; + + fInformation= info; + fProposal= proposal; + showInformation(); + } + + /* + * @see AbstractInformationControlManager#computeInformation() + */ + protected void computeInformation() { + if ( cast(ICompletionProposalExtension3)fProposal ) + setCustomInformationControlCreator((cast(ICompletionProposalExtension3) fProposal).getInformationControlCreator()); + else + setCustomInformationControlCreator(null); + + // compute subject area + Point size= fProposalTable.getShell().getSize(); + + // set information & subject area + setInformation(fInformation, new Rectangle(0, 0, size.x, size.y)); + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#computeLocation(dwt.graphics.Rectangle, dwt.graphics.Point, dwtx.jface.text.AbstractInformationControlManager.Anchor) + */ + protected Point computeLocation(Rectangle subjectArea, Point controlSize, Anchor anchor) { + Point location= super.computeLocation(subjectArea, controlSize, anchor); + + /* + * The location is computed using subjectControl.toDisplay(), which does not include the + * trim of the subject control. As we want the additional info popup aligned with the outer + * coordinates of the proposal popup, adjust this here + */ + Rectangle trim= fProposalTable.getShell().computeTrim(0, 0, 0, 0); + location.x += trim.x; + location.y += trim.y; + + return location; + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#computeSizeConstraints(Control, IInformationControl) + */ + protected Point computeSizeConstraints(Control subjectControl, IInformationControl informationControl) { + // at least as big as the proposal table + Point sizeConstraint= super.computeSizeConstraints(subjectControl, informationControl); + Point size= subjectControl.getShell().getSize(); + + // AbstractInformationControlManager#internalShowInformationControl(Rectangle, Object) adds trims + // to the computed constraints. Need to remove them here, to make the outer bounds of the additional + // info shell fit the bounds of the proposal shell: + if ( cast(IInformationControlExtension3)fInformationControl ) { + Rectangle shellTrim= (cast(IInformationControlExtension3) fInformationControl).computeTrim(); + size.x -= shellTrim.width; + size.y -= shellTrim.height; + } + + if (sizeConstraint.x < size.x) + sizeConstraint.x= size.x; + if (sizeConstraint.y < size.y) + sizeConstraint.y= size.y; + return sizeConstraint; + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#hideInformationControl() + */ + protected void hideInformationControl() { + super.hideInformationControl(); + } + package void hideInformationControl_package() { + this.hideInformationControl(); + } + + /** + * @return the current information control, or null if none available + */ + public IInformationControl getCurrentInformationControl2() { + return getInternalAccessor().getCurrentInformationControl(); + } +} + + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/CompletionProposal.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/CompletionProposal.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,170 @@ +/******************************************************************************* + * 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 + * 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.text.contentassist.CompletionProposal; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + + + + +import dwt.graphics.Image; +import dwt.graphics.Point; +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; + + +/** + * The standard implementation of the ICompletionProposal interface. + */ +public final class CompletionProposal : ICompletionProposal { + + /** The string to be displayed in the completion proposal popup. */ + private String fDisplayString; + /** The replacement string. */ + private String fReplacementString; + /** The replacement offset. */ + private int fReplacementOffset; + /** The replacement length. */ + private int fReplacementLength; + /** The cursor position after this proposal has been applied. */ + private int fCursorPosition; + /** The image to be displayed in the completion proposal popup. */ + private Image fImage; + /** The context information of this proposal. */ + private IContextInformation fContextInformation; + /** The additional info of this proposal. */ + private String fAdditionalProposalInfo; + + /** + * Creates a new completion proposal based on the provided information. The replacement string is + * considered being the display string too. All remaining fields are set to null. + * + * @param replacementString the actual string to be inserted into the document + * @param replacementOffset the offset of the text to be replaced + * @param replacementLength the length of the text to be replaced + * @param cursorPosition the position of the cursor following the insert relative to replacementOffset + */ + public this(String replacementString, int replacementOffset, int replacementLength, int cursorPosition) { + this(replacementString, replacementOffset, replacementLength, cursorPosition, null, null, null, null); + } + + /** + * Creates a new completion proposal. All fields are initialized based on the provided information. + * + * @param replacementString the actual string to be inserted into the document + * @param replacementOffset the offset of the text to be replaced + * @param replacementLength the length of the text to be replaced + * @param cursorPosition the position of the cursor following the insert relative to replacementOffset + * @param image the image to display for this proposal + * @param displayString the string to be displayed for the proposal + * @param contextInformation the context information associated with this proposal + * @param additionalProposalInfo the additional information associated with this proposal + */ + public this(String replacementString, int replacementOffset, int replacementLength, int cursorPosition, Image image, String displayString, IContextInformation contextInformation, String additionalProposalInfo) { + Assert.isNotNull(replacementString); + Assert.isTrue(replacementOffset >= 0); + Assert.isTrue(replacementLength >= 0); + Assert.isTrue(cursorPosition >= 0); + + fReplacementString= replacementString; + fReplacementOffset= replacementOffset; + fReplacementLength= replacementLength; + fCursorPosition= cursorPosition; + fImage= image; + fDisplayString= displayString; + fContextInformation= contextInformation; + fAdditionalProposalInfo= additionalProposalInfo; + } + + /* + * @see ICompletionProposal#apply(IDocument) + */ + public void apply(IDocument document) { + try { + document.replace(fReplacementOffset, fReplacementLength, fReplacementString); + } catch (BadLocationException x) { + // ignore + } + } + + /* + * @see ICompletionProposal#getSelection(IDocument) + */ + public Point getSelection(IDocument document) { + return new Point(fReplacementOffset + fCursorPosition, 0); + } + + /* + * @see ICompletionProposal#getContextInformation() + */ + public IContextInformation getContextInformation() { + return fContextInformation; + } + + /* + * @see ICompletionProposal#getImage() + */ + public Image getImage() { + return fImage; + } + + /* + * @see ICompletionProposal#getDisplayString() + */ + public String getDisplayString() { + if (fDisplayString !is null) + return fDisplayString; + return fReplacementString; + } + + /* + * @see ICompletionProposal#getAdditionalProposalInfo() + */ + public String getAdditionalProposalInfo() { + return fAdditionalProposalInfo; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/CompletionProposalPopup.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/CompletionProposalPopup.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,1884 @@ +/******************************************************************************* + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Sean Montgomery, sean_montgomery@comcast.net - https://bugs.eclipse.org/bugs/show_bug.cgi?id=116454 + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.text.contentassist.CompletionProposalPopup; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + +import dwt.DWT; +import dwt.custom.BusyIndicator; +import dwt.custom.StyleRange; +import dwt.events.ControlEvent; +import dwt.events.ControlListener; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.events.FocusEvent; +import dwt.events.FocusListener; +import dwt.events.KeyAdapter; +import dwt.events.KeyEvent; +import dwt.events.KeyListener; +import dwt.events.MouseAdapter; +import dwt.events.MouseEvent; +import dwt.events.SelectionEvent; +import dwt.events.SelectionListener; +import dwt.events.TraverseEvent; +import dwt.events.TraverseListener; +import dwt.events.VerifyEvent; +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.layout.GridData; +import dwt.layout.GridLayout; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Label; +import dwt.widgets.Listener; +import dwt.widgets.Shell; +import dwt.widgets.Table; +import dwt.widgets.TableItem; +import dwtx.core.commands.AbstractHandler; +import dwtx.core.commands.ExecutionEvent; +import dwtx.core.commands.ExecutionException; +import dwtx.core.commands.IHandler; +import dwtx.core.runtime.Assert; +import dwtx.jface.bindings.keys.KeySequence; +import dwtx.jface.bindings.keys.SWTKeySupport; +import dwtx.jface.contentassist.IContentAssistSubjectControl; +import dwtx.jface.internal.text.InformationControlReplacer; +import dwtx.jface.internal.text.TableOwnerDrawSupport; +import dwtx.jface.preference.JFacePreferences; +import dwtx.jface.resource.JFaceResources; +import dwtx.jface.text.AbstractInformationControlManager; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentListener; +import dwtx.jface.text.IEditingSupport; +import dwtx.jface.text.IEditingSupportRegistry; +import dwtx.jface.text.IInformationControl; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.IRewriteTarget; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.ITextViewerExtension; +import dwtx.jface.text.TextUtilities; +import dwtx.jface.text.AbstractInformationControlManager; +import dwtx.jface.util.Geometry; +import dwtx.jface.viewers.StyledString; + + +/** + * This class is used to present proposals to the user. If additional + * information exists for a proposal, then selecting that proposal + * will result in the information being displayed in a secondary + * window. + * + * @see dwtx.jface.text.contentassist.ICompletionProposal + * @see dwtx.jface.text.contentassist.AdditionalInfoController + */ +class CompletionProposalPopup : IContentAssistListener { + /** + * Set to true to use a Table with DWT.VIRTUAL. + * XXX: This is a workaround for: https://bugs.eclipse.org/bugs/show_bug.cgi?id=90321 + * More details see also: https://bugs.eclipse.org/bugs/show_bug.cgi?id=98585#c36 + * @since 3.1 + */ + private static bool USE_VIRTUAL_; + private static bool USE_VIRTUAL_init = false;; + private static bool USE_VIRTUAL(){ + if( !USE_VIRTUAL_init ){ + USE_VIRTUAL_init = true; + USE_VIRTUAL_ = !"motif".equals(DWT.getPlatform()); //$NON-NLS-1$ + } + return USE_VIRTUAL_; + } + + /** + * Completion proposal selection handler. + * + * @since 3.4 + */ + final class ProposalSelectionHandler : AbstractHandler { + + /** + * Selection operation codes. + */ + static const int SELECT_NEXT= 1; + static const int SELECT_PREVIOUS= 2; + + + private int fOperationCode; + + /** + * Creates a new selection handler. + * + * @param operationCode the operation code + * @since 3.4 + */ + public this(int operationCode) { + Assert.isLegal(operationCode is SELECT_NEXT || operationCode is SELECT_PREVIOUS); + fOperationCode= operationCode; + } + + /* + * @see dwtx.core.commands.AbstractHandler#execute(dwtx.core.commands.ExecutionEvent) + * @since 3.4 + */ + public Object execute(ExecutionEvent event) { + int itemCount= fProposalTable.getItemCount(); + int selectionIndex= fProposalTable.getSelectionIndex(); + switch (fOperationCode) { + case SELECT_NEXT: + selectionIndex+= 1; + if (selectionIndex > itemCount - 1) + selectionIndex= 0; + break; + case SELECT_PREVIOUS: + selectionIndex-= 1; + if (selectionIndex < 0) + selectionIndex= itemCount - 1; + break; + } + selectProposal(selectionIndex, false); + return null; + } + + } + + + /** + * The empty proposal displayed if there is nothing else to show. + * + * @since 3.2 + */ + private static final class EmptyProposal : ICompletionProposal, ICompletionProposalExtension { + + String fDisplayString; + int fOffset; + /* + * @see ICompletionProposal#apply(IDocument) + */ + public void apply(IDocument document) { + } + + /* + * @see ICompletionProposal#getSelection(IDocument) + */ + public Point getSelection(IDocument document) { + return new Point(fOffset, 0); + } + + /* + * @see ICompletionProposal#getContextInformation() + */ + public IContextInformation getContextInformation() { + return null; + } + + /* + * @see ICompletionProposal#getImage() + */ + public Image getImage() { + return null; + } + + /* + * @see ICompletionProposal#getDisplayString() + */ + public String getDisplayString() { + return fDisplayString; + } + + /* + * @see ICompletionProposal#getAdditionalProposalInfo() + */ + public String getAdditionalProposalInfo() { + return null; + } + + /* + * @see dwtx.jface.text.contentassist.ICompletionProposalExtension#apply(dwtx.jface.text.IDocument, char, int) + */ + public void apply(IDocument document, char trigger, int offset) { + } + + /* + * @see dwtx.jface.text.contentassist.ICompletionProposalExtension#isValidFor(dwtx.jface.text.IDocument, int) + */ + public bool isValidFor(IDocument document, int offset) { + return false; + } + + /* + * @see dwtx.jface.text.contentassist.ICompletionProposalExtension#getTriggerCharacters() + */ + public char[] getTriggerCharacters() { + return null; + } + + /* + * @see dwtx.jface.text.contentassist.ICompletionProposalExtension#getContextInformationPosition() + */ + public int getContextInformationPosition() { + return -1; + } + } + + private final class ProposalSelectionListener : KeyListener { + public void keyPressed(KeyEvent e) { + if (!Helper.okToUse(fProposalShell)) + return; + + if (e.character is 0 && e.keyCode is DWT.CTRL) { + // http://dev.eclipse.org/bugs/show_bug.cgi?id=34754 + int index= fProposalTable.getSelectionIndex(); + if (index >= 0) + selectProposal(index, true); + } + } + + public void keyReleased(KeyEvent e) { + if (!Helper.okToUse(fProposalShell)) + return; + + if (e.character is 0 && e.keyCode is DWT.CTRL) { + // http://dev.eclipse.org/bugs/show_bug.cgi?id=34754 + int index= fProposalTable.getSelectionIndex(); + if (index >= 0) + selectProposal(index, false); + } + } + } + + private final class CommandKeyListener : KeyAdapter { + private KeySequence fCommandSequence; + + private this(KeySequence keySequence) { + fCommandSequence= keySequence; + } + + public void keyPressed(KeyEvent e) { + if (!Helper.okToUse(fProposalShell)) + return; + + int accelerator= SWTKeySupport.convertEventToUnmodifiedAccelerator(e); + KeySequence sequence= KeySequence.getInstance(SWTKeySupport.convertAcceleratorToKeyStroke(accelerator)); + if (sequence==/++/fCommandSequence) + if (fContentAssistant.isPrefixCompletionEnabled()) + incrementalComplete(); + else + showProposals(false); + + } + } + + + /** The associated text viewer. */ + private ITextViewer fViewer; + /** The associated content assistant. */ + private ContentAssistant fContentAssistant; + /** The used additional info controller. */ + private AdditionalInfoController fAdditionalInfoController; + /** The closing strategy for this completion proposal popup. */ + private PopupCloser fPopupCloser; + /** The popup shell. */ + private Shell fProposalShell; + /** The proposal table. */ + private Table fProposalTable; + /** Indicates whether a completion proposal is being inserted. */ + private bool fInserting= false; + /** The key listener to control navigation. */ + private ProposalSelectionListener fKeyListener; + /** List of document events used for filtering proposals. */ + private List fDocumentEvents; + /** Listener filling the document event queue. */ + private IDocumentListener fDocumentListener; + /** The filter list of proposals. */ + private ICompletionProposal[] fFilteredProposals; + /** The computed list of proposals. */ + private ICompletionProposal[] fComputedProposals; + /** The offset for which the proposals have been computed. */ + private int fInvocationOffset; + /** The offset for which the computed proposals have been filtered. */ + private int fFilterOffset; + /** + * The most recently selected proposal. + * @since 3.0 + */ + private ICompletionProposal fLastProposal; + /** + * The content assist subject control. + * This replaces fViewer + * + * @since 3.0 + */ + private IContentAssistSubjectControl fContentAssistSubjectControl; + /** + * The content assist subject control adapter. + * This replaces fViewer + * + * @since 3.0 + */ + private ContentAssistSubjectControlAdapter fContentAssistSubjectControlAdapter; + /** + * Remembers the size for this completion proposal popup. + * @since 3.0 + */ + private Point fSize; + /** + * Editor helper that communicates that the completion proposal popup may + * have focus while the 'logical focus' is still with the editor. + * @since 3.1 + */ + private IEditingSupport fFocusHelper; + /** + * Set to true by {@link #computeFilteredProposals(int, DocumentEvent)} if + * the returned proposals are a subset of {@link #fFilteredProposals}, + * false if not. + * @since 3.1 + */ + private bool fIsFilteredSubset; + /** + * The filter runnable. + * + * @since 3.1.1 + */ + private Runnable fFilterRunnable; + private void fFilterRunnableInit(){ + fFilterRunnable = dgRunnable( { + if (!fIsFilterPending) + return; + + fIsFilterPending= false; + + if (!Helper.okToUse(fContentAssistSubjectControlAdapter.getControl())) + return; + + int offset= fContentAssistSubjectControlAdapter.getSelectedRange().x; + ICompletionProposal[] proposals= null; + try { + if (offset > -1) { + DocumentEvent event= TextUtilities.mergeProcessedDocumentEvents(fDocumentEvents); + proposals= computeFilteredProposals(offset, event); + } + } catch (BadLocationException x) { + } finally { + fDocumentEvents.clear(); + } + fFilterOffset= offset; + + if (proposals !is null && proposals.length > 0) + setProposals(proposals, fIsFilteredSubset); + else + hide(); + }); + } + + /** + * true if fFilterRunnable has been + * posted, false if not. + * + * @since 3.1.1 + */ + private bool fIsFilterPending= false; + /** + * The info message at the bottom of the popup, or null for no popup (if + * ContentAssistant does not provide one). + * + * @since 3.2 + */ + private Label fMessageText; + /** + * The font used for fMessageText or null; dispose when done. + * + * @since 3.2 + */ + private Font fMessageTextFont; + /** + * The most recent completion offset (used to determine repeated invocation) + * + * @since 3.2 + */ + private int fLastCompletionOffset; + /** + * The (reusable) empty proposal. + * + * @since 3.2 + */ + private EmptyProposal fEmptyProposal; + /** + * The text for the empty proposal, or null to use the default text. + * + * @since 3.2 + */ + private String fEmptyMessage= null; + /** + * Tells whether colored labels support is enabled. + * Only valid while the popup is active. + * + * @since 3.4 + */ + private bool fIsColoredLabelsSupportEnabled= false; + + + /** + * Creates a new completion proposal popup for the given elements. + * + * @param contentAssistant the content assistant feeding this popup + * @param viewer the viewer on top of which this popup appears + * @param infoController the information control collaborating with this popup + * @since 2.0 + */ + public this(ContentAssistant contentAssistant, ITextViewer viewer, AdditionalInfoController infoController) { + // DWT instance init + fDocumentEvents= new ArrayList(); + fPopupCloser= new PopupCloser(); + if( fEmptyProposal is null ) fEmptyProposal= new EmptyProposal(); + fFilterRunnableInit(); + + fContentAssistant= contentAssistant; + fViewer= viewer; + fAdditionalInfoController= infoController; + fContentAssistSubjectControlAdapter= new ContentAssistSubjectControlAdapter(fViewer); + } + + /** + * Creates a new completion proposal popup for the given elements. + * + * @param contentAssistant the content assistant feeding this popup + * @param contentAssistSubjectControl the content assist subject control on top of which this popup appears + * @param infoController the information control collaborating with this popup + * @since 3.0 + */ + public this(ContentAssistant contentAssistant, IContentAssistSubjectControl contentAssistSubjectControl, AdditionalInfoController infoController) { + // DWT instance init + fDocumentEvents= new ArrayList(); + fPopupCloser= new PopupCloser(); + if( fEmptyProposal is null ) fEmptyProposal= new EmptyProposal(); + fFilterRunnableInit(); + + fContentAssistant= contentAssistant; + fContentAssistSubjectControl= contentAssistSubjectControl; + fAdditionalInfoController= infoController; + fContentAssistSubjectControlAdapter= new ContentAssistSubjectControlAdapter(fContentAssistSubjectControl); + } + + /** + * Computes and presents completion proposals. The flag indicates whether this call has + * be made out of an auto activation context. + * + * @param autoActivated true if auto activation context + * @return an error message or null in case of no error + */ + public String showProposals(bool autoActivated) { + + if (fKeyListener is null) + fKeyListener= new ProposalSelectionListener(); + + final Control control= fContentAssistSubjectControlAdapter.getControl(); + + if (!Helper.okToUse(fProposalShell) && control !is null && !control.isDisposed()) { + // add the listener before computing the proposals so we don't move the caret + // when the user types fast. + fContentAssistSubjectControlAdapter.addKeyListener(fKeyListener); + + BusyIndicator.showWhile(control.getDisplay(), dgRunnable((bool autoActivated_) { + + fInvocationOffset= fContentAssistSubjectControlAdapter.getSelectedRange().x; + fFilterOffset= fInvocationOffset; + fLastCompletionOffset= fFilterOffset; + fComputedProposals= computeProposals(fInvocationOffset); + + int count= (fComputedProposals is null ? 0 : fComputedProposals.length); + if (count is 0 && hideWhenNoProposals(autoActivated_)) + return; + + if (count is 1 && !autoActivated_ && canAutoInsert(fComputedProposals[0])) { + insertProposal(fComputedProposals[0], cast(wchar) 0, 0, fInvocationOffset); + hide(); + } else { + createProposalSelector(); + setProposals(fComputedProposals, false); + displayProposals(); + } + }, autoActivated )); + } else { + fLastCompletionOffset= fFilterOffset; + handleRepeatedInvocation(); + } + + return getErrorMessage(); + } + + /** + * Hides the popup and returns true if the popup is configured + * to never display an empty list. Returns false otherwise. + * + * @param autoActivated whether the invocation was auto-activated + * @return false if an empty list should be displayed, true otherwise + * @since 3.2 + */ + private bool hideWhenNoProposals(bool autoActivated) { + if (autoActivated || !fContentAssistant.isShowEmptyList()) { + if (!autoActivated) { + Control control= fContentAssistSubjectControlAdapter.getControl(); + if (control !is null && !control.isDisposed()) + control.getDisplay().beep(); + } + hide(); + return true; + } + return false; + } + + /** + * If content assist is set up to handle cycling, then the proposals are recomputed. Otherwise, + * nothing happens. + * + * @since 3.2 + */ + private void handleRepeatedInvocation() { + if (fContentAssistant.isRepeatedInvocationMode()) { + fComputedProposals= computeProposals(fFilterOffset); + setProposals(fComputedProposals, false); + } + } + + /** + * Returns the completion proposal available at the given offset of the + * viewer's document. Delegates the work to the content assistant. + * + * @param offset the offset + * @return the completion proposals available at this offset + */ + private ICompletionProposal[] computeProposals(int offset) { + if (fContentAssistSubjectControl !is null) + return fContentAssistant.computeCompletionProposals(fContentAssistSubjectControl, offset); + return fContentAssistant.computeCompletionProposals(fViewer, offset); + } + + /** + * Returns the error message. + * + * @return the error message + */ + private String getErrorMessage() { + return fContentAssistant.getErrorMessage(); + } + + /** + * Creates the proposal selector. + */ + private void createProposalSelector() { + if (Helper.okToUse(fProposalShell)) + return; + + Control control= fContentAssistSubjectControlAdapter.getControl(); + fProposalShell= new Shell(control.getShell(), DWT.ON_TOP | DWT.RESIZE ); + fProposalShell.setFont(JFaceResources.getDefaultFont()); + if (USE_VIRTUAL) { + fProposalTable= new Table(fProposalShell, DWT.H_SCROLL | DWT.V_SCROLL | DWT.VIRTUAL); + + Listener listener= new class() Listener { + public void handleEvent(Event event) { + handleSetData(event); + } + }; + fProposalTable.addListener(DWT.SetData, listener); + } else { + fProposalTable= new Table(fProposalShell, DWT.H_SCROLL | DWT.V_SCROLL); + } + + fIsColoredLabelsSupportEnabled= fContentAssistant.isColoredLabelsSupportEnabled(); + if (fIsColoredLabelsSupportEnabled) + TableOwnerDrawSupport.install(fProposalTable); + + fProposalTable.setLocation(0, 0); + if (fAdditionalInfoController !is null) + fAdditionalInfoController.setSizeConstraints(50, 10, true, true); + + GridLayout layout= new GridLayout(); + layout.marginWidth= 0; + layout.marginHeight= 0; + layout.verticalSpacing= 1; + fProposalShell.setLayout(layout); + + if (fContentAssistant.isStatusLineVisible()) { + createMessageText(); + } + + GridData data= new GridData(GridData.FILL_BOTH); + + Point size= fContentAssistant.restoreCompletionProposalPopupSize_package(); + if (size !is null) { + fProposalTable.setLayoutData(data); + fProposalShell.setSize(size); + } else { + int height= fProposalTable.getItemHeight() * 10; + // use golden ratio as default aspect ratio + double aspectRatio= (1 + Math.sqrt(5.0f)) / 2; + int width= cast(int) (height * aspectRatio); + Rectangle trim= fProposalTable.computeTrim(0, 0, width, height); + data.heightHint= trim.height; + data.widthHint= trim.width; + fProposalTable.setLayoutData(data); + fProposalShell.pack(); + } + fContentAssistant.addToLayout(this, fProposalShell, ContentAssistant.LayoutManager.LAYOUT_PROPOSAL_SELECTOR, fContentAssistant.getSelectionOffset()); + + fProposalShell.addControlListener(new class() ControlListener { + + public void controlMoved(ControlEvent e) {} + + public void controlResized(ControlEvent e) { + if (fAdditionalInfoController !is null) { + // reset the cached resize constraints + fAdditionalInfoController.setSizeConstraints(50, 10, true, false); + } + + fSize= fProposalShell.getSize(); + } + }); + + fProposalShell.setBackground(control.getDisplay().getSystemColor(DWT.COLOR_GRAY)); + + Color c= getBackgroundColor(control); + fProposalTable.setBackground(c); + + c= getForegroundColor(control); + fProposalTable.setForeground(c); + + fProposalTable.addSelectionListener(new class() SelectionListener { + + public void widgetSelected(SelectionEvent e) {} + + public void widgetDefaultSelected(SelectionEvent e) { + insertSelectedProposalWithMask(e.stateMask); + } + }); + + fPopupCloser.install(fContentAssistant, fProposalTable, fAdditionalInfoController); + + fProposalShell.addDisposeListener(new class() DisposeListener { + public void widgetDisposed(DisposeEvent e) { + unregister(); // but don't dispose the shell, since we're being called from its disposal event! + } + }); + + fProposalTable.setHeaderVisible(false); + + addCommandSupport(fProposalTable); + } + + /** + * Returns the minimal required height for the proposal, may return 0 if the popup has not been + * created yet. + * + * @return the minimal height + * @since 3.3 + */ + int getMinimalHeight() { + int height= 0; + if (Helper.okToUse(fProposalTable)) { + int items= fProposalTable.getItemHeight() * 10; + Rectangle trim= fProposalTable.computeTrim(0, 0, DWT.DEFAULT, items); + height= trim.height; + } + if (Helper.okToUse(fMessageText)) + height+= fMessageText.getSize().y + 1; + return height; + } + + /** + * Adds command support to the given control. + * + * @param control the control to watch for focus + * @since 3.2 + */ + private void addCommandSupport(Control control) { + final KeySequence commandSequence= fContentAssistant.getRepeatedInvocationKeySequence(); + if (commandSequence !is null && !commandSequence.isEmpty() && fContentAssistant.isRepeatedInvocationMode()) { + control.addFocusListener(new class(control,commandSequence) FocusListener { + Control control_; + KeySequence commandSequence_; + this(Control a, KeySequence b){ + control_=a; + commandSequence_=b; + } + private CommandKeyListener fCommandKeyListener; + public void focusGained(FocusEvent e) { + if (Helper.okToUse(control_)) { + if (fCommandKeyListener is null) { + fCommandKeyListener= new CommandKeyListener(commandSequence_); + fProposalTable.addKeyListener(fCommandKeyListener); + } + } + } + public void focusLost(FocusEvent e) { + if (fCommandKeyListener !is null) { + control_.removeKeyListener(fCommandKeyListener); + fCommandKeyListener= null; + } + } + }); + } + control.addFocusListener(new class(control) FocusListener { + Control control_; + private TraverseListener fTraverseListener; + this(Control a){ + control_=a; + } + public void focusGained(FocusEvent e) { + if (Helper.okToUse(control_)) { + if (fTraverseListener is null) { + fTraverseListener= new class() TraverseListener { + public void keyTraversed(TraverseEvent event) { + if (event.detail is DWT.TRAVERSE_TAB_NEXT) { + IInformationControl iControl= fAdditionalInfoController.getCurrentInformationControl2(); + if (fAdditionalInfoController.getInternalAccessor().canReplace(iControl)) { + fAdditionalInfoController.getInternalAccessor().replaceInformationControl(true); + event.doit= false; + } + } + } + }; + fProposalTable.addTraverseListener(fTraverseListener); + } + } + } + public void focusLost(FocusEvent e) { + if (fTraverseListener !is null) { + control_.removeTraverseListener(fTraverseListener); + fTraverseListener= null; + } + } + }); + } + + /** + * Returns the background color to use. + * + * @param control the control to get the display from + * @return the background color + * @since 3.2 + */ + private Color getBackgroundColor(Control control) { + Color c= fContentAssistant.getProposalSelectorBackground(); + if (c is null) + c= JFaceResources.getColorRegistry().get(JFacePreferences.CONTENT_ASSIST_BACKGROUND_COLOR); + return c; + } + + /** + * Returns the foreground color to use. + * + * @param control the control to get the display from + * @return the foreground color + * @since 3.2 + */ + private Color getForegroundColor(Control control) { + Color c= fContentAssistant.getProposalSelectorForeground(); + if (c is null) + c= JFaceResources.getColorRegistry().get(JFacePreferences.CONTENT_ASSIST_FOREGROUND_COLOR); + return c; + } + + /** + * Creates the caption line under the proposal table. + * + * @since 3.2 + */ + private void createMessageText() { + if (fMessageText is null) { + fMessageText= new Label(fProposalShell, DWT.RIGHT); + GridData textData= new GridData(DWT.FILL, DWT.BOTTOM, true, false); + fMessageText.setLayoutData(textData); + fMessageText.setText(fContentAssistant.getStatusMessage() ~ " "); //$NON-NLS-1$ + if (fMessageTextFont is null) { + Font font= fMessageText.getFont(); + Display display= fProposalShell.getDisplay(); + FontData[] fontDatas= font.getFontData(); + for (int i= 0; i < fontDatas.length; i++) + fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10); + fMessageTextFont= new Font(display, fontDatas); + } + fMessageText.setFont(fMessageTextFont); + fMessageText.setBackground(getBackgroundColor(fProposalShell)); + fMessageText.setForeground(getForegroundColor(fProposalShell)); + + if (fContentAssistant.isRepeatedInvocationMode()) { + fMessageText.setCursor(fProposalShell.getDisplay().getSystemCursor(DWT.CURSOR_HAND)); + fMessageText.addMouseListener(new class() MouseAdapter { + public void mouseUp(MouseEvent e) { + fLastCompletionOffset= fFilterOffset; + fProposalTable.setFocus(); + handleRepeatedInvocation(); + } + + public void mouseDown(MouseEvent e) { + } + }); + } + } + } + + /* + * @since 3.1 + */ + private void handleSetData(Event event) { + TableItem item= cast(TableItem) event.item; + int index= fProposalTable.indexOf(item); + + if (0 <= index && index < fFilteredProposals.length) { + ICompletionProposal current= fFilteredProposals[index]; + + String displayString; + StyleRange[] styleRanges= null; + if (fIsColoredLabelsSupportEnabled && cast(ICompletionProposalExtension6)current ) { + StyledString styledString= (cast(ICompletionProposalExtension6)current).getStyledDisplayString(); + displayString= styledString.getString(); + styleRanges= styledString.getStyleRanges(); + } else + displayString= current.getDisplayString(); + + item.setText(displayString); + if (fIsColoredLabelsSupportEnabled) + TableOwnerDrawSupport.storeStyleRanges(item, 0, styleRanges); + + item.setImage(current.getImage()); + item.setData(cast(Object)current); + } else { + // this should not happen, but does on win32 + } + } + + /** + * Returns the proposal selected in the proposal selector. + * + * @return the selected proposal + * @since 2.0 + */ + private ICompletionProposal getSelectedProposal() { + /* Make sure that there is no filter runnable pending. + * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=31427 + */ + if (fIsFilterPending) + fFilterRunnable.run(); + + // filter runnable may have hidden the proposals + if (!Helper.okToUse(fProposalTable)) + return null; + + int i= fProposalTable.getSelectionIndex(); + if (fFilteredProposals is null || i < 0 || i >= fFilteredProposals.length) + return null; + return fFilteredProposals[i]; + } + + /** + * Takes the selected proposal and applies it. + * + * @param stateMask the state mask + * @since 3.2 + */ + private void insertSelectedProposalWithMask(int stateMask) { + ICompletionProposal p= getSelectedProposal(); + hide(); + if (p !is null) + insertProposal(p, cast(wchar) 0, stateMask, fContentAssistSubjectControlAdapter.getSelectedRange().x); + } + + /** + * Applies the given proposal at the given offset. The given character is the + * one that triggered the insertion of this proposal. + * + * @param p the completion proposal + * @param trigger the trigger character + * @param stateMask the state mask + * @param offset the offset + * @since 2.1 + */ + private void insertProposal(ICompletionProposal p, char trigger, int stateMask, int offset) { + + fInserting= true; + IRewriteTarget target= null; + IEditingSupport helper= new class(offset) IEditingSupport { + int offset_; + this(int a){ + offset_=a; + } + public bool isOriginator(DocumentEvent event, IRegion focus) { + return focus.getOffset() <= offset_ && focus.getOffset() + focus.getLength() >= offset_; + } + + public bool ownsFocusShell() { + return false; + } + + }; + + try { + + IDocument document= fContentAssistSubjectControlAdapter.getDocument(); + + if ( cast(ITextViewerExtension)fViewer ) { + ITextViewerExtension extension= cast(ITextViewerExtension) fViewer; + target= extension.getRewriteTarget(); + } + + if (target !is null) + target.beginCompoundChange(); + + if ( cast(IEditingSupportRegistry)fViewer ) { + IEditingSupportRegistry registry= cast(IEditingSupportRegistry) fViewer; + registry.register(helper); + } + + + if (cast(ICompletionProposalExtension2)p && fViewer !is null) { + ICompletionProposalExtension2 e= cast(ICompletionProposalExtension2) p; + e.apply(fViewer, trigger, stateMask, offset); + } else if ( cast(ICompletionProposalExtension)p ) { + ICompletionProposalExtension e= cast(ICompletionProposalExtension) p; + e.apply(document, trigger, offset); + } else { + p.apply(document); + } + + Point selection= p.getSelection(document); + if (selection !is null) { + fContentAssistSubjectControlAdapter.setSelectedRange(selection.x, selection.y); + fContentAssistSubjectControlAdapter.revealRange(selection.x, selection.y); + } + + IContextInformation info= p.getContextInformation(); + if (info !is null) { + + int contextInformationOffset; + if ( cast(ICompletionProposalExtension)p ) { + ICompletionProposalExtension e= cast(ICompletionProposalExtension) p; + contextInformationOffset= e.getContextInformationPosition(); + } else { + if (selection is null) + selection= fContentAssistSubjectControlAdapter.getSelectedRange(); + contextInformationOffset= selection.x + selection.y; + } + + fContentAssistant.showContextInformation(info, contextInformationOffset); + } else + fContentAssistant.showContextInformation(null, -1); + + + } finally { + if (target !is null) + target.endCompoundChange(); + + if ( cast(IEditingSupportRegistry)fViewer ) { + IEditingSupportRegistry registry= cast(IEditingSupportRegistry) fViewer; + registry.unregister(helper); + } + fInserting= false; + } + } + + /** + * Returns whether this popup has the focus. + * + * @return true if the popup has the focus + */ + public bool hasFocus() { + if (Helper.okToUse(fProposalShell)) { + if ((fProposalShell.isFocusControl() || fProposalTable.isFocusControl())) + return true; + /* + * We have to delegate this query to the additional info controller + * as well, since the content assistant is the widget token owner + * and its closer does not know that the additional info control can + * now also take focus. + */ + if (fAdditionalInfoController !is null) { + IInformationControl informationControl= fAdditionalInfoController.getCurrentInformationControl2(); + if (informationControl !is null && informationControl.isFocusControl()) + return true; + InformationControlReplacer replacer= fAdditionalInfoController.getInternalAccessor().getInformationControlReplacer(); + if (replacer !is null) { + informationControl= replacer.getCurrentInformationControl2(); + if (informationControl !is null && informationControl.isFocusControl()) + return true; + } + } + } + + return false; + } + + /** + * Hides this popup. + */ + public void hide() { + + unregister(); + + if ( cast(IEditingSupportRegistry)fViewer ) { + IEditingSupportRegistry registry= cast(IEditingSupportRegistry) fViewer; + registry.unregister(fFocusHelper); + } + + if (Helper.okToUse(fProposalShell)) { + + fContentAssistant.removeContentAssistListener(this, ContentAssistant.PROPOSAL_SELECTOR); + + fPopupCloser.uninstall(); + fProposalShell.setVisible(false); + fProposalShell.dispose(); + fProposalShell= null; + } + + if (fMessageTextFont !is null) { + fMessageTextFont.dispose(); + fMessageTextFont= null; + } + + if (fMessageText !is null) { + fMessageText= null; + } + + fEmptyMessage= null; + + fLastCompletionOffset= -1; + + fContentAssistant.fireSessionEndEvent(); + } + + /** + * Unregister this completion proposal popup. + * + * @since 3.0 + */ + private void unregister() { + if (fDocumentListener !is null) { + IDocument document= fContentAssistSubjectControlAdapter.getDocument(); + if (document !is null) + document.removeDocumentListener(fDocumentListener); + fDocumentListener= null; + } + fDocumentEvents.clear(); + + if (fKeyListener !is null && fContentAssistSubjectControlAdapter.getControl() !is null && !fContentAssistSubjectControlAdapter.getControl().isDisposed()) { + fContentAssistSubjectControlAdapter.removeKeyListener(fKeyListener); + fKeyListener= null; + } + + if (fLastProposal !is null) { + if (cast(ICompletionProposalExtension2)fLastProposal && fViewer !is null) { + ICompletionProposalExtension2 extension= cast(ICompletionProposalExtension2) fLastProposal; + extension.unselected(fViewer); + } + fLastProposal= null; + } + + fFilteredProposals= null; + fComputedProposals= null; + + fContentAssistant.possibleCompletionsClosed_package(); + } + + /** + *Returns whether this popup is active. It is active if the proposal selector is visible. + * + * @return true if this popup is active + */ + public bool isActive() { + return fProposalShell !is null && !fProposalShell.isDisposed(); + } + + /** + * Initializes the proposal selector with these given proposals. + * @param proposals the proposals + * @param isFilteredSubset if true, the proposal table is + * not cleared, but the proposals that are not in the passed array + * are removed from the displayed set + */ + private void setProposals(ICompletionProposal[] proposals, bool isFilteredSubset) { + ICompletionProposal[] oldProposals= fFilteredProposals; + ICompletionProposal oldProposal= getSelectedProposal(); // may trigger filtering and a reentrant call to setProposals() + if (oldProposals !is fFilteredProposals) // reentrant call was first - abort + return; + + if (Helper.okToUse(fProposalTable)) { + if (cast(ICompletionProposalExtension2)oldProposal && fViewer !is null) + (cast(ICompletionProposalExtension2) oldProposal).unselected(fViewer); + + if (proposals is null || proposals.length is 0) { + fEmptyProposal.fOffset= fFilterOffset; + fEmptyProposal.fDisplayString= fEmptyMessage !is null ? fEmptyMessage : JFaceTextMessages.getString("CompletionProposalPopup.no_proposals"); //$NON-NLS-1$ + proposals= [ fEmptyProposal ]; + } + + fFilteredProposals= proposals; + final int newLen= proposals.length; + if (USE_VIRTUAL) { + fProposalTable.setItemCount(newLen); + fProposalTable.clearAll(); + } else { + fProposalTable.setRedraw(false); + fProposalTable.setItemCount(newLen); + TableItem[] items= fProposalTable.getItems(); + for (int i= 0; i < items.length; i++) { + TableItem item= items[i]; + ICompletionProposal proposal= proposals[i]; + item.setText(proposal.getDisplayString()); + item.setImage(proposal.getImage()); + item.setData(cast(Object)proposal); + } + fProposalTable.setRedraw(true); + } + + Point currentLocation= fProposalShell.getLocation(); + Point newLocation= getLocation(); + if ((newLocation.x < currentLocation.x && newLocation.y is currentLocation.y) || newLocation.y < currentLocation.y) + fProposalShell.setLocation(newLocation); + + selectProposal(0, false); + } + } + + /** + * Returns the graphical location at which this popup should be made visible. + * + * @return the location of this popup + */ + private Point getLocation() { + int caret= fContentAssistSubjectControlAdapter.getCaretOffset(); + Rectangle location= fContentAssistant.getLayoutManager().computeBoundsBelowAbove_package(fProposalShell, fSize is null ? fProposalShell.getSize() : fSize, caret, this); + return Geometry.getLocation(location); + } + + /** + * Returns the size of this completion proposal popup. + * + * @return a Point containing the size + * @since 3.0 + */ + Point getSize() { + return fSize; + } + + /** + * Displays this popup and install the additional info controller, so that additional info + * is displayed when a proposal is selected and additional info is available. + */ + private void displayProposals() { + + if (!Helper.okToUse(fProposalShell) || !Helper.okToUse(fProposalTable)) + return; + + if (fContentAssistant.addContentAssistListener(this, ContentAssistant.PROPOSAL_SELECTOR)) { + + ensureDocumentListenerInstalled(); + + if (fFocusHelper is null) { + fFocusHelper= new class() IEditingSupport { + + public bool isOriginator(DocumentEvent event, IRegion focus) { + return false; // this helper just covers the focus change to the proposal shell, no remote editions + } + + public bool ownsFocusShell() { + return true; + } + + }; + } + if ( cast(IEditingSupportRegistry)fViewer ) { + IEditingSupportRegistry registry= cast(IEditingSupportRegistry) fViewer; + registry.register(fFocusHelper); + } + + + /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=52646 + * on GTK, setVisible and such may run the event loop + * (see also https://bugs.eclipse.org/bugs/show_bug.cgi?id=47511) + * Since the user may have already canceled the popup or selected + * an entry (ESC or RETURN), we have to double check whether + * the table is still okToUse. See comments below + */ + fProposalShell.setVisible(true); // may run event loop on GTK + // transfer focus since no verify key listener can be attached + if (!fContentAssistSubjectControlAdapter.supportsVerifyKeyListener() && Helper.okToUse(fProposalShell)) + fProposalShell.setFocus(); // may run event loop on GTK ?? + + if (fAdditionalInfoController !is null && Helper.okToUse(fProposalTable)) { + fAdditionalInfoController.install(fProposalTable); + fAdditionalInfoController.handleTableSelectionChanged(); + } + } else + hide(); + } + + /** + * Installs the document listener if not already done. + * + * @since 3.2 + */ + private void ensureDocumentListenerInstalled() { + if (fDocumentListener is null) { + fDocumentListener= new class() IDocumentListener { + public void documentAboutToBeChanged(DocumentEvent event) { + if (!fInserting) + fDocumentEvents.add(event); + } + + public void documentChanged(DocumentEvent event) { + if (!fInserting) + filterProposals(); + } + }; + IDocument document= fContentAssistSubjectControlAdapter.getDocument(); + if (document !is null) + document.addDocumentListener(fDocumentListener); + } + } + + /* + * @see IContentAssistListener#verifyKey(VerifyEvent) + */ + public bool verifyKey(VerifyEvent e) { + if (!Helper.okToUse(fProposalShell)) + return true; + + char key= e.character; + if (key is 0) { + int newSelection= fProposalTable.getSelectionIndex(); + int visibleRows= (fProposalTable.getSize().y / fProposalTable.getItemHeight()) - 1; + int itemCount= fProposalTable.getItemCount(); + bool smartToggle= false; + switch (e.keyCode) { + + case DWT.ARROW_LEFT : + case DWT.ARROW_RIGHT : + filterProposals(); + return true; + + case DWT.ARROW_UP : + newSelection -= 1; + if (newSelection < 0) + newSelection= itemCount - 1; + break; + + case DWT.ARROW_DOWN : + newSelection += 1; + if (newSelection > itemCount - 1) + newSelection= 0; + break; + + case DWT.PAGE_DOWN : + newSelection += visibleRows; + if (newSelection >= itemCount) + newSelection= itemCount - 1; + break; + + case DWT.PAGE_UP : + newSelection -= visibleRows; + if (newSelection < 0) + newSelection= 0; + break; + + case DWT.HOME : + newSelection= 0; + break; + + case DWT.END : + newSelection= itemCount - 1; + break; + + default : + if (e.keyCode !is DWT.CAPS_LOCK && e.keyCode !is DWT.MOD1 && e.keyCode !is DWT.MOD2 && e.keyCode !is DWT.MOD3 && e.keyCode !is DWT.MOD4) + hide(); + return true; + } + + selectProposal(newSelection, smartToggle); + + e.doit= false; + return false; + + } + + // key !is 0 + switch (key) { + case 0x1B: // Esc + e.doit= false; + hide(); + break; + + case '\n': // Ctrl-Enter on w2k + case '\r': // Enter + e.doit= false; + insertSelectedProposalWithMask(e.stateMask); + break; + + case '\t': + e.doit= false; + fProposalShell.setFocus(); + return false; + + default: + ICompletionProposal p= getSelectedProposal(); + if ( cast(ICompletionProposalExtension)p ) { + ICompletionProposalExtension t= cast(ICompletionProposalExtension) p; + char[] triggers= t.getTriggerCharacters(); + if (contains(triggers, key)) { + e.doit= false; + hide(); + insertProposal(p, key, e.stateMask, fContentAssistSubjectControlAdapter.getSelectedRange().x); + } + } + } + + return true; + } + + /** + * Selects the entry with the given index in the proposal selector and feeds + * the selection to the additional info controller. + * + * @param index the index in the list + * @param smartToggle true if the smart toggle key has been pressed + * @since 2.1 + */ + private void selectProposal(int index, bool smartToggle) { + + ICompletionProposal oldProposal= getSelectedProposal(); + if (cast(ICompletionProposalExtension2)oldProposal && fViewer !is null) + (cast(ICompletionProposalExtension2) oldProposal).unselected(fViewer); + + if (fFilteredProposals is null) { + fireSelectionEvent(null, smartToggle); + return; + } + + ICompletionProposal proposal= fFilteredProposals[index]; + if (cast(ICompletionProposalExtension2)proposal && fViewer !is null) + (cast(ICompletionProposalExtension2) proposal).selected(fViewer, smartToggle); + + fireSelectionEvent(proposal, smartToggle); + + fLastProposal= proposal; + + fProposalTable.setSelection(index); + fProposalTable.showSelection(); + if (fAdditionalInfoController !is null) + fAdditionalInfoController.handleTableSelectionChanged(); + } + + /** + * Fires a selection event, see {@link ICompletionListener}. + * + * @param proposal the selected proposal, possibly null + * @param smartToggle true if the smart toggle is on + * @since 3.2 + */ + private void fireSelectionEvent(ICompletionProposal proposal, bool smartToggle) { + fContentAssistant.fireSelectionEvent(proposal, smartToggle); + } + + /** + * Returns whether the given character is contained in the given array of + * characters. + * + * @param characters the list of characters + * @param c the character to look for in the list + * @return true if character belongs to the list + * @since 2.0 + */ + private bool contains(char[] characters, char c) { + + if (characters is null) + return false; + + for (int i= 0; i < characters.length; i++) { + if (c is characters[i]) + return true; + } + + return false; + } + + /* + * @see IEventConsumer#processEvent(VerifyEvent) + */ + public void processEvent(VerifyEvent e) { + } + + /** + * Filters the displayed proposal based on the given cursor position and the + * offset of the original invocation of the content assistant. + */ + private void filterProposals() { + if (!fIsFilterPending) { + fIsFilterPending= true; + Control control= fContentAssistSubjectControlAdapter.getControl(); + control.getDisplay().asyncExec(fFilterRunnable); + } + } + + /** + * Computes the subset of already computed proposals that are still valid for + * the given offset. + * + * @param offset the offset + * @param event the merged document event + * @return the set of filtered proposals + * @since 3.0 + */ + private ICompletionProposal[] computeFilteredProposals(int offset, DocumentEvent event) { + + if (offset is fInvocationOffset && event is null) { + fIsFilteredSubset= false; + return fComputedProposals; + } + + if (offset < fInvocationOffset) { + fIsFilteredSubset= false; + fInvocationOffset= offset; + fContentAssistant.fireSessionRestartEvent(); + fComputedProposals= computeProposals(fInvocationOffset); + return fComputedProposals; + } + + ICompletionProposal[] proposals; + if (offset < fFilterOffset) { + proposals= fComputedProposals; + fIsFilteredSubset= false; + } else { + proposals= fFilteredProposals; + fIsFilteredSubset= true; + } + + if (proposals is null) { + fIsFilteredSubset= false; + return null; + } + + IDocument document= fContentAssistSubjectControlAdapter.getDocument(); + int length= proposals.length; + List filtered= new ArrayList(length); + for (int i= 0; i < length; i++) { + + if (cast(ICompletionProposalExtension2)proposals[i] ) { + + ICompletionProposalExtension2 p= cast(ICompletionProposalExtension2) proposals[i]; + if (p.validate(document, offset, event)) + filtered.add(cast(Object)p); + + } else if (cast(ICompletionProposalExtension)proposals[i] ) { + + ICompletionProposalExtension p= cast(ICompletionProposalExtension) proposals[i]; + if (p.isValidFor(document, offset)) + filtered.add(cast(Object)p); + + } else { + // restore original behavior + fIsFilteredSubset= false; + fInvocationOffset= offset; + fContentAssistant.fireSessionRestartEvent(); + fComputedProposals= computeProposals(fInvocationOffset); + return fComputedProposals; + } + } + + return arraycast!(ICompletionProposal)( filtered.toArray()); + } + + /** + * Requests the proposal shell to take focus. + * + * @since 3.0 + */ + public void setFocus() { + if (Helper.okToUse(fProposalShell)) { + fProposalShell.setFocus(); + } + } + + /** + * Returns true if proposal should be auto-inserted, + * false otherwise. + * + * @param proposal the single proposal that might be automatically inserted + * @return true if proposal can be inserted automatically, + * false otherwise + * @since 3.1 + */ + private bool canAutoInsert(ICompletionProposal proposal) { + if (fContentAssistant.isAutoInserting()) { + if ( cast(ICompletionProposalExtension4)proposal ) { + ICompletionProposalExtension4 ext= cast(ICompletionProposalExtension4) proposal; + return ext.isAutoInsertable(); + } + return true; // default behavior before ICompletionProposalExtension4 was introduced + } + return false; + } + + /** + * Completes the common prefix of all proposals directly in the code. If no + * common prefix can be found, the proposal popup is shown. + * + * @return an error message if completion failed. + * @since 3.0 + */ + public String incrementalComplete() { + if (Helper.okToUse(fProposalShell) && fFilteredProposals !is null) { + if (fLastCompletionOffset is fFilterOffset) { + handleRepeatedInvocation(); + } else { + fLastCompletionOffset= fFilterOffset; + completeCommonPrefix(); + } + } else { + final Control control= fContentAssistSubjectControlAdapter.getControl(); + + if (fKeyListener is null) + fKeyListener= new ProposalSelectionListener(); + + if (!Helper.okToUse(fProposalShell) && !control.isDisposed()) + fContentAssistSubjectControlAdapter.addKeyListener(fKeyListener); + + BusyIndicator.showWhile(control.getDisplay(), new class() Runnable { + public void run() { + + fInvocationOffset= fContentAssistSubjectControlAdapter.getSelectedRange().x; + fFilterOffset= fInvocationOffset; + fLastCompletionOffset= fFilterOffset; + fFilteredProposals= computeProposals(fInvocationOffset); + + int count= (fFilteredProposals is null ? 0 : fFilteredProposals.length); + if (count is 0 && hideWhenNoProposals(false)) + return; + + if (count is 1 && canAutoInsert(fFilteredProposals[0])) { + insertProposal(fFilteredProposals[0], cast(wchar) 0, 0, fInvocationOffset); + hide(); + } else { + ensureDocumentListenerInstalled(); + if (count > 0 && completeCommonPrefix()) + hide(); + else { + fComputedProposals= fFilteredProposals; + createProposalSelector(); + setProposals(fComputedProposals, false); + displayProposals(); + } + } + } + }); + } + return getErrorMessage(); + } + + /** + * Acts upon fFilteredProposals: if there is just one valid + * proposal, it is inserted, otherwise, the common prefix of all proposals + * is inserted into the document. If there is no common prefix, nothing + * happens and false is returned. + * + * @return true if a single proposal was inserted and the + * selector can be closed, false otherwise + * @since 3.0 + */ + private bool completeCommonPrefix() { + + // 0: insert single proposals + if (fFilteredProposals.length is 1) { + if (canAutoInsert(fFilteredProposals[0])) { + insertProposal(fFilteredProposals[0], cast(wchar) 0, 0, fFilterOffset); + hide(); + return true; + } + return false; + } + + // 1: extract pre- and postfix from all remaining proposals + IDocument document= fContentAssistSubjectControlAdapter.getDocument(); + + // contains the common postfix in the case that there are any proposals matching our LHS + StringBuffer rightCasePostfix; + List rightCase= new ArrayList(); + + bool isWrongCaseMatch= false; + + // the prefix of all case insensitive matches. This differs from the document + // contents and will be replaced. + CharSequence wrongCasePrefix= null; + int wrongCasePrefixStart= 0; + // contains the common postfix of all case-insensitive matches + StringBuffer wrongCasePostfix; + List wrongCase= new ArrayList(); + + for (int i= 0; i < fFilteredProposals.length; i++) { + ICompletionProposal proposal= fFilteredProposals[i]; + + if (!( cast(ICompletionProposalExtension3)proposal )) + return false; + + int start= (cast(ICompletionProposalExtension3)proposal).getPrefixCompletionStart(fContentAssistSubjectControlAdapter.getDocument(), fFilterOffset); + CharSequence insertion= (cast(ICompletionProposalExtension3)proposal).getPrefixCompletionText(fContentAssistSubjectControlAdapter.getDocument(), fFilterOffset); + if (insertion is null) + insertion= new StringCharSequence(proposal.getDisplayString()); + try { + int prefixLength= fFilterOffset - start; + int relativeCompletionOffset= Math.min(insertion.length(), prefixLength); + String prefix= document.get(start, prefixLength); + if (!isWrongCaseMatch && insertion.toString().startsWith(prefix)) { + isWrongCaseMatch= false; + rightCase.add(cast(Object)proposal); + CharSequence newPostfix= insertion.subSequence(relativeCompletionOffset, insertion.length()); + if (rightCasePostfix is null) + rightCasePostfix= new StringBuffer(newPostfix.toString()); + else + truncatePostfix(rightCasePostfix, newPostfix); + } else if (i is 0 || isWrongCaseMatch) { + CharSequence newPrefix= insertion.subSequence(0, relativeCompletionOffset); + if (isPrefixCompatible(wrongCasePrefix, wrongCasePrefixStart, newPrefix, start, document)) { + isWrongCaseMatch= true; + wrongCasePrefix= newPrefix; + wrongCasePrefixStart= start; + CharSequence newPostfix= insertion.subSequence(relativeCompletionOffset, insertion.length()); + if (wrongCasePostfix is null) + wrongCasePostfix= new StringBuffer(newPostfix.toString()); + else + truncatePostfix(wrongCasePostfix, newPostfix); + wrongCase.add(cast(Object)proposal); + } else { + return false; + } + } else + return false; + } catch (BadLocationException e2) { + // bail out silently + return false; + } + + if (rightCasePostfix !is null && rightCasePostfix.length() is 0 && rightCase.size() > 1) + return false; + } + + // 2: replace single proposals + + if (rightCase.size() is 1) { + ICompletionProposal proposal= cast(ICompletionProposal) rightCase.get(0); + if (canAutoInsert(proposal) && rightCasePostfix.length() > 0) { + insertProposal(proposal, cast(wchar) 0, 0, fInvocationOffset); + hide(); + return true; + } + return false; + } else if (isWrongCaseMatch && wrongCase.size() is 1) { + ICompletionProposal proposal= cast(ICompletionProposal) wrongCase.get(0); + if (canAutoInsert(proposal)) { + insertProposal(proposal, cast(wchar) 0, 0, fInvocationOffset); + hide(); + return true; + } + return false; + } + + // 3: replace post- / prefixes + + CharSequence prefix; + if (isWrongCaseMatch) + prefix= wrongCasePrefix; + else + prefix= new StringCharSequence(""); //$NON-NLS-1$ + + CharSequence postfix; + if (isWrongCaseMatch) + postfix= new StringCharSequence(wrongCasePostfix.toString); + else + postfix= new StringCharSequence(rightCasePostfix.toString); + + if (prefix is null || postfix is null) + return false; + + try { + // 4: check if parts of the postfix are already in the document + int to= Math.min(document.getLength(), fFilterOffset + postfix.length()); + StringBuffer inDocument= new StringBuffer(document.get(fFilterOffset, to - fFilterOffset)); + truncatePostfix(inDocument, postfix); + + // 5: replace and reveal + document.replace(fFilterOffset - prefix.length(), prefix.length() + inDocument.length(), prefix.toString() ~ postfix.toString()); + + fContentAssistSubjectControlAdapter.setSelectedRange(fFilterOffset + postfix.length(), 0); + fContentAssistSubjectControlAdapter.revealRange(fFilterOffset + postfix.length(), 0); + fFilterOffset+= postfix.length(); + fLastCompletionOffset= fFilterOffset; + + return false; + } catch (BadLocationException e) { + // ignore and return false + return false; + } + } + + /* + * @since 3.1 + */ + private bool isPrefixCompatible(CharSequence oneSequence, int oneOffset, CharSequence twoSequence, int twoOffset, IDocument document) { + if (oneSequence is null || twoSequence is null) + return true; + + int min= Math.min(oneOffset, twoOffset); + int oneEnd= oneOffset + oneSequence.length(); + int twoEnd= twoOffset + twoSequence.length(); + + String one= document.get(oneOffset, min - oneOffset) ~ oneSequence.toString ~ document.get(oneEnd, Math.min(fFilterOffset, fFilterOffset - oneEnd)); + String two= document.get(twoOffset, min - twoOffset) ~ twoSequence.toString ~ document.get(twoEnd, Math.min(fFilterOffset, fFilterOffset - twoEnd)); + + return one.equals(two); + } + + /** + * Truncates buffer to the common prefix of buffer + * and sequence. + * + * @param buffer the common postfix to truncate + * @param sequence the characters to truncate with + */ + private void truncatePostfix(StringBuffer buffer, CharSequence sequence) { + // find common prefix + int min= Math.min(buffer.length(), sequence.length()); + for (int c= 0; c < min; c++) { + if (sequence.charAt(c) !is buffer.slice()[c]) { + buffer.truncate(c); + return; + } + } + + // all equal up to minimum + buffer.truncate(min); + } + + /** + * Sets the message for the repetition affordance text at the bottom of the proposal. Only has + * an effect if {@link ContentAssistant#isRepeatedInvocationMode()} returns true. + * + * @param message the new caption + * @since 3.2 + */ + void setMessage(String message) { + Assert.isNotNull(message); + if (isActive() && fMessageText !is null) + fMessageText.setText(message ~ " "); //$NON-NLS-1$ + } + + /** + * Sets the text to be displayed if no proposals are available. Only has an effect if + * {@link ContentAssistant#isShowEmptyList()} returns true. + * + * @param message the empty message + * @since 3.2 + */ + void setEmptyMessage(String message) { + Assert.isNotNull(message); + fEmptyMessage= message; + } + + /** + * Enables or disables showing of the caption line. See also {@link #setMessage(String)}. + * + * @param show + * @since 3.2 + */ + public void setStatusLineVisible(bool show) { + if (!isActive() || show is (fMessageText !is null)) + return; // nothing to do + + if (show) { + createMessageText(); + } else { + fMessageText.dispose(); + fMessageText= null; + } + fProposalShell.layout(); + } + + /** + * Informs the popup that it is being placed above the caret line instead of below. + * + * @param above true if the location of the popup is above the caret line, false if it is below + * @since 3.3 + */ + void switchedPositionToAbove(bool above) { + if (fAdditionalInfoController !is null) { + fAdditionalInfoController.setFallbackAnchors([ + AbstractInformationControlManager.ANCHOR_RIGHT, + AbstractInformationControlManager.ANCHOR_LEFT, + above ? AbstractInformationControlManager.ANCHOR_TOP : AbstractInformationControlManager.ANCHOR_BOTTOM + ]); + } + } + + /** + * Returns a new proposal selection handler. + * + * @param operationCode the operation code + * @return the handler + * @since 3.4 + */ + IHandler createProposalSelectionHandler(int operationCode) { + return new ProposalSelectionHandler(operationCode); + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/ContentAssistEvent.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/ContentAssistEvent.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,104 @@ +/******************************************************************************* + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Anton Leherbauer (Wind River Systems) - [content assist][api] ContentAssistEvent should contain information about auto activation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=193728 + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.text.contentassist.ContentAssistEvent; + +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Describes the state that the content assistant is in when completing proposals. + *

                + * Clients may use this class. + *

                + * + * @since 3.2 + * @see ICompletionListener + * @noinstantiate This class is not intended to be instantiated by clients. + */ +public final class ContentAssistEvent { + /** + * Creates a new event. + * + * @param ca the assistant + * @param proc the processor + * @param isAutoActivated whether content assist was triggered by auto activation + * @since 3.4 + */ + this(IContentAssistant ca, IContentAssistProcessor proc, bool isAutoActivated) { + assistant= ca; + processor= proc; + this.isAutoActivated= isAutoActivated; + } + + /** + * Creates a new event. + * + * @param ca the assistant + * @param proc the processor + */ + this(ContentAssistant ca, IContentAssistProcessor proc) { + this(ca, proc, false); + } + + /** + * The content assistant computing proposals. + */ + public const IContentAssistant assistant; + /** + * The processor for the current partition. + */ + public const IContentAssistProcessor processor; + /** + * Tells, whether content assist was triggered by auto activation. + *

                + * Note: This flag is only valid in {@link ICompletionListener#assistSessionStarted(ContentAssistEvent)}. + *

                + * + * @since 3.4 + */ + public const bool isAutoActivated; +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/ContentAssistSubjectControlAdapter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/ContentAssistSubjectControlAdapter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,450 @@ +/******************************************************************************* + * 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 + * 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.text.contentassist.ContentAssistSubjectControlAdapter; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + + + + + +import dwt.custom.StyledText; +import dwt.custom.VerifyKeyListener; +import dwt.events.KeyListener; +import dwt.events.SelectionListener; +import dwt.graphics.Point; +import dwt.widgets.Control; +import dwtx.core.runtime.Assert; +import dwtx.jface.contentassist.IContentAssistSubjectControl; +import dwtx.jface.contentassist.ISubjectControlContextInformationPresenter; +import dwtx.jface.contentassist.ISubjectControlContextInformationValidator; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IEventConsumer; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.ITextViewerExtension; +import dwtx.jface.text.contentassist.ContextInformationPopup; + + +/** + * This content assist adapter delegates the calls either to + * a text viewer or to a content assist subject control. + * + * @since 3.0 + */ +final class ContentAssistSubjectControlAdapter : IContentAssistSubjectControl { + + /** + * The text viewer which is used as content assist subject control. + */ + private ITextViewer fViewer; + + /** + * The content assist subject control. + */ + private IContentAssistSubjectControl fContentAssistSubjectControl; + + + /** + * Creates an adapter for the given content assist subject control. + * + * @param contentAssistSubjectControl the content assist subject control + */ + this(IContentAssistSubjectControl contentAssistSubjectControl) { + Assert.isNotNull(cast(Object)contentAssistSubjectControl); + fContentAssistSubjectControl= contentAssistSubjectControl; + } + + /** + * Creates an adapter for the given text viewer. + * + * @param viewer the text viewer + */ + public this(ITextViewer viewer) { + Assert.isNotNull(cast(Object)viewer); + fViewer= viewer; + } + + /* + * @see IContentAssistSubjectControl#getLineHeight() + */ + public int getLineHeight() { + if (fContentAssistSubjectControl !is null) + return fContentAssistSubjectControl.getLineHeight(); + + return fViewer.getTextWidget().getLineHeight(getCaretOffset()); + } + + /* + * @see IContentAssistSubjectControl#getControl() + */ + public Control getControl() { + if (fContentAssistSubjectControl !is null) + return fContentAssistSubjectControl.getControl(); + return fViewer.getTextWidget(); + } + + /* + * @see IContentAssistSubjectControl#getLocationAtOffset(int) + */ + public Point getLocationAtOffset(int offset) { + if (fContentAssistSubjectControl !is null) + return fContentAssistSubjectControl.getLocationAtOffset(offset); + return fViewer.getTextWidget().getLocationAtOffset(offset); + } + + /* + * @see IContentAssistSubjectControl#getWidgetSelectionRange() + */ + public Point getWidgetSelectionRange() { + if (fContentAssistSubjectControl !is null) + return fContentAssistSubjectControl.getWidgetSelectionRange(); + return fViewer.getTextWidget().getSelectionRange(); + } + + /* + * @see IContentAssistSubjectControl#getSelectedRange() + */ + public Point getSelectedRange() { + if (fContentAssistSubjectControl !is null) + return fContentAssistSubjectControl.getSelectedRange(); + return fViewer.getSelectedRange(); + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#getCaretOffset() + */ + public int getCaretOffset() { + if (fContentAssistSubjectControl !is null) + return fContentAssistSubjectControl.getCaretOffset(); + return fViewer.getTextWidget().getCaretOffset(); + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#getLineDelimiter() + */ + public String getLineDelimiter() { + if (fContentAssistSubjectControl !is null) + return fContentAssistSubjectControl.getLineDelimiter(); + return fViewer.getTextWidget().getLineDelimiter(); + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#addKeyListener(dwt.events.KeyListener) + */ + public void addKeyListener(KeyListener keyListener) { + if (fContentAssistSubjectControl !is null) + fContentAssistSubjectControl.addKeyListener(keyListener); + else + fViewer.getTextWidget().addKeyListener(keyListener); + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#removeKeyListener(dwt.events.KeyListener) + */ + public void removeKeyListener(KeyListener keyListener) { + if (fContentAssistSubjectControl !is null) + fContentAssistSubjectControl.removeKeyListener(keyListener); + else + fViewer.getTextWidget().removeKeyListener(keyListener); + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#getDocument() + */ + public IDocument getDocument() { + if (fContentAssistSubjectControl !is null) + return fContentAssistSubjectControl.getDocument(); + return fViewer.getDocument(); + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#prependVerifyKeyListener(VerifyKeyListener) + */ + public bool prependVerifyKeyListener(VerifyKeyListener verifyKeyListener) { + if (fContentAssistSubjectControl !is null) { + return fContentAssistSubjectControl.prependVerifyKeyListener(verifyKeyListener); + } else if ( cast(ITextViewerExtension)fViewer ) { + ITextViewerExtension e= cast(ITextViewerExtension) fViewer; + e.prependVerifyKeyListener(verifyKeyListener); + return true; + } else { + + StyledText textWidget= fViewer.getTextWidget(); + if (Helper.okToUse(textWidget)) { + textWidget.addVerifyKeyListener(verifyKeyListener); + return true; + } + } + return false; + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#appendVerifyKeyListener(dwt.custom.VerifyKeyListener) + */ + public bool appendVerifyKeyListener(VerifyKeyListener verifyKeyListener) { + if (fContentAssistSubjectControl !is null) + return fContentAssistSubjectControl.appendVerifyKeyListener(verifyKeyListener); + else if ( cast(ITextViewerExtension)fViewer ) { + ITextViewerExtension extension= cast(ITextViewerExtension)fViewer; + extension.appendVerifyKeyListener(verifyKeyListener); + return true; + } else { + StyledText textWidget= fViewer.getTextWidget(); + if (Helper.okToUse(textWidget)) { + textWidget.addVerifyKeyListener(verifyKeyListener); + return true; + } + } + return false; + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#removeVerifyKeyListener(dwt.custom.VerifyKeyListener) + */ + public void removeVerifyKeyListener(VerifyKeyListener verifyKeyListener) { + if (fContentAssistSubjectControl !is null) { + fContentAssistSubjectControl.removeVerifyKeyListener(verifyKeyListener); + } else if ( cast(ITextViewerExtension)fViewer ) { + ITextViewerExtension extension= cast(ITextViewerExtension) fViewer; + extension.removeVerifyKeyListener(verifyKeyListener); + } else { + StyledText textWidget= fViewer.getTextWidget(); + if (Helper.okToUse(textWidget)) + textWidget.removeVerifyKeyListener(verifyKeyListener); + } + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#setEventConsumer(dwtx.jface.text.contentassist.ContentAssistant.InternalListener) + */ + public void setEventConsumer(IEventConsumer eventConsumer) { + if (fContentAssistSubjectControl !is null) + fContentAssistSubjectControl.setEventConsumer(eventConsumer); + else + fViewer.setEventConsumer(eventConsumer); + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#setSelectedRange(int, int) + */ + public void setSelectedRange(int i, int j) { + if (fContentAssistSubjectControl !is null) + fContentAssistSubjectControl.setSelectedRange(i, j); + else + fViewer.setSelectedRange(i, j); + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#revealRange(int, int) + */ + public void revealRange(int i, int j) { + if (fContentAssistSubjectControl !is null) + fContentAssistSubjectControl.revealRange(i, j); + else + fViewer.revealRange(i, j); + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#canAddVerifyKeyListener() + */ + public bool supportsVerifyKeyListener() { + if (fContentAssistSubjectControl !is null) + return fContentAssistSubjectControl.supportsVerifyKeyListener(); + return true; + } + /** + * Returns the characters which when typed by the user should automatically + * initiate proposing completions. The position is used to determine the + * appropriate content assist processor to invoke. + * + * @param contentAssistant the content assistant + * @param offset a document offset + * @return the auto activation characters + * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters() + */ + public char[] getCompletionProposalAutoActivationCharacters(ContentAssistant contentAssistant, int offset) { + if (fContentAssistSubjectControl !is null) + return contentAssistant.getCompletionProposalAutoActivationCharacters(fContentAssistSubjectControl, offset); + return contentAssistant.getCompletionProposalAutoActivationCharacters(fViewer, offset); + } + + /** + * Returns the characters which when typed by the user should automatically + * initiate the presentation of context information. The position is used + * to determine the appropriate content assist processor to invoke. + * + * @param contentAssistant the content assistant + * @param offset a document offset + * @return the auto activation characters + * + * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters() + */ + char[] getContextInformationAutoActivationCharacters(ContentAssistant contentAssistant, int offset) { + if (fContentAssistSubjectControl !is null) + return contentAssistant.getContextInformationAutoActivationCharacters(fContentAssistSubjectControl, offset); + return contentAssistant.getContextInformationAutoActivationCharacters(fViewer, offset); + } + + /** + * Creates and returns a completion proposal popup for the given content assistant. + * + * @param contentAssistant the content assistant + * @param controller the additional info controller + * @return the completion proposal popup + */ + CompletionProposalPopup createCompletionProposalPopup(ContentAssistant contentAssistant, AdditionalInfoController controller) { + if (fContentAssistSubjectControl !is null) + return new CompletionProposalPopup(contentAssistant, fContentAssistSubjectControl, controller); + return new CompletionProposalPopup(contentAssistant, fViewer, controller); + + } + + /** + * Creates and returns a context info popup for the given content assistant. + * + * @param contentAssistant the content assistant + * @return the context info popup or null + */ + ContextInformationPopup createContextInfoPopup(ContentAssistant contentAssistant) { + if (fContentAssistSubjectControl !is null) + return new ContextInformationPopup(contentAssistant, fContentAssistSubjectControl); + return new ContextInformationPopup(contentAssistant, fViewer); + + } + + /** + * Returns the context information validator that should be used to + * determine when the currently displayed context information should + * be dismissed. The position is used to determine the appropriate + * content assist processor to invoke. + * + * @param contentAssistant the content assistant + * @param offset a document offset + * @return an validator + */ + public IContextInformationValidator getContextInformationValidator(ContentAssistant contentAssistant, int offset) { + if (fContentAssistSubjectControl !is null) + return contentAssistant.getContextInformationValidator(fContentAssistSubjectControl, offset); + return contentAssistant.getContextInformationValidator(fViewer, offset); + } + + /** + * Returns the context information presenter that should be used to + * display context information. The position is used to determine the + * appropriate content assist processor to invoke. + * + * @param contentAssistant the content assistant + * @param offset a document offset + * @return a presenter + */ + public IContextInformationPresenter getContextInformationPresenter(ContentAssistant contentAssistant, int offset) { + if (fContentAssistSubjectControl !is null) + return contentAssistant.getContextInformationPresenter(fContentAssistSubjectControl, offset); + return contentAssistant.getContextInformationPresenter(fViewer, offset); + } + + /** + * Installs this adapter's information validator on the given context frame. + * + * @param frame the context frame + */ + public void installValidator(ContextInformationPopup_ContextFrame frame) { + if (fContentAssistSubjectControl !is null) { + if (cast(ISubjectControlContextInformationValidator)frame.fValidator ) + (cast(ISubjectControlContextInformationValidator)frame.fValidator).install(frame.fInformation, fContentAssistSubjectControl, frame.fOffset); + } else + frame.fValidator.install(frame.fInformation, fViewer, frame.fOffset); + } + + /** + * Installs this adapter's information presenter on the given context frame. + * + * @param frame the context frame + */ + public void installContextInformationPresenter(ContextInformationPopup_ContextFrame frame) { + if (fContentAssistSubjectControl !is null) { + if (cast(ISubjectControlContextInformationPresenter)frame.fPresenter ) + (cast(ISubjectControlContextInformationPresenter)frame.fValidator).install(frame.fInformation, fContentAssistSubjectControl, frame.fBeginOffset); + } else + frame.fPresenter.install(frame.fInformation, fViewer, frame.fBeginOffset); + } + + /** + * Returns an array of context information objects computed based + * on the specified document position. The position is used to determine + * the appropriate content assist processor to invoke. + * + * @param contentAssistant the content assistant + * @param offset a document offset + * @return an array of context information objects + * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int) + */ + public IContextInformation[] computeContextInformation(ContentAssistant contentAssistant, int offset) { + if (fContentAssistSubjectControl !is null) + return contentAssistant.computeContextInformation(fContentAssistSubjectControl, offset); + return contentAssistant.computeContextInformation(fViewer, offset); + } + + /* + * @see IContentAssistSubjectControl#addSelectionListener(SelectionListener) + */ + public bool addSelectionListener(SelectionListener selectionListener) { + if (fContentAssistSubjectControl !is null) + return fContentAssistSubjectControl.addSelectionListener(selectionListener); + fViewer.getTextWidget().addSelectionListener(selectionListener); + return true; + } + + /* + * @see IContentAssistSubjectControl#removeSelectionListener(SelectionListener) + */ + public void removeSelectionListener(SelectionListener selectionListener) { + if (fContentAssistSubjectControl !is null) + fContentAssistSubjectControl.removeSelectionListener(selectionListener); + else + fViewer.getTextWidget().removeSelectionListener(selectionListener); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/ContentAssistant.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/ContentAssistant.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,2506 @@ +/******************************************************************************* + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Guy Gurfinkel, guy.g@zend.com - [content assist][api] provide better access to ContentAssistant - https://bugs.eclipse.org/bugs/show_bug.cgi?id=169954 + * Anton Leherbauer (Wind River Systems) - [content assist][api] ContentAssistEvent should contain information about auto activation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=193728 + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.text.contentassist.ContentAssistant; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; +import tango.core.Thread; + +import dwt.DWT; +import dwt.DWTError; +import dwt.custom.VerifyKeyListener; +import dwt.events.ControlEvent; +import dwt.events.ControlListener; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.events.FocusEvent; +import dwt.events.FocusListener; +import dwt.events.KeyAdapter; +import dwt.events.KeyEvent; +import dwt.events.KeyListener; +import dwt.events.MouseEvent; +import dwt.events.MouseListener; +import dwt.events.TraverseEvent; +import dwt.events.TraverseListener; +import dwt.events.VerifyEvent; +import dwt.graphics.Color; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Listener; +import dwt.widgets.Monitor; +import dwt.widgets.Shell; +import dwt.widgets.Widget; +import dwtx.core.commands.IHandler; +import dwtx.core.runtime.Assert; +import dwtx.core.runtime.ListenerList; +import dwtx.jface.bindings.keys.KeySequence; +import dwtx.jface.contentassist.IContentAssistSubjectControl; +import dwtx.jface.contentassist.ISubjectControlContentAssistProcessor; +import dwtx.jface.dialogs.IDialogSettings; +import dwtx.jface.preference.JFacePreferences; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentExtension3; +import dwtx.jface.text.IEventConsumer; +import dwtx.jface.text.IInformationControlCreator; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.IViewportListener; +import dwtx.jface.text.IWidgetTokenKeeper; +import dwtx.jface.text.IWidgetTokenKeeperExtension; +import dwtx.jface.text.IWidgetTokenOwner; +import dwtx.jface.text.IWidgetTokenOwnerExtension; +import dwtx.jface.text.TextUtilities; +import dwtx.jface.util.Geometry; + + +/** + * The standard implementation of the IContentAssistant interface. Usually, clients + * instantiate this class and configure it before using it. + */ +public class ContentAssistant : IContentAssistant, IContentAssistantExtension, IContentAssistantExtension2, IContentAssistantExtension3, IContentAssistantExtension4, IWidgetTokenKeeper, IWidgetTokenKeeperExtension { + + + + /** + * Content assist command identifier for 'select next proposal'. + * + * @since 3.4 + */ + public static const String SELECT_NEXT_PROPOSAL_COMMAND_ID= "dwtx.ui.edit.text.contentAssist.selectNextProposal"; //$NON-NLS-1$ + /** + * Content assist command identifier for 'select previous proposal'. + * + * @since 3.4 + */ + public static const String SELECT_PREVIOUS_PROPOSAL_COMMAND_ID= "dwtx.ui.edit.text.contentAssist.selectPreviousProposal"; //$NON-NLS-1$ + + + /** + * A generic closer class used to monitor various interface events in order to determine whether + * content-assist should be terminated and all associated windows closed. + */ + class Closer : ControlListener, MouseListener, FocusListener, DisposeListener, IViewportListener { + + /** The shell that a ControlListener is registered with. */ + private Shell fShell; + /** + * The control that a MouseListener, aFocusListener and a + * DisposeListener are registered with. + */ + private Control fControl; + + /** + * Installs this closer on it's viewer's text widget. + */ + protected void install() { + Control control= fContentAssistSubjectControlAdapter.getControl(); + fControl= control; + if (Helper.okToUse(control)) { + + Shell shell= control.getShell(); + fShell= shell; + shell.addControlListener(this); + + control.addMouseListener(this); + control.addFocusListener(this); + + /* + * 1GGYYWK: ITPJUI:ALL - Dismissing editor with code assist up causes lots of + * Internal Errors + */ + control.addDisposeListener(this); + } + if (fViewer !is null) + fViewer.addViewportListener(this); + } + + /** + * Uninstalls this closer from the viewer's text widget. + */ + protected void uninstall() { + Control shell= fShell; + fShell= null; + if (Helper.okToUse(shell)) + shell.removeControlListener(this); + + Control control= fControl; + fControl= null; + if (Helper.okToUse(control)) { + + control.removeMouseListener(this); + control.removeFocusListener(this); + + /* + * 1GGYYWK: ITPJUI:ALL - Dismissing editor with code assist up causes lots of + * Internal Errors + */ + control.removeDisposeListener(this); + } + + if (fViewer !is null) + fViewer.removeViewportListener(this); + } + + /* + * @see ControlListener#controlResized(ControlEvent) + */ + public void controlResized(ControlEvent e) { + hide(); + } + + /* + * @see ControlListener#controlMoved(ControlEvent) + */ + public void controlMoved(ControlEvent e) { + hide(); + } + + /* + * @see MouseListener#mouseDown(MouseEvent) + */ + public void mouseDown(MouseEvent e) { + hide(); + } + + /* + * @see MouseListener#mouseUp(MouseEvent) + */ + public void mouseUp(MouseEvent e) { + } + + /* + * @see MouseListener#mouseDoubleClick(MouseEvent) + */ + public void mouseDoubleClick(MouseEvent e) { + hide(); + } + + /* + * @see FocusListener#focusGained(FocusEvent) + */ + public void focusGained(FocusEvent e) { + } + + /* + * @see FocusListener#focusLost(FocusEvent) + */ + public void focusLost(FocusEvent e) { + Control control= fControl; + if (Helper.okToUse(control)) { + Display d= control.getDisplay(); + if (d !is null) { + d.asyncExec(new class() Runnable { + public void run() { + if (!fProposalPopup.hasFocus() && (fContextInfoPopup is null || !fContextInfoPopup.hasFocus())) + hide(); + } + }); + } + } + } + + /* + * @seeDisposeListener#widgetDisposed(DisposeEvent) + */ + public void widgetDisposed(DisposeEvent e) { + /* + * 1GGYYWK: ITPJUI:ALL - Dismissing editor with code assist up causes lots of Internal + * Errors + */ + hide(); + } + + /* + * @see IViewportListener#viewportChanged(int) + */ + public void viewportChanged(int topIndex) { + hide(); + } + } + + /** + * An implementation of IContentAssistListener, this class is used to monitor + * key events in support of automatic activation of the content assistant. If enabled, the + * implementation utilizes a thread to watch for input characters matching the activation + * characters specified by the content assist processor, and if detected, will wait the + * indicated delay interval before activating the content assistant. + * + * @since 3.4 protected, was added in 2.1 as private class + */ + protected class AutoAssistListener : KeyAdapter , KeyListener, Runnable, VerifyKeyListener { + + private Thread fThread; + private bool fIsReset= false; + private Object fMutex= new Object(); + private int fShowStyle; + + private const static int SHOW_PROPOSALS= 1; + private const static int SHOW_CONTEXT_INFO= 2; + + protected this() { + } + + protected void start(int showStyle) { + fShowStyle= showStyle; + fThread= new Thread(&run); + fThread.name = JFaceTextMessages.getString("ContentAssistant.assist_delay_timer_name"); //$NON-NLS-1$ + fThread.start(); + } + + public void run() { + try { + while (true) { + synchronized (fMutex) { + if (fAutoActivationDelay !is 0) + fMutex.wait(fAutoActivationDelay); + if (fIsReset) { + fIsReset= false; + continue; + } + } + showAssist(fShowStyle); + break; + } + } catch (InterruptedException e) { + } + fThread= null; + } + + protected void reset(int showStyle) { + synchronized (fMutex) { + fShowStyle= showStyle; + fIsReset= true; + fMutex.notifyAll(); + } + } + + protected void stop() { + Thread threadToStop= fThread; + if (threadToStop !is null && threadToStop.isAlive()) + threadToStop.interrupt(); + } + + private bool contains(char[] characters, char character) { + if (characters !is null) { + for (int i= 0; i < characters.length; i++) { + if (character is characters[i]) + return true; + } + } + return false; + } + + public void keyPressed(KeyEvent e) { + // Only act on typed characters and ignore modifier-only events + if (e.character is 0 && (e.keyCode & DWT.KEYCODE_BIT) is 0) + return; + + if (e.character !is 0 && (e.stateMask is DWT.ALT)) + return; + + // Only act on characters that are trigger candidates. This + // avoids computing the model selection on every keystroke + if (computeAllAutoActivationTriggers().indexOf(e.character) < 0) { + stop(); + return; + } + + int showStyle; + int pos= fContentAssistSubjectControlAdapter.getSelectedRange().x; + char[] activation; + + activation= fContentAssistSubjectControlAdapter.getCompletionProposalAutoActivationCharacters(this.outer, pos); + + if (contains(activation, e.character) && !isProposalPopupActive()) + showStyle= SHOW_PROPOSALS; + else { + activation= fContentAssistSubjectControlAdapter.getContextInformationAutoActivationCharacters(this.outer, pos); + if (contains(activation, e.character) && !isContextInfoPopupActive()) + showStyle= SHOW_CONTEXT_INFO; + else { + stop(); + return; + } + } + + if (fThread !is null && fThread.isAlive()) + reset(showStyle); + else + start(showStyle); + } + + /* + * @see dwt.custom.VerifyKeyListener#verifyKey(dwt.events.VerifyEvent) + */ + public void verifyKey(VerifyEvent event) { + keyPressed(event); + } + + protected void showAssist(int showStyle) { + final Control control= fContentAssistSubjectControlAdapter.getControl(); + if (control is null) + return; + + final Display d= control.getDisplay(); + if (d is null) + return; + + try { + d.syncExec(new class() Runnable { + public void run() { + if (isProposalPopupActive()) + return; + + if (control.isDisposed() || !control.isFocusControl()) + return; + + if (showStyle is SHOW_PROPOSALS) { + if (!prepareToShowCompletions(true)) + return; + fProposalPopup.showProposals(true); + fLastAutoActivation= System.currentTimeMillis(); + } else if (showStyle is SHOW_CONTEXT_INFO && fContextInfoPopup !is null) { + promoteKeyListener(); + fContextInfoPopup.showContextProposals(true); + } + } + }); + } catch (DWTError e) { + } + } + } + + /** + * The layout manager layouts the various windows associated with the content assistant based on + * the settings of the content assistant. + */ + class LayoutManager : Listener { + + // Presentation types. + /** The presentation type for the proposal selection popup. */ + public const static int LAYOUT_PROPOSAL_SELECTOR= 0; + /** The presentation type for the context selection popup. */ + public const static int LAYOUT_CONTEXT_SELECTOR= 1; + /** The presentation type for the context information hover . */ + public const static int LAYOUT_CONTEXT_INFO_POPUP= 2; + + int fContextType= LAYOUT_CONTEXT_SELECTOR; + Shell[] fShells= new Shell[3]; + Object[] fPopups= new Object[3]; + + protected void add(Object popup, Shell shell, int type, int offset) { + Assert.isNotNull(popup); + Assert.isTrue(shell !is null && !shell.isDisposed()); + checkType(type); + + if (fShells[type] !is shell) { + if (fShells[type] !is null) + fShells[type].removeListener(DWT.Dispose, this); + shell.addListener(DWT.Dispose, this); + fShells[type]= shell; + } + + fPopups[type]= popup; + if (type is LAYOUT_CONTEXT_SELECTOR || type is LAYOUT_CONTEXT_INFO_POPUP) + fContextType= type; + + layout(type, offset); + adjustListeners(type); + } + + protected void checkType(int type) { + Assert.isTrue(type is LAYOUT_PROPOSAL_SELECTOR || + type is LAYOUT_CONTEXT_SELECTOR || type is LAYOUT_CONTEXT_INFO_POPUP); + } + + public void handleEvent(Event event) { + Widget source= event.widget; + source.removeListener(DWT.Dispose, this); + + int type= getShellType(source); + checkType(type); + fShells[type]= null; + + switch (type) { + case LAYOUT_PROPOSAL_SELECTOR: + if (fContextType is LAYOUT_CONTEXT_SELECTOR && + Helper.okToUse(fShells[LAYOUT_CONTEXT_SELECTOR])) { + // Restore event notification to the tip popup. + addContentAssistListener(cast(IContentAssistListener) fPopups[LAYOUT_CONTEXT_SELECTOR], CONTEXT_SELECTOR); + } + break; + + case LAYOUT_CONTEXT_SELECTOR: + if (Helper.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) { + if (fProposalPopupOrientation is PROPOSAL_STACKED) + layout(LAYOUT_PROPOSAL_SELECTOR, getSelectionOffset()); + // Restore event notification to the proposal popup. + addContentAssistListener(cast(IContentAssistListener) fPopups[LAYOUT_PROPOSAL_SELECTOR], PROPOSAL_SELECTOR); + } + fContextType= LAYOUT_CONTEXT_INFO_POPUP; + break; + + case LAYOUT_CONTEXT_INFO_POPUP: + if (Helper.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) { + if (fContextInfoPopupOrientation is CONTEXT_INFO_BELOW) + layout(LAYOUT_PROPOSAL_SELECTOR, getSelectionOffset()); + } + fContextType= LAYOUT_CONTEXT_SELECTOR; + break; + } + } + + protected int getShellType(Widget shell) { + for (int i= 0; i < fShells.length; i++) { + if (fShells[i] is shell) + return i; + } + return -1; + } + + /** + * Layouts the popup defined by type at the given widget offset. + * + * @param type the kind of popup to layout + * @param offset the widget offset + */ + protected void layout(int type, int offset) { + switch (type) { + case LAYOUT_PROPOSAL_SELECTOR: + layoutProposalSelector(offset); + break; + case LAYOUT_CONTEXT_SELECTOR: + layoutContextSelector(offset); + break; + case LAYOUT_CONTEXT_INFO_POPUP: + layoutContextInfoPopup(offset); + break; + } + } + + protected void layoutProposalSelector(int offset) { + if (fContextType is LAYOUT_CONTEXT_INFO_POPUP && + fContextInfoPopupOrientation is CONTEXT_INFO_BELOW && + Helper.okToUse(fShells[LAYOUT_CONTEXT_INFO_POPUP])) { + // Stack proposal selector beneath the tip box. + Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR]; + Shell parent= fShells[LAYOUT_CONTEXT_INFO_POPUP]; + shell.setLocation(getStackedLocation(shell, parent)); + } else if (fContextType !is LAYOUT_CONTEXT_SELECTOR || + !Helper.okToUse(fShells[LAYOUT_CONTEXT_SELECTOR])) { + // There are no other presentations to be concerned with, + // so place the proposal selector beneath the cursor line. + Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR]; + CompletionProposalPopup popup= cast(CompletionProposalPopup) fPopups[LAYOUT_PROPOSAL_SELECTOR]; + shell.setBounds(computeBoundsBelowAbove(shell, shell.getSize(), offset, popup)); + } else { + CompletionProposalPopup popup= (cast(CompletionProposalPopup) fPopups[LAYOUT_PROPOSAL_SELECTOR]); + switch (fProposalPopupOrientation) { + case PROPOSAL_REMOVE: { + // Remove the tip selector and place the + // proposal selector beneath the cursor line. + fShells[LAYOUT_CONTEXT_SELECTOR].dispose(); + Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR]; + shell.setBounds(computeBoundsBelowAbove(shell, shell.getSize(), offset, popup)); + break; + } + case PROPOSAL_OVERLAY: { + // Overlay the tip selector with the proposal selector. + Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR]; + shell.setBounds(computeBoundsBelowAbove(shell, shell.getSize(), offset, popup)); + break; + } + case PROPOSAL_STACKED: { + // Stack the proposal selector beneath the tip selector. + Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR]; + Shell parent= fShells[LAYOUT_CONTEXT_SELECTOR]; + shell.setLocation(getStackedLocation(shell, parent)); + break; + } + } + } + } + + protected void layoutContextSelector(int offset) { + // Always place the context selector beneath the cursor line. + Shell shell= fShells[LAYOUT_CONTEXT_SELECTOR]; + shell.setBounds(computeBoundsBelowAbove(shell, shell.getSize(), offset, null)); + + if (Helper.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) { + switch (fProposalPopupOrientation) { + case PROPOSAL_REMOVE: + // Remove the proposal selector. + fShells[LAYOUT_PROPOSAL_SELECTOR].dispose(); + break; + + case PROPOSAL_OVERLAY: + // The proposal selector has been overlaid by the tip selector. + break; + + case PROPOSAL_STACKED: { + // Stack the proposal selector beneath the tip selector. + shell= fShells[LAYOUT_PROPOSAL_SELECTOR]; + Shell parent= fShells[LAYOUT_CONTEXT_SELECTOR]; + shell.setLocation(getStackedLocation(shell, parent)); + break; + } + } + } + } + + protected void layoutContextInfoPopup(int offset) { + switch (fContextInfoPopupOrientation) { + case CONTEXT_INFO_ABOVE: { + // Place the popup above the cursor line. + Shell shell= fShells[LAYOUT_CONTEXT_INFO_POPUP]; + shell.setBounds(computeBoundsAboveBelow(shell, shell.getSize(), offset)); + break; + } + case CONTEXT_INFO_BELOW: { + // Place the popup beneath the cursor line. + Shell parent= fShells[LAYOUT_CONTEXT_INFO_POPUP]; + parent.setBounds(computeBoundsBelowAbove(parent, parent.getSize(), offset, null)); + if (Helper.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) { + // Stack the proposal selector beneath the context info popup. + Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR]; + shell.setLocation(getStackedLocation(shell, parent)); + } + break; + } + } + } + + /** + * Moves point such that rectangle does not bleed outside of + * bounds. All coordinates must have the same reference. + * + * @param point the point to move if needed + * @param shellSize the size of the shell that may be moved + * @param bounds the bounds + * @since 3.3 + */ + protected void constrainLocation(Point point, Point shellSize, Rectangle bounds) { + if (point.x + shellSize.x > bounds.x + bounds.width) + point.x= bounds.x + bounds.width - shellSize.x; + + if (point.x < bounds.x) + point.x= bounds.x; + + if (point.y + shellSize.y > bounds.y + bounds.height) + point.y= bounds.y + bounds.height - shellSize.y; + + if (point.y < bounds.y) + point.y= bounds.y; + } + + protected Rectangle constrainHorizontally(Rectangle rect, Rectangle bounds) { + // clip width + if (rect.width > bounds.width) + rect.width= bounds.width; + + if (rect.x + rect.width > bounds.x + bounds.width) + rect.x= bounds.x + bounds.width - rect.width; + if (rect.x < bounds.x) + rect.x= bounds.x; + + return rect; + } + + /** + * Returns the display bounds for shell such that it appears right above + * offset, or below it if above is not suitable. The returned bounds lie + * within the monitor at the caret location and never overlap with the caret line. + * + * @param shell the shell to compute the placement for + * @param preferred the preferred size for shell + * @param offset the caret offset in the subject control + * @return the point right above offset in display coordinates + * @since 3.3 + */ + protected Rectangle computeBoundsAboveBelow(Shell shell, Point preferred, int offset) { + Control subjectControl= fContentAssistSubjectControlAdapter.getControl(); + Display display= subjectControl.getDisplay(); + Rectangle caret= getCaretRectangle(offset); + Monitor monitor= getClosestMonitor(display, caret); + Rectangle bounds= monitor.getClientArea(); + Geometry.moveInside(caret, bounds); + + int spaceAbove= caret.y - bounds.y; + int caretLowerY= caret.y + caret.height; + int spaceBelow= bounds.y + bounds.height - caretLowerY; + Rectangle rect; + if (spaceAbove >= preferred.y) + rect= new Rectangle(caret.x, caret.y - preferred.y, preferred.x, preferred.y); + else if (spaceBelow >= preferred.y) + rect= new Rectangle(caret.x, caretLowerY, preferred.x, preferred.y); + // we can't fit in the preferred size - squeeze into larger area + else if (spaceBelow <= spaceAbove) + rect= new Rectangle(caret.x, bounds.y, preferred.x, spaceAbove); + else + rect= new Rectangle(caret.x, caretLowerY, preferred.x, spaceBelow); + + return constrainHorizontally(rect, bounds); + } + package Rectangle computeBoundsAboveBelow_package(Shell shell, Point preferred, int offset) { + return computeBoundsAboveBelow(shell, preferred, offset); + } + + /** + * Returns the display bounds for shell such that it appears right below + * offset, or above it if below is not suitable. The returned bounds lie + * within the monitor at the caret location and never overlap with the caret line. + * + * @param shell the shell to compute the placement for + * @param preferred the preferred size for shell + * @param offset the caret offset in the subject control + * @param popup a popup to inform if the location was switched to above, null to do nothing + * @return the point right below offset in display coordinates + * @since 3.3 + */ + protected Rectangle computeBoundsBelowAbove(Shell shell, Point preferred, int offset, CompletionProposalPopup popup) { + Control subjectControl= fContentAssistSubjectControlAdapter.getControl(); + Display display= subjectControl.getDisplay(); + Rectangle caret= getCaretRectangle(offset); + Monitor monitor= getClosestMonitor(display, caret); + Rectangle bounds= monitor.getClientArea(); + Geometry.moveInside(caret, bounds); + + int threshold= popup is null ? Integer.MAX_VALUE : popup.getMinimalHeight(); + int spaceAbove= caret.y - bounds.y; + int spaceBelow= bounds.y + bounds.height - (caret.y + caret.height); + Rectangle rect; + bool switched= false; + if (spaceBelow >= preferred.y) + rect= new Rectangle(caret.x, caret.y + caret.height, preferred.x, preferred.y); + // squeeze in below if we have at least threshold space + else if (spaceBelow >= threshold) + rect= new Rectangle(caret.x, caret.y + caret.height, preferred.x, spaceBelow); + else if (spaceAbove >= preferred.y) { + rect= new Rectangle(caret.x, caret.y - preferred.y, preferred.x, preferred.y); + switched= true; + } else if (spaceBelow >= spaceAbove) { + // we can't fit in the preferred size - squeeze into larger area + rect= new Rectangle(caret.x, caret.y + caret.height, preferred.x, spaceBelow); + } else { + rect= new Rectangle(caret.x, bounds.y, preferred.x, spaceAbove); + switched= true; + } + + if (popup !is null) + popup.switchedPositionToAbove(switched); + + return constrainHorizontally(rect, bounds); + } + package Rectangle computeBoundsBelowAbove_package(Shell shell, Point preferred, int offset, CompletionProposalPopup popup) { + return computeBoundsBelowAbove(shell, preferred, offset, popup ); + } + + private Rectangle getCaretRectangle(int offset) { + Point location= fContentAssistSubjectControlAdapter.getLocationAtOffset(offset); + Control subjectControl= fContentAssistSubjectControlAdapter.getControl(); + Point controlSize= subjectControl.getSize(); + constrainLocation(location, new Point(0, 0), new Rectangle(0, 0, controlSize.x, controlSize.y)); + location= subjectControl.toDisplay(location); + Rectangle subjectRectangle= new Rectangle(location.x, location.y, 1, fContentAssistSubjectControlAdapter.getLineHeight()); + return subjectRectangle; + } + + protected Point getStackedLocation(Shell shell, Shell parent) { + Point p= parent.getLocation(); + Point size= parent.getSize(); + p.x += size.x / 4; + p.y += size.y; + + p= parent.toDisplay(p); + + Point shellSize= shell.getSize(); + Monitor monitor= getClosestMonitor(parent.getDisplay(), new Rectangle(p.x, p.y, 0, 0)); + Rectangle displayBounds= monitor.getClientArea(); + constrainLocation(p, shellSize, displayBounds); + + return p; + } + + protected void adjustListeners(int type) { + switch (type) { + case LAYOUT_PROPOSAL_SELECTOR: + if (fContextType is LAYOUT_CONTEXT_SELECTOR && + Helper.okToUse(fShells[LAYOUT_CONTEXT_SELECTOR])) + // Disable event notification to the tip selector. + removeContentAssistListener(cast(IContentAssistListener) fPopups[LAYOUT_CONTEXT_SELECTOR], CONTEXT_SELECTOR); + break; + case LAYOUT_CONTEXT_SELECTOR: + if (Helper.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) + // Disable event notification to the proposal selector. + removeContentAssistListener(cast(IContentAssistListener) fPopups[LAYOUT_PROPOSAL_SELECTOR], PROPOSAL_SELECTOR); + break; + case LAYOUT_CONTEXT_INFO_POPUP: + break; + } + } + + /** + * Copied from dwtx.jface.window.Window. + * Returns the monitor whose client area contains the given point. If no + * monitor contains the point, returns the monitor that is closest to the + * point. If this is ever made public, it should be moved into a separate + * utility class. + * + * @param toSearch + * point to find (display coordinates) + * @param rectangle + * rectangle to find (display coordinates) + * @return the monitor closest to the given point + * @since 3.3 + */ + private Monitor getClosestMonitor(Display toSearch, Rectangle rectangle) { + int closest = Integer.MAX_VALUE; + + Point toFind= Geometry.centerPoint(rectangle); + Monitor[] monitors = toSearch.getMonitors(); + Monitor result = monitors[0]; + + for (int idx = 0; idx < monitors.length; idx++) { + Monitor current = monitors[idx]; + + Rectangle clientArea = current.getClientArea(); + + if (clientArea.contains(toFind)) { + return current; + } + + int distance = Geometry.distanceSquared(Geometry.centerPoint(clientArea), toFind); + if (distance < closest) { + closest = distance; + result = current; + } + } + + return result; + } + } + + /** + * Internal key listener and event consumer. + */ + class InternalListener : VerifyKeyListener, IEventConsumer { + + /** + * Verifies key events by notifying the registered listeners. Each listener is allowed to + * indicate that the event has been handled and should not be further processed. + * + * @param e the verify event + * @see VerifyKeyListener#verifyKey(dwt.events.VerifyEvent) + */ + public void verifyKey(VerifyEvent e) { + IContentAssistListener[] listeners= arraycast!(IContentAssistListener)( fListeners.clone() ); + for (int i= 0; i < listeners.length; i++) { + if (listeners[i] !is null) { + if (!listeners[i].verifyKey(e) || !e.doit) + break; + } + } + if (fAutoAssistListener !is null) + fAutoAssistListener.keyPressed(e); + } + + /* + * @see IEventConsumer#processEvent + */ + public void processEvent(VerifyEvent event) { + + installKeyListener(); + + IContentAssistListener[] listeners= arraycast!(IContentAssistListener)( fListeners.clone() ); + for (int i= 0; i < listeners.length; i++) { + if (listeners[i] !is null) { + listeners[i].processEvent(event); + if (!event.doit) + return; + } + } + } + } + + /** + * Dialog store constants. + * + * @since 3.0 + */ + public static const String STORE_SIZE_X= "size.x"; //$NON-NLS-1$ + public static const String STORE_SIZE_Y= "size.y"; //$NON-NLS-1$ + + // Content-Assist Listener types + final static int CONTEXT_SELECTOR= 0; + final static int PROPOSAL_SELECTOR= 1; + final static int CONTEXT_INFO_POPUP= 2; + + /** + * The popup priority: > linked position proposals and hover pop-ups. Default value: + * 20; + * + * @since 3.0 + */ + public static const int WIDGET_PRIORITY= 20; + + private static const int DEFAULT_AUTO_ACTIVATION_DELAY= 500; + + private IInformationControlCreator fInformationControlCreator; + private int fAutoActivationDelay= DEFAULT_AUTO_ACTIVATION_DELAY; + private bool fIsAutoActivated= false; + private bool fIsAutoInserting= false; + private int fProposalPopupOrientation= PROPOSAL_OVERLAY; + private int fContextInfoPopupOrientation= CONTEXT_INFO_ABOVE; + private Map fProcessors; + + /** + * The partitioning. + * + * @since 3.0 + */ + private String fPartitioning; + + private Color fContextInfoPopupBackground; + private Color fContextInfoPopupForeground; + private Color fContextSelectorBackground; + private Color fContextSelectorForeground; + private Color fProposalSelectorBackground; + private Color fProposalSelectorForeground; + + private ITextViewer fViewer; + private String fLastErrorMessage; + + private Closer fCloser; + LayoutManager fLayoutManager; + private AutoAssistListener fAutoAssistListener; + private InternalListener fInternalListener; + private CompletionProposalPopup fProposalPopup; + private ContextInformationPopup fContextInfoPopup; + + /** + * Flag which tells whether a verify key listener is hooked. + * + * @since 3.0 + */ + private bool fVerifyKeyListenerHooked= false; + private IContentAssistListener[] fListeners; + /** + * The content assist subject control. + * + * @since 3.0 + */ + private IContentAssistSubjectControl fContentAssistSubjectControl; + /** + * The content assist subject control's shell. + * + * @since 3.2 + */ + private Shell fContentAssistSubjectControlShell; + /** + * The content assist subject control's shell traverse listener. + * + * @since 3.2 + */ + private TraverseListener fCASCSTraverseListener; + /** + * The content assist subject control adapter. + * + * @since 3.0 + */ + private ContentAssistSubjectControlAdapter fContentAssistSubjectControlAdapter; + /** + * The dialog settings for the control's bounds. + * + * @since 3.0 + */ + private IDialogSettings fDialogSettings; + /** + * Prefix completion setting. + * + * @since 3.0 + */ + private bool fIsPrefixCompletionEnabled= false; + /** + * The list of completion listeners. + * + * @since 3.2 + */ + private ListenerList fCompletionListeners; + /** + * The message to display at the bottom of the proposal popup. + * + * @since 3.2 + */ + private String fMessage= ""; //$NON-NLS-1$ + /** + * The cycling mode property. + * + * @since 3.2 + */ + private bool fIsRepetitionMode= false; + /** + * The show empty property. + * + * @since 3.2 + */ + private bool fShowEmptyList= false; + /** + * The message line property. + * + * @since 3.2 + */ + private bool fIsStatusLineVisible; + /** + * The last system time when auto activation performed. + * + * @since 3.2 + */ + private long fLastAutoActivation= Long.MIN_VALUE; + /** + * The iteration key sequence to listen for, or null. + * + * @since 3.2 + */ + private KeySequence fRepeatedInvocationKeySequence; + + /** + * Maps handler to command identifiers. + * + * @since 3.4 + */ + private Map fHandlers; + + /** + * Tells whether colored labels support is enabled. + * + * @since 3.4 + */ + private bool fIsColoredLabelsSupportEnabled= false; + + + /** + * Creates a new content assistant. The content assistant is not automatically activated, + * overlays the completion proposals with context information list if necessary, and shows the + * context information above the location at which it was activated. If auto activation will be + * enabled, without further configuration steps, this content assistant is activated after a 500 + * milliseconds delay. It uses the default partitioning. + */ + public this() { + fListeners= new IContentAssistListener[4]; + fCompletionListeners= new ListenerList(ListenerList.IDENTITY); + fPartitioning= IDocumentExtension3.DEFAULT_PARTITIONING; + } + + /** + * Sets the document partitioning this content assistant is using. + * + * @param partitioning the document partitioning for this content assistant + * @since 3.0 + */ + public void setDocumentPartitioning(String partitioning) { + Assert.isNotNull(partitioning); + fPartitioning= partitioning; + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistantExtension#getDocumentPartitioning() + * @since 3.0 + */ + public String getDocumentPartitioning() { + return fPartitioning; + } + + /** + * Registers a given content assist processor for a particular content type. If there is already + * a processor registered for this type, the new processor is registered instead of the old one. + * + * @param processor the content assist processor to register, or null to remove + * an existing one + * @param contentType the content type under which to register + */ + public void setContentAssistProcessor(IContentAssistProcessor processor, String contentType) { + + Assert.isNotNull(contentType); + + if (fProcessors is null) + fProcessors= new HashMap(); + + if (processor is null) + fProcessors.remove(contentType); + else + fProcessors.put(contentType, processor); + } + + /* + * @see IContentAssistant#getContentAssistProcessor + */ + public IContentAssistProcessor getContentAssistProcessor(String contentType) { + if (fProcessors is null) + return null; + + return cast(IContentAssistProcessor) fProcessors.get(contentType); + } + + /** + * Computes the sorted set of all auto activation trigger characters. + * + * @return the sorted set of all auto activation trigger characters + * @since 3.1 + */ + private String computeAllAutoActivationTriggers() { + if (fProcessors is null) + return ""; //$NON-NLS-1$ + + StringBuffer buf= new StringBuffer(5); + Iterator iter= fProcessors.entrySet().iterator(); + while (iter.hasNext()) { + Entry entry= cast(Entry) iter.next(); + IContentAssistProcessor processor= cast(IContentAssistProcessor) entry.getValue(); + char[] triggers= processor.getCompletionProposalAutoActivationCharacters(); + if (triggers !is null) + buf.append(triggers); + triggers= processor.getContextInformationAutoActivationCharacters(); + if (triggers !is null) + buf.append(triggers); + } + return buf.toString(); + } + + /** + * Enables the content assistant's auto activation mode. + * + * @param enabled indicates whether auto activation is enabled or not + */ + public void enableAutoActivation(bool enabled) { + fIsAutoActivated= enabled; + manageAutoActivation(fIsAutoActivated); + } + + /** + * Enables the content assistant's auto insertion mode. If enabled, the content assistant + * inserts a proposal automatically if it is the only proposal. In the case of ambiguities, the + * user must make the choice. + * + * @param enabled indicates whether auto insertion is enabled or not + * @since 2.0 + */ + public void enableAutoInsert(bool enabled) { + fIsAutoInserting= enabled; + } + + /** + * Returns whether this content assistant is in the auto insertion mode or not. + * + * @return true if in auto insertion mode + * @since 2.0 + */ + bool isAutoInserting() { + return fIsAutoInserting; + } + + /** + * Installs and uninstall the listeners needed for auto activation. + * + * @param start true if listeners must be installed, false if they + * must be removed + * @since 2.0 + */ + private void manageAutoActivation(bool start) { + if (start) { + + if ((fContentAssistSubjectControlAdapter !is null) && fAutoAssistListener is null) { + fAutoAssistListener= createAutoAssistListener(); + // For details see https://bugs.eclipse.org/bugs/show_bug.cgi?id=49212 + if (fContentAssistSubjectControlAdapter.supportsVerifyKeyListener()) + fContentAssistSubjectControlAdapter.appendVerifyKeyListener(fAutoAssistListener); + else + fContentAssistSubjectControlAdapter.addKeyListener(fAutoAssistListener); + } + + } else if (fAutoAssistListener !is null) { + // For details see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=49212 + if (fContentAssistSubjectControlAdapter.supportsVerifyKeyListener()) + fContentAssistSubjectControlAdapter.removeVerifyKeyListener(fAutoAssistListener); + else + fContentAssistSubjectControlAdapter.removeKeyListener(fAutoAssistListener); + fAutoAssistListener= null; + } + } + + /** + * This method allows subclasses to provide their own {@link AutoAssistListener}. + * + * @return a new auto assist listener + * @since 3.4 + */ + protected AutoAssistListener createAutoAssistListener() { + return new AutoAssistListener(); + } + + /** + * Sets the delay after which the content assistant is automatically invoked if the cursor is + * behind an auto activation character. + * + * @param delay the auto activation delay + */ + public void setAutoActivationDelay(int delay) { + fAutoActivationDelay= delay; + } + + /** + * Gets the delay after which the content assistant is automatically invoked if the cursor is + * behind an auto activation character. + * + * @return the auto activation delay + * @since 3.4 + */ + public int getAutoActivationDelay() { + return fAutoActivationDelay; + } + + /** + * Sets the proposal pop-ups' orientation. The following values may be used: + *
                  + *
                • PROPOSAL_OVERLAY

                  + * proposal popup windows should overlay each other + *

                • + *
                • PROPOSAL_REMOVE

                  + * any currently shown proposal popup should be closed + *

                • + *
                • PROPOSAL_STACKED

                  + * proposal popup windows should be vertical stacked, with no overlap, + * beneath the line containing the current cursor location + *

                • + *
                + * + * @param orientation the popup's orientation + */ + public void setProposalPopupOrientation(int orientation) { + fProposalPopupOrientation= orientation; + } + + /** + * Sets the context information popup's orientation. + * The following values may be used: + *
                  + *
                • CONTEXT_ABOVE

                  + * context information popup should always appear above the line containing + * the current cursor location + *

                • + *
                • CONTEXT_BELOW

                  + * context information popup should always appear below the line containing + * the current cursor location + *

                • + *
                + * + * @param orientation the popup's orientation + */ + public void setContextInformationPopupOrientation(int orientation) { + fContextInfoPopupOrientation= orientation; + } + + /** + * Sets the context information popup's background color. + * + * @param background the background color + */ + public void setContextInformationPopupBackground(Color background) { + fContextInfoPopupBackground= background; + } + + /** + * Returns the background of the context information popup. + * + * @return the background of the context information popup + * @since 2.0 + */ + Color getContextInformationPopupBackground() { + return fContextInfoPopupBackground; + } + + /** + * Sets the context information popup's foreground color. + * + * @param foreground the foreground color + * @since 2.0 + */ + public void setContextInformationPopupForeground(Color foreground) { + fContextInfoPopupForeground= foreground; + } + + /** + * Returns the foreground of the context information popup. + * + * + * @return the foreground of the context information popup + * @since 2.0 + */ + Color getContextInformationPopupForeground() { + return fContextInfoPopupForeground; + } + + /** + * Sets the proposal selector's background color. + *

                + * Note: As of 3.4, you should only call this + * method if you want to override the {@link JFacePreferences#CONTENT_ASSIST_BACKGROUND_COLOR}. + *

                + * + * @param background the background color + * @since 2.0 + */ + public void setProposalSelectorBackground(Color background) { + fProposalSelectorBackground= background; + } + + /** + * Returns the custom background color of the proposal selector. + * + * @return the background of the proposal selector or null if not set + * @since 2.0 + */ + Color getProposalSelectorBackground() { + return fProposalSelectorBackground; + } + + /** + * Sets the proposal's foreground color. + *

                + * Note: As of 3.4, you should only call this + * method if you want to override the {@link JFacePreferences#CONTENT_ASSIST_FOREGROUND_COLOR}. + *

                + * + * @param foreground the foreground color + * @since 2.0 + */ + public void setProposalSelectorForeground(Color foreground) { + fProposalSelectorForeground= foreground; + } + + /** + * Returns the custom foreground color of the proposal selector. + * + * @return the foreground of the proposal selector or null if not set + * @since 2.0 + */ + Color getProposalSelectorForeground() { + return fProposalSelectorForeground; + } + + /** + * Sets the context selector's background color. + * + * @param background the background color + * @since 2.0 + */ + public void setContextSelectorBackground(Color background) { + fContextSelectorBackground= background; + } + + /** + * Returns the background of the context selector. + * + * @return the background of the context selector + * @since 2.0 + */ + Color getContextSelectorBackground() { + return fContextSelectorBackground; + } + + /** + * Sets the context selector's foreground color. + * + * @param foreground the foreground color + * @since 2.0 + */ + public void setContextSelectorForeground(Color foreground) { + fContextSelectorForeground= foreground; + } + + /** + * Returns the foreground of the context selector. + * + * @return the foreground of the context selector + * @since 2.0 + */ + Color getContextSelectorForeground() { + return fContextSelectorForeground; + } + + /** + * Sets the information control creator for the additional information control. + * + * @param creator the information control creator for the additional information control + * @since 2.0 + */ + public void setInformationControlCreator(IInformationControlCreator creator) { + fInformationControlCreator= creator; + } + + /* + * @see IControlContentAssistant#install(IContentAssistSubjectControl) + * @since 3.0 + */ + protected void install(IContentAssistSubjectControl contentAssistSubjectControl) { + fContentAssistSubjectControl= contentAssistSubjectControl; + fContentAssistSubjectControlAdapter= new ContentAssistSubjectControlAdapter(fContentAssistSubjectControl); + install(); + } + + /* + * @see IContentAssist#install + * @since 3.0 + */ + public void install(ITextViewer textViewer) { + fViewer= textViewer; + fContentAssistSubjectControlAdapter= new ContentAssistSubjectControlAdapter(fViewer); + install(); + } + + protected void install() { + + fLayoutManager= new LayoutManager(); + fInternalListener= new InternalListener(); + + AdditionalInfoController controller= null; + if (fInformationControlCreator !is null) { + int delay= fAutoActivationDelay; + if (delay is 0) + delay= DEFAULT_AUTO_ACTIVATION_DELAY; + delay= Math.round(delay * 1.5f); + controller= new AdditionalInfoController(fInformationControlCreator, delay); + } + + fContextInfoPopup= fContentAssistSubjectControlAdapter.createContextInfoPopup(this); + fProposalPopup= fContentAssistSubjectControlAdapter.createCompletionProposalPopup(this, controller); + + registerHandler(SELECT_NEXT_PROPOSAL_COMMAND_ID, fProposalPopup.createProposalSelectionHandler(CompletionProposalPopup.ProposalSelectionHandler.SELECT_NEXT)); + registerHandler(SELECT_PREVIOUS_PROPOSAL_COMMAND_ID, fProposalPopup.createProposalSelectionHandler(CompletionProposalPopup.ProposalSelectionHandler.SELECT_PREVIOUS)); + + if (Helper.okToUse(fContentAssistSubjectControlAdapter.getControl())) { + fContentAssistSubjectControlShell= fContentAssistSubjectControlAdapter.getControl().getShell(); + fCASCSTraverseListener= new class() TraverseListener { + public void keyTraversed(TraverseEvent e) { + if (e.detail is DWT.TRAVERSE_ESCAPE && isProposalPopupActive()) + e.doit= false; + } + }; + fContentAssistSubjectControlShell.addTraverseListener(fCASCSTraverseListener); + } + + manageAutoActivation(fIsAutoActivated); + } + + /* + * @see IContentAssist#uninstall + */ + public void uninstall() { + hide(); + manageAutoActivation(false); + + if (fHandlers !is null) { + fHandlers.clear(); + fHandlers= null; + } + + if (fCloser !is null) { + fCloser.uninstall(); + fCloser= null; + } + + if (Helper.okToUse(fContentAssistSubjectControlShell)) + fContentAssistSubjectControlShell.removeTraverseListener(fCASCSTraverseListener); + fCASCSTraverseListener= null; + fContentAssistSubjectControlShell= null; + + fViewer= null; + fContentAssistSubjectControl= null; + fContentAssistSubjectControlAdapter= null; + } + + /** + * Adds the given shell of the specified type to the layout. Valid types are defined by + * LayoutManager. + * + * @param popup a content assist popup + * @param shell the shell of the content-assist popup + * @param type the type of popup + * @param visibleOffset the offset at which to layout the popup relative to the offset of the + * viewer's visible region + * @since 2.0 + */ + void addToLayout(Object popup, Shell shell, int type, int visibleOffset) { + fLayoutManager.add(popup, shell, type, visibleOffset); + } + + /** + * Layouts the registered popup of the given type relative to the given offset. The offset is + * relative to the offset of the viewer's visible region. Valid types are defined by + * LayoutManager. + * + * @param type the type of popup to layout + * @param visibleOffset the offset at which to layout relative to the offset of the viewer's + * visible region + * @since 2.0 + */ + void layout(int type, int visibleOffset) { + fLayoutManager.layout(type, visibleOffset); + } + + /** + * Returns the layout manager. + * + * @return the layout manager + * @since 3.3 + */ + LayoutManager getLayoutManager() { + return fLayoutManager; + } + + /** + * Notifies the controller that a popup has lost focus. + * + * @param e the focus event + */ + void popupFocusLost(FocusEvent e) { + fCloser.focusLost(e); + } + + /** + * Returns the offset of the selection relative to the offset of the visible region. + * + * @return the offset of the selection relative to the offset of the visible region + * @since 2.0 + */ + int getSelectionOffset() { + return fContentAssistSubjectControlAdapter.getWidgetSelectionRange().x; + } + + /** + * Returns whether the widget token could be acquired. The following are valid listener types: + *
                  + *
                • AUTO_ASSIST
                • + *
                • CONTEXT_SELECTOR
                • + *
                • PROPOSAL_SELECTOR
                • + *
                • CONTEXT_INFO_POPUP
                • + *
                + * + * @param type the listener type for which to acquire + * @return true if the widget token could be acquired + * @since 2.0 + */ + private bool acquireWidgetToken(int type) { + switch (type) { + case CONTEXT_SELECTOR: + case PROPOSAL_SELECTOR: + if ( cast(IWidgetTokenOwnerExtension)fContentAssistSubjectControl ) { + IWidgetTokenOwnerExtension extension= cast(IWidgetTokenOwnerExtension) fContentAssistSubjectControl; + return extension.requestWidgetToken(this, WIDGET_PRIORITY); + } else if ( cast(IWidgetTokenOwner)fContentAssistSubjectControl ) { + IWidgetTokenOwner owner= cast(IWidgetTokenOwner) fContentAssistSubjectControl; + return owner.requestWidgetToken(this); + } else if ( cast(IWidgetTokenOwnerExtension)fViewer ) { + IWidgetTokenOwnerExtension extension= cast(IWidgetTokenOwnerExtension) fViewer; + return extension.requestWidgetToken(this, WIDGET_PRIORITY); + } else if ( cast(IWidgetTokenOwner)fViewer ) { + IWidgetTokenOwner owner= cast(IWidgetTokenOwner) fViewer; + return owner.requestWidgetToken(this); + } + } + return true; + } + + /** + * Registers a content assist listener. The following are valid listener types: + *
                  + *
                • AUTO_ASSIST
                • + *
                • CONTEXT_SELECTOR
                • + *
                • PROPOSAL_SELECTOR
                • + *
                • CONTEXT_INFO_POPUP
                • + *
                + * Returns whether the listener could be added successfully. A listener can not be added if the + * widget token could not be acquired. + * + * @param listener the listener to register + * @param type the type of listener + * @return true if the listener could be added + */ + bool addContentAssistListener(IContentAssistListener listener, int type) { + + if (acquireWidgetToken(type)) { + + fListeners[type]= listener; + + if (fCloser is null && getNumberOfListeners() is 1) { + fCloser= new Closer(); + fCloser.install(); + fContentAssistSubjectControlAdapter.setEventConsumer(fInternalListener); + installKeyListener(); + } else + promoteKeyListener(); + return true; + } + + return false; + } + + /** + * Re-promotes the key listener to the first position, using prependVerifyKeyListener. This + * ensures no other instance is filtering away the keystrokes underneath, if we've been up for a + * while (e.g. when the context info is showing. + * + * @since 3.0 + */ + private void promoteKeyListener() { + uninstallVerifyKeyListener(); + installKeyListener(); + } + + /** + * Installs a key listener on the text viewer's widget. + */ + private void installKeyListener() { + if (!fVerifyKeyListenerHooked) { + if (Helper.okToUse(fContentAssistSubjectControlAdapter.getControl())) { + fVerifyKeyListenerHooked= fContentAssistSubjectControlAdapter.prependVerifyKeyListener(fInternalListener); + } + } + } + + /** + * Releases the previously acquired widget token if the token is no longer necessary. The + * following are valid listener types: + *
                  + *
                • AUTO_ASSIST
                • + *
                • CONTEXT_SELECTOR
                • + *
                • PROPOSAL_SELECTOR
                • + *
                • CONTEXT_INFO_POPUP
                • + *
                + * + * @param type the listener type + * @since 2.0 + */ + private void releaseWidgetToken(int type) { + if (fListeners[CONTEXT_SELECTOR] is null && fListeners[PROPOSAL_SELECTOR] is null) { + IWidgetTokenOwner owner= null; + if ( cast(IWidgetTokenOwner)fContentAssistSubjectControl ) + owner= cast(IWidgetTokenOwner) fContentAssistSubjectControl; + else if ( cast(IWidgetTokenOwner)fViewer ) + owner= cast(IWidgetTokenOwner) fViewer; + if (owner !is null) + owner.releaseWidgetToken(this); + } + } + + /** + * Unregisters a content assist listener. + * + * @param listener the listener to unregister + * @param type the type of listener + * @see #addContentAssistListener(IContentAssistListener, int) + */ + void removeContentAssistListener(IContentAssistListener listener, int type) { + fListeners[type]= null; + + if (getNumberOfListeners() is 0) { + + if (fCloser !is null) { + fCloser.uninstall(); + fCloser= null; + } + + uninstallVerifyKeyListener(); + fContentAssistSubjectControlAdapter.setEventConsumer(null); + } + + releaseWidgetToken(type); + } + + /** + * Uninstall the key listener from the text viewer's widget. + * + * @since 3.0 + */ + private void uninstallVerifyKeyListener() { + if (fVerifyKeyListenerHooked) { + if (Helper.okToUse(fContentAssistSubjectControlAdapter.getControl())) + fContentAssistSubjectControlAdapter.removeVerifyKeyListener(fInternalListener); + fVerifyKeyListenerHooked= false; + } + } + + /** + * Returns the number of listeners. + * + * @return the number of listeners + * @since 2.0 + */ + private int getNumberOfListeners() { + int count= 0; + for (int i= 0; i <= CONTEXT_INFO_POPUP; i++) { + if (fListeners[i] !is null) + ++count; + } + return count; + } + + /* + * @see IContentAssist#showPossibleCompletions + */ + public String showPossibleCompletions() { + if (!prepareToShowCompletions(false)) + return null; + if (fIsPrefixCompletionEnabled) + return fProposalPopup.incrementalComplete(); + return fProposalPopup.showProposals(false); + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistantExtension#completePrefix() + * @since 3.0 + */ + public String completePrefix() { + if (!prepareToShowCompletions(false)) + return null; + return fProposalPopup.incrementalComplete(); + } + + /** + * Prepares to show content assist proposals. It returns false if auto activation has kicked in + * recently. + * + * @param isAutoActivated whether completion was triggered by auto activation + * @return true if the caller should continue and show the proposals, + * false otherwise. + * @since 3.2 + */ + private bool prepareToShowCompletions(bool isAutoActivated) { + long current= System.currentTimeMillis(); + int gracePeriod= Math.max(fAutoActivationDelay, 200); + if (current < fLastAutoActivation + gracePeriod) + return false; + + promoteKeyListener(); + fireSessionBeginEvent(isAutoActivated); + return true; + } + + /** + * Callback to signal this content assistant that the presentation of the possible completions + * has been stopped. + * + * @since 2.1 + */ + protected void possibleCompletionsClosed() { + fLastAutoActivation= Long.MIN_VALUE; + storeCompletionProposalPopupSize(); + } + package void possibleCompletionsClosed_package() { + possibleCompletionsClosed(); + } + + /* + * @see IContentAssist#showContextInformation + */ + public String showContextInformation() { + promoteKeyListener(); + if (fContextInfoPopup !is null) + return fContextInfoPopup.showContextProposals(false); + return null; + } + + /** + * Callback to signal this content assistant that the presentation of the context information + * has been stopped. + * + * @since 2.1 + */ + protected void contextInformationClosed() { + } + package void contextInformationClosed_package() { + contextInformationClosed(); + } + + /** + * Requests that the specified context information to be shown. + * + * @param contextInformation the context information to be shown + * @param offset the offset to which the context information refers to + * @since 2.0 + */ + void showContextInformation(IContextInformation contextInformation, int offset) { + if (fContextInfoPopup !is null) + fContextInfoPopup.showContextInformation(contextInformation, offset); + } + + /** + * Returns the current content assist error message. + * + * @return an error message or null if no error has occurred + */ + String getErrorMessage() { + return fLastErrorMessage; + } + + /** + * Returns the content assist processor for the content type of the specified document position. + * + * @param viewer the text viewer + * @param offset a offset within the document + * @return a content-assist processor or null if none exists + * @since 3.0 + */ + private IContentAssistProcessor getProcessor(ITextViewer viewer, int offset) { + try { + + IDocument document= viewer.getDocument(); + String type= TextUtilities.getContentType(document, getDocumentPartitioning(), offset, true); + + return getContentAssistProcessor(type); + + } catch (BadLocationException x) { + } + + return null; + } + + /** + * Returns the content assist processor for the content type of the specified document position. + * + * @param contentAssistSubjectControl the content assist subject control + * @param offset a offset within the document + * @return a content-assist processor or null if none exists + * @since 3.0 + */ + private IContentAssistProcessor getProcessor(IContentAssistSubjectControl contentAssistSubjectControl, int offset) { + try { + + IDocument document= contentAssistSubjectControl.getDocument(); + String type; + if (document !is null) + type= TextUtilities.getContentType(document, getDocumentPartitioning(), offset, true); + else + type= IDocument.DEFAULT_CONTENT_TYPE; + + return getContentAssistProcessor(type); + + } catch (BadLocationException x) { + } + + return null; + } + + /** + * Returns an array of completion proposals computed based on the specified document position. + * The position is used to determine the appropriate content assist processor to invoke. + * + * @param contentAssistSubjectControl the content assist subject control + * @param offset a document offset + * @return an array of completion proposals + * @see IContentAssistProcessor#computeCompletionProposals(ITextViewer, int) + * @since 3.0 + */ + ICompletionProposal[] computeCompletionProposals(IContentAssistSubjectControl contentAssistSubjectControl, int offset) { + fLastErrorMessage= null; + + ICompletionProposal[] result= null; + + IContentAssistProcessor p= getProcessor(contentAssistSubjectControl, offset); + if ( cast(ISubjectControlContentAssistProcessor)p ) { + result= (cast(ISubjectControlContentAssistProcessor) p).computeCompletionProposals(contentAssistSubjectControl, offset); + fLastErrorMessage= p.getErrorMessage(); + } + + return result; + } + + /** + * Returns an array of completion proposals computed based on the specified document position. + * The position is used to determine the appropriate content assist processor to invoke. + * + * @param viewer the viewer for which to compute the proposals + * @param offset a document offset + * @return an array of completion proposals or null if no proposals are possible + * @see IContentAssistProcessor#computeCompletionProposals(ITextViewer, int) + */ + ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) { + fLastErrorMessage= null; + + ICompletionProposal[] result= null; + + IContentAssistProcessor p= getProcessor(viewer, offset); + if (p !is null) { + result= p.computeCompletionProposals(viewer, offset); + fLastErrorMessage= p.getErrorMessage(); + } + + return result; + } + + /** + * Returns an array of context information objects computed based on the specified document + * position. The position is used to determine the appropriate content assist processor to + * invoke. + * + * @param viewer the viewer for which to compute the context information + * @param offset a document offset + * @return an array of context information objects + * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int) + */ + IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) { + fLastErrorMessage= null; + + IContextInformation[] result= null; + + IContentAssistProcessor p= getProcessor(viewer, offset); + if (p !is null) { + result= p.computeContextInformation(viewer, offset); + fLastErrorMessage= p.getErrorMessage(); + } + + return result; + } + + /** + * Returns an array of context information objects computed based on the specified document + * position. The position is used to determine the appropriate content assist processor to + * invoke. + * + * @param contentAssistSubjectControl the content assist subject control + * @param offset a document offset + * @return an array of context information objects + * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int) + * @since 3.0 + */ + IContextInformation[] computeContextInformation(IContentAssistSubjectControl contentAssistSubjectControl, int offset) { + fLastErrorMessage= null; + + IContextInformation[] result= null; + + IContentAssistProcessor p= getProcessor(contentAssistSubjectControl, offset); + if ( cast(ISubjectControlContentAssistProcessor)p ) { + result= (cast(ISubjectControlContentAssistProcessor) p).computeContextInformation(contentAssistSubjectControl, offset); + fLastErrorMessage= p.getErrorMessage(); + } + + return result; + } + + /** + * Returns the context information validator that should be used to determine when the currently + * displayed context information should be dismissed. The position is used to determine the + * appropriate content assist processor to invoke. + * + * @param viewer the text viewer + * @param offset a document offset + * @return an validator + * @see IContentAssistProcessor#getContextInformationValidator() + * @since 3.0 + */ + IContextInformationValidator getContextInformationValidator(ITextViewer viewer, int offset) { + IContentAssistProcessor p= getProcessor(viewer, offset); + return p !is null ? p.getContextInformationValidator() : null; + } + + /** + * Returns the context information validator that should be used to determine when the currently + * displayed context information should be dismissed. The position is used to determine the + * appropriate content assist processor to invoke. + * + * @param contentAssistSubjectControl the content assist subject control + * @param offset a document offset + * @return an validator + * @see IContentAssistProcessor#getContextInformationValidator() + * @since 3.0 + */ + IContextInformationValidator getContextInformationValidator(IContentAssistSubjectControl contentAssistSubjectControl, int offset) { + IContentAssistProcessor p= getProcessor(contentAssistSubjectControl, offset); + return p !is null ? p.getContextInformationValidator() : null; + } + + /** + * Returns the context information presenter that should be used to display context information. + * The position is used to determine the appropriate content assist processor to invoke. + * + * @param viewer the text viewer + * @param offset a document offset + * @return a presenter + * @since 2.0 + */ + IContextInformationPresenter getContextInformationPresenter(ITextViewer viewer, int offset) { + IContextInformationValidator validator= getContextInformationValidator(viewer, offset); + if ( cast(IContextInformationPresenter)validator ) + return cast(IContextInformationPresenter) validator; + return null; + } + + /** + * Returns the context information presenter that should be used to display context information. + * The position is used to determine the appropriate content assist processor to invoke. + * + * @param contentAssistSubjectControl the content assist subject control + * @param offset a document offset + * @return a presenter + * @since 3.0 + */ + IContextInformationPresenter getContextInformationPresenter(IContentAssistSubjectControl contentAssistSubjectControl, int offset) { + IContextInformationValidator validator= getContextInformationValidator(contentAssistSubjectControl, offset); + if ( cast(IContextInformationPresenter)validator ) + return cast(IContextInformationPresenter) validator; + return null; + } + + /** + * Returns the characters which when typed by the user should automatically initiate proposing + * completions. The position is used to determine the appropriate content assist processor to + * invoke. + * + * @param contentAssistSubjectControl the content assist subject control + * @param offset a document offset + * @return the auto activation characters + * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters() + * @since 3.0 + */ + char[] getCompletionProposalAutoActivationCharacters(IContentAssistSubjectControl contentAssistSubjectControl, int offset) { + IContentAssistProcessor p= getProcessor(contentAssistSubjectControl, offset); + return p !is null ? p.getCompletionProposalAutoActivationCharacters() : null; + } + + /** + * Returns the characters which when typed by the user should automatically initiate proposing + * completions. The position is used to determine the appropriate content assist processor to + * invoke. + * + * @param viewer the text viewer + * @param offset a document offset + * @return the auto activation characters + * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters() + */ + char[] getCompletionProposalAutoActivationCharacters(ITextViewer viewer, int offset) { + IContentAssistProcessor p= getProcessor(viewer, offset); + return p !is null ? p.getCompletionProposalAutoActivationCharacters() : null; + } + + /** + * Returns the characters which when typed by the user should automatically initiate the + * presentation of context information. The position is used to determine the appropriate + * content assist processor to invoke. + * + * @param viewer the text viewer + * @param offset a document offset + * @return the auto activation characters + * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters() + * @since 3.0 + */ + char[] getContextInformationAutoActivationCharacters(ITextViewer viewer, int offset) { + IContentAssistProcessor p= getProcessor(viewer, offset); + return p !is null ? p.getContextInformationAutoActivationCharacters() : null; + } + + /** + * Returns the characters which when typed by the user should automatically initiate the + * presentation of context information. The position is used to determine the appropriate + * content assist processor to invoke. + * + * @param contentAssistSubjectControl the content assist subject control + * @param offset a document offset + * @return the auto activation characters + * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters() + * @since 3.0 + */ + char[] getContextInformationAutoActivationCharacters(IContentAssistSubjectControl contentAssistSubjectControl, int offset) { + IContentAssistProcessor p= getProcessor(contentAssistSubjectControl, offset); + return p !is null ? p.getContextInformationAutoActivationCharacters() : null; + } + + /* + * @see dwtx.jface.text.IWidgetTokenKeeper#requestWidgetToken(IWidgetTokenOwner) + * @since 2.0 + */ + public bool requestWidgetToken(IWidgetTokenOwner owner) { + return false; + } + + /* + * @see dwtx.jface.text.IWidgetTokenKeeperExtension#requestWidgetToken(dwtx.jface.text.IWidgetTokenOwner, + * int) + * @since 3.0 + */ + public bool requestWidgetToken(IWidgetTokenOwner owner, int priority) { + if (priority > WIDGET_PRIORITY) { + hide(); + return true; + } + return false; + } + + /* + * @see dwtx.jface.text.IWidgetTokenKeeperExtension#setFocus(dwtx.jface.text.IWidgetTokenOwner) + * @since 3.0 + */ + public bool setFocus(IWidgetTokenOwner owner) { + if (fProposalPopup !is null) { + fProposalPopup.setFocus(); + return fProposalPopup.hasFocus(); + } + return false; + } + + /** + * Hides any open pop-ups. + * + * @since 3.0 + */ + protected void hide() { + if (fProposalPopup !is null) + fProposalPopup.hide(); + + if (fContextInfoPopup !is null) + fContextInfoPopup.hide(); + } + package void hide_package() { + hide(); + } + + // ------ control's size handling dialog settings ------ + + /** + * Tells this information control manager to open the information control with the values + * contained in the given dialog settings and to store the control's last valid size in the + * given dialog settings. + *

                + * Note: This API is only valid if the information control implements + * {@link dwtx.jface.text.IInformationControlExtension3}. Not following this restriction + * will later result in an {@link UnsupportedOperationException}. + *

                + *

                + * The constants used to store the values are: + *

                  + *
                • {@link ContentAssistant#STORE_SIZE_X}
                • + *
                • {@link ContentAssistant#STORE_SIZE_Y}
                • + *
                + *

                + * + * @param dialogSettings + * @since 3.0 + */ + public void setRestoreCompletionProposalSize(IDialogSettings dialogSettings) { + Assert.isTrue(dialogSettings !is null); + fDialogSettings= dialogSettings; + } + + /** + * Stores the content assist pop-up's size. + */ + protected void storeCompletionProposalPopupSize() { + if (fDialogSettings is null || fProposalPopup is null) + return; + + Point size= fProposalPopup.getSize(); + if (size is null) + return; + + fDialogSettings.put(STORE_SIZE_X, size.x); + fDialogSettings.put(STORE_SIZE_Y, size.y); + } + + /** + * Restores the content assist pop-up's size. + * + * @return the stored size + * @since 3.0 + */ + protected Point restoreCompletionProposalPopupSize() { + if (fDialogSettings is null) + return null; + + Point size= new Point(-1, -1); + + try { + size.x= fDialogSettings.getInt(STORE_SIZE_X); + size.y= fDialogSettings.getInt(STORE_SIZE_Y); + } catch (NumberFormatException ex) { + size.x= -1; + size.y= -1; + } + + // sanity check + if (size.x is -1 && size.y is -1) + return null; + + Rectangle maxBounds= null; + if (fContentAssistSubjectControl !is null && Helper.okToUse(fContentAssistSubjectControl.getControl())) + maxBounds= fContentAssistSubjectControl.getControl().getDisplay().getBounds(); + else { + // fallback + Display display= Display.getCurrent(); + if (display is null) + display= Display.getDefault(); + if (display !is null && !display.isDisposed()) + maxBounds= display.getBounds(); + } + + if (size.x > -1 && size.y > -1) { + if (maxBounds !is null) { + size.x= Math.min(size.x, maxBounds.width); + size.y= Math.min(size.y, maxBounds.height); + } + + // Enforce an absolute minimal size + size.x= Math.max(size.x, 30); + size.y= Math.max(size.y, 30); + } + + return size; + } + package Point restoreCompletionProposalPopupSize_package() { + return restoreCompletionProposalPopupSize(); + } + + /** + * Sets the prefix completion property. If enabled, content assist delegates completion to + * prefix completion. + * + * @param enabled true to enable prefix completion, false to + * disable + */ + public void enablePrefixCompletion(bool enabled) { + fIsPrefixCompletionEnabled= enabled; + } + + /** + * Returns the prefix completion state. + * + * @return true if prefix completion is enabled, false otherwise + * @since 3.2 + */ + bool isPrefixCompletionEnabled() { + return fIsPrefixCompletionEnabled; + } + + /** + * Returns whether the content assistant proposal popup has the focus. + * + * @return true if the proposal popup has the focus + * @since 3.0 + */ + public bool hasProposalPopupFocus() { + return fProposalPopup.hasFocus(); + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistantExtension2#addCompletionListener(dwtx.jface.text.contentassist.ICompletionListener) + * @since 3.2 + */ + public void addCompletionListener(ICompletionListener listener) { + Assert.isLegal(listener !is null); + fCompletionListeners.add(listener); + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistantExtension2#removeCompletionListener(dwtx.jface.text.contentassist.ICompletionListener) + * @since 3.2 + */ + public void removeCompletionListener(ICompletionListener listener) { + fCompletionListeners.remove(listener); + } + + /** + * Fires a session begin event to all registered {@link ICompletionListener}s. + * + * @param isAutoActivated true if this session was triggered by auto activation + * @since 3.2 + */ + void fireSessionBeginEvent(bool isAutoActivated) { + if (fContentAssistSubjectControlAdapter !is null && !isProposalPopupActive()) { + IContentAssistProcessor processor= getProcessor(fContentAssistSubjectControlAdapter, fContentAssistSubjectControlAdapter.getSelectedRange().x); + ContentAssistEvent event= new ContentAssistEvent(this, processor, isAutoActivated); + Object[] listeners= fCompletionListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) { + ICompletionListener listener= cast(ICompletionListener)listeners[i]; + listener.assistSessionStarted(event); + } + } + } + + /** + * Fires a session restart event to all registered {@link ICompletionListener}s. + * + * @since 3.4 + */ + void fireSessionRestartEvent() { + if (fContentAssistSubjectControlAdapter !is null) { + IContentAssistProcessor processor= getProcessor(fContentAssistSubjectControlAdapter, fContentAssistSubjectControlAdapter.getSelectedRange().x); + ContentAssistEvent event= new ContentAssistEvent(this, processor); + Object[] listeners= fCompletionListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) { + ICompletionListener listener= cast(ICompletionListener)listeners[i]; + if ( cast(ICompletionListenerExtension)listener ) + (cast(ICompletionListenerExtension)listener).assistSessionRestarted(event); + } + } + } + + /** + * Fires a session end event to all registered {@link ICompletionListener}s. + * + * @since 3.2 + */ + void fireSessionEndEvent() { + if (fContentAssistSubjectControlAdapter !is null) { + IContentAssistProcessor processor= getProcessor(fContentAssistSubjectControlAdapter, fContentAssistSubjectControlAdapter.getSelectedRange().x); + ContentAssistEvent event= new ContentAssistEvent(this, processor); + Object[] listeners= fCompletionListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) { + ICompletionListener listener= cast(ICompletionListener)listeners[i]; + listener.assistSessionEnded(event); + } + } + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistantExtension2#setRepeatedInvocationMode(bool) + * @since 3.2 + */ + public void setRepeatedInvocationMode(bool cycling) { + fIsRepetitionMode= cycling; + } + + /** + * Returns true if repeated invocation mode is enabled, false + * otherwise. + * + * @return true if repeated invocation mode is enabled, false + * otherwise + * @since 3.2 + */ + bool isRepeatedInvocationMode() { + return fIsRepetitionMode; + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistantExtension2#setShowEmptyList(bool) + * @since 3.2 + */ + public void setShowEmptyList(bool showEmpty) { + fShowEmptyList= showEmpty; + } + + /** + * Returns true if empty lists should be displayed, false + * otherwise. + * + * @return true if empty lists should be displayed, false + * otherwise + * @since 3.2 + */ + bool isShowEmptyList() { + return fShowEmptyList; + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistantExtension2#setStatusLineVisible(bool) + * @since 3.2 + */ + public void setStatusLineVisible(bool show) { + fIsStatusLineVisible= show; + if (fProposalPopup !is null) + fProposalPopup.setStatusLineVisible(show); + } + + /** + * Returns true if a message line should be displayed, false + * otherwise. + * + * @return true if a message line should be displayed, false + * otherwise + * @since 3.2 + */ + bool isStatusLineVisible() { + return fIsStatusLineVisible; + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistantExtension2#setStatusMessage(java.lang.String) + * @since 3.2 + */ + public void setStatusMessage(String message) { + Assert.isLegal(message !is null); + fMessage= message; + if (fProposalPopup !is null) + fProposalPopup.setMessage(message); + } + + /** + * Returns the affordance caption for the cycling affordance at the bottom of the pop-up. + * + * @return the affordance caption for the cycling affordance at the bottom of the pop-up + * @since 3.2 + */ + String getStatusMessage() { + return fMessage; + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistantExtension2#setEmptyMessage(java.lang.String) + * @since 3.2 + */ + public void setEmptyMessage(String message) { + Assert.isLegal(message !is null); + if (fProposalPopup !is null) + fProposalPopup.setEmptyMessage(message); + } + + /** + * Fires a selection event, see {@link ICompletionListener}. + * + * @param proposal the selected proposal, possibly null + * @param smartToggle true if the smart toggle is on + * @since 3.2 + */ + void fireSelectionEvent(ICompletionProposal proposal, bool smartToggle) { + Object[] listeners= fCompletionListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) { + ICompletionListener listener= cast(ICompletionListener)listeners[i]; + listener.selectionChanged(proposal, smartToggle); + } + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistantExtension3#setInvocationTrigger(dwtx.jface.bindings.keys.KeySequence) + * @since 3.2 + */ + public void setRepeatedInvocationTrigger(KeySequence sequence) { + fRepeatedInvocationKeySequence= sequence; + } + + /** + * Returns the repeated invocation key sequence. + * + * @return the repeated invocation key sequence or null, if none + * @since 3.2 + */ + KeySequence getRepeatedInvocationKeySequence() { + return fRepeatedInvocationKeySequence; + } + + /** + * Returns whether proposal popup is active. + * + * @return true if the proposal popup is active, false otherwise + * @since 3.4 + */ + protected bool isProposalPopupActive(){ + return fProposalPopup !is null && fProposalPopup.isActive(); + } + + /** + * Returns whether the context information popup is active. + * + * @return true if the context information popup is active, false otherwise + * @since 3.4 + */ + protected bool isContextInfoPopupActive(){ + return fContextInfoPopup !is null && fContextInfoPopup.isActive(); + } + + /** + * {@inheritDoc} + * + * @since 3.4 + */ + public final IHandler getHandler(String commandId) { + if (fHandlers is null) + throw new IllegalStateException(); + + IHandler handler= cast(IHandler)fHandlers.get(commandId); + if (handler !is null) + return handler; + + Assert.isLegal(false); + return null; + } + + /** + * Registers the given handler under the given command identifier. + * + * @param commandId the command identifier + * @param handler the handler + * @since 3.4 + */ + protected final void registerHandler(String commandId, IHandler handler) { + if (fHandlers is null) + fHandlers= new HashMap(2); + fHandlers.put(commandId, handler); + } + + /** + * Tells whether the support for colored labels is enabled. + * + * @return true if the support for colored labels is enabled, false otherwise + * @since 3.4 + */ + bool isColoredLabelsSupportEnabled() { + return fIsColoredLabelsSupportEnabled; + } + + /** + * Enables the support for colored labels in the proposal popup. + *

                Completion proposals can implement {@link ICompletionProposalExtension6} + * to provide colored proposal labels.

                + * + * @param isEnabled if true the support for colored labels is enabled in the proposal popup + * @since 3.4 + */ + public void enableColoredLabels(bool isEnabled) { + fIsColoredLabelsSupportEnabled= isEnabled; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/ContextInformation.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/ContextInformation.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,141 @@ +/******************************************************************************* + * 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 + * 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.text.contentassist.ContextInformation; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + + + +import dwt.graphics.Image; +import dwtx.core.runtime.Assert; + + + +/** + * A default implementation of the IContextInformation interface. + */ +public final class ContextInformation : IContextInformation { + + /** The name of the context. */ + private const String fContextDisplayString; + /** The information to be displayed. */ + private const String fInformationDisplayString; + /** The image to be displayed. */ + private const Image fImage; + + /** + * Creates a new context information without an image. + * + * @param contextDisplayString the string to be used when presenting the context + * @param informationDisplayString the string to be displayed when presenting the context information + */ + public this(String contextDisplayString, String informationDisplayString) { + this(null, contextDisplayString, informationDisplayString); + } + + /** + * Creates a new context information with an image. + * + * @param image the image to display when presenting the context information + * @param contextDisplayString the string to be used when presenting the context + * @param informationDisplayString the string to be displayed when presenting the context information, + * may not be null + */ + public this(Image image, String contextDisplayString, String informationDisplayString) { + + Assert.isNotNull(informationDisplayString); + + fImage= image; + fContextDisplayString= contextDisplayString; + fInformationDisplayString= informationDisplayString; + } + + /* + * @see IContextInformation#equals(Object) + */ + public bool equals(Object object) { + if ( cast(IContextInformation)object ) { + IContextInformation contextInformation= cast(IContextInformation) object; + bool equals= fInformationDisplayString.equalsIgnoreCase(contextInformation.getInformationDisplayString()); + if (fContextDisplayString !is null) + equals= equals && fContextDisplayString.equalsIgnoreCase(contextInformation.getContextDisplayString()); + return equals; + } + return false; + } + + /* + * @see java.lang.Object#hashCode() + * @since 3.1 + */ + public override hash_t toHash() { + int low= fContextDisplayString !is null ? .toHash(fContextDisplayString) : 0; + return (.toHash(fInformationDisplayString) << 16) | low; + } + + /* + * @see IContextInformation#getInformationDisplayString() + */ + public String getInformationDisplayString() { + return fInformationDisplayString; + } + + /* + * @see IContextInformation#getImage() + */ + public Image getImage() { + return fImage; + } + + /* + * @see IContextInformation#getContextDisplayString() + */ + public String getContextDisplayString() { + if (fContextDisplayString !is null) + return fContextDisplayString; + return fInformationDisplayString; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/ContextInformationPopup.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/ContextInformationPopup.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,886 @@ +/******************************************************************************* + * 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 + * 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.text.contentassist.ContextInformationPopup; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + +import dwt.DWT; +import dwt.custom.BusyIndicator; +import dwt.custom.StyledText; +import dwt.events.KeyEvent; +import dwt.events.SelectionAdapter; +import dwt.events.SelectionEvent; +import dwt.events.SelectionListener; +import dwt.events.VerifyEvent; +import dwt.graphics.Color; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.layout.GridData; +import dwt.layout.GridLayout; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Shell; +import dwt.widgets.Table; +import dwt.widgets.TableItem; +import dwtx.jface.contentassist.IContentAssistSubjectControl; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.TextPresentation; + + /** + * Represents the state necessary for embedding contexts. + * + * @since 2.0 + */ + static class ContextFrame { + + final int fBeginOffset; + final int fOffset; + final int fVisibleOffset; + final IContextInformation fInformation; + final IContextInformationValidator fValidator; + final IContextInformationPresenter fPresenter; + + /* + * @since 3.1 + */ + public this(IContextInformation information, int beginOffset, int offset, int visibleOffset, IContextInformationValidator validator, IContextInformationPresenter presenter) { + fInformation = information; + fBeginOffset = beginOffset; + fOffset = offset; + fVisibleOffset = visibleOffset; + fValidator = validator; + fPresenter = presenter; + } + + /* + * @see java.lang.Object#equals(java.lang.Object) + * @since 3.0 + */ + public override int opEquals(Object obj) { + if ( cast(ContextFrame)obj ) { + ContextFrame frame= cast(ContextFrame) obj; + return fInformation==/++/frame.fInformation && fBeginOffset is frame.fBeginOffset; + } + return super.opEquals(obj); + } + + /* + * @see java.lang.Object#hashCode() + * @since 3.1 + */ + public override hash_t toHash() { + return ((cast(Object)fInformation).toHash() << 16) | fBeginOffset; + } + } + + alias ContextFrame ContextInformationPopup_ContextFrame; +/** + * This class is used to present context information to the user. + * If multiple contexts are valid at the current cursor location, + * a list is presented from which the user may choose one context. + * Once the user makes their choice, or if there was only a single + * possible context, the context information is shown in a tool tip like popup.

                + * If the tool tip is visible and the user wants to see context information of + * a context embedded into the one for which context information is displayed, + * context information for the embedded context is shown. As soon as the + * cursor leaves the embedded context area, the context information for + * the embedding context is shown again. + * + * @see IContextInformation + * @see IContextInformationValidator + */ +class ContextInformationPopup : IContentAssistListener { + + + + private ITextViewer fViewer; + private ContentAssistant fContentAssistant; + + private PopupCloser fPopupCloser; + private Shell fContextSelectorShell; + private Table fContextSelectorTable; + private IContextInformation[] fContextSelectorInput; + private String fLineDelimiter= null; + + private Shell fContextInfoPopup; + private StyledText fContextInfoText; + private TextPresentation fTextPresentation; + + private Stack fContextFrameStack; + /** + * The content assist subject control. + * + * @since 3.0 + */ + private IContentAssistSubjectControl fContentAssistSubjectControl; + /** + * The content assist subject control adapter. + * + * @since 3.0 + */ + private ContentAssistSubjectControlAdapter fContentAssistSubjectControlAdapter; + + /** + * Selection listener on the text widget which is active + * while a context information pop up is shown. + * + * @since 3.0 + */ + private SelectionListener fTextWidgetSelectionListener; + + /** + * The last removed context frame is remembered in order to not re-query the + * user about which context should be used. + * + * @since 3.0 + */ + private ContextFrame fLastContext= null; + + /** + * Creates a new context information popup. + * + * @param contentAssistant the content assist for computing the context information + * @param viewer the viewer on top of which the context information is shown + */ + public this(ContentAssistant contentAssistant, ITextViewer viewer) { + fPopupCloser= new PopupCloser(); + fContextFrameStack= new Stack(); + + fContentAssistant= contentAssistant; + fViewer= viewer; + fContentAssistSubjectControlAdapter= new ContentAssistSubjectControlAdapter(fViewer); + } + + /** + * Creates a new context information popup. + * + * @param contentAssistant the content assist for computing the context information + * @param contentAssistSubjectControl the content assist subject control on top of which the context information is shown + * @since 3.0 + */ + public this(ContentAssistant contentAssistant, IContentAssistSubjectControl contentAssistSubjectControl) { + fPopupCloser= new PopupCloser(); + fContextFrameStack= new Stack(); + + fContentAssistant= contentAssistant; + fContentAssistSubjectControl= contentAssistSubjectControl; + fContentAssistSubjectControlAdapter= new ContentAssistSubjectControlAdapter(fContentAssistSubjectControl); + } + + /** + * Shows all possible contexts for the given cursor position of the viewer. + * + * @param autoActivated true if auto activated + * @return a potential error message or null in case of no error + */ + public String showContextProposals(bool autoActivated) { + final Control control= fContentAssistSubjectControlAdapter.getControl(); + BusyIndicator.showWhile(control.getDisplay(), dgRunnable( { + int offset= fContentAssistSubjectControlAdapter.getSelectedRange().x; + + IContextInformation[] contexts= computeContextInformation(offset); + int count = (contexts is null ? 0 : contexts.length); + if (count is 1) { + + ContextFrame frame= createContextFrame(contexts[0], offset); + if (isDuplicate(frame)) + validateContextInformation(); + else + // Show context information directly + internalShowContextInfo(frame); + + } else if (count > 0) { + + // if any of the proposed context matches any of the contexts on the stack, + // assume that one (so, if context info is invoked repeatedly, the current + // info is kept) + for (int i= 0; i < contexts.length; i++) { + IContextInformation info= contexts[i]; + ContextFrame frame= createContextFrame(info, offset); + + // check top of stack and stored context + if (isDuplicate(frame)) { + validateContextInformation(); + return; + } + + if (isLastFrame(frame)) { + internalShowContextInfo(frame); + return; + } + + // also check all other contexts + for (Iterator it= fContextFrameStack.iterator(); it.hasNext(); ) { + ContextFrame stackFrame= cast(ContextFrame) it.next(); + if (stackFrame==/++/frame) { + validateContextInformation(); + return; + } + } + } + + // otherwise: + // Precise context must be selected + + if (fLineDelimiter is null) + fLineDelimiter= fContentAssistSubjectControlAdapter.getLineDelimiter(); + + createContextSelector(); + setContexts(contexts); + displayContextSelector(); + } + })); + + return getErrorMessage(); + } + + /** + * Displays the given context information for the given offset. + * + * @param info the context information + * @param offset the offset + * @since 2.0 + */ + public void showContextInformation(IContextInformation info, int offset) { + Control control= fContentAssistSubjectControlAdapter.getControl(); + BusyIndicator.showWhile(control.getDisplay(), dgRunnable( (IContextInformation info_, int offset_){ + if (info_ is null) + validateContextInformation(); + else { + ContextFrame frame= createContextFrame(info_, offset_); + if (isDuplicate(frame)) + validateContextInformation(); + else + internalShowContextInfo(frame); + hideContextSelector(); + } + }, info, offset )); + } + + /** + * Displays the given context information for the given offset. + * + * @param frame the context frame to display, or null + * @since 3.0 + */ + private void internalShowContextInfo(ContextFrame frame) { + if (frame !is null) { + fContextFrameStack.push(frame); + if (fContextFrameStack.size() is 1) + fLastContext= null; + internalShowContextFrame(frame, fContextFrameStack.size() is 1); + validateContextInformation(); + } + } + + /** + * Creates a context frame for the given offset. + * + * @param information the context information + * @param offset the offset + * @return the created context frame + * @since 3.0 + */ + private ContextFrame createContextFrame(IContextInformation information, int offset) { + IContextInformationValidator validator= fContentAssistSubjectControlAdapter.getContextInformationValidator(fContentAssistant, offset); + + if (validator !is null) { + int beginOffset= ( cast(IContextInformationExtension)information ) ? (cast(IContextInformationExtension) information).getContextInformationPosition() : offset; + if (beginOffset is -1) beginOffset= offset; + int visibleOffset= fContentAssistSubjectControlAdapter.getWidgetSelectionRange().x - (offset - beginOffset); + IContextInformationPresenter presenter = fContentAssistSubjectControlAdapter.getContextInformationPresenter(fContentAssistant, offset); + return new ContextFrame(information, beginOffset, offset, visibleOffset, validator, presenter); + } + + return null; + } + + /** + * Compares frame with the top of the stack, returns true + * if the frames are the same. + * + * @param frame the frame to check + * @return true if frame matches the top of the stack + * @since 3.0 + */ + private bool isDuplicate(ContextFrame frame) { + if (frame is null) + return false; + if (fContextFrameStack.isEmpty()) + return false; + // stack not empty + ContextFrame top= cast(ContextFrame) fContextFrameStack.peek(); + return cast(bool) frame.opEquals(top); + } + + /** + * Compares frame with most recently removed context frame, returns true + * if the frames are the same. + * + * @param frame the frame to check + * @return true if frame matches the most recently removed + * @since 3.0 + */ + private bool isLastFrame(ContextFrame frame) { + return frame !is null && frame.opEquals(fLastContext); + } + + /** + * Shows the given context frame. + * + * @param frame the frame to display + * @param initial true if this is the first frame to be displayed + * @since 2.0 + */ + private void internalShowContextFrame(ContextFrame frame, bool initial) { + + fContentAssistSubjectControlAdapter.installValidator(frame); + + if (frame.fPresenter !is null) { + if (fTextPresentation is null) + fTextPresentation= new TextPresentation(); + fContentAssistSubjectControlAdapter.installContextInformationPresenter(frame); + frame.fPresenter.updatePresentation(frame.fOffset, fTextPresentation); + } + + createContextInfoPopup(); + + fContextInfoText.setText(frame.fInformation.getInformationDisplayString()); + if (fTextPresentation !is null) + TextPresentation.applyTextPresentation(fTextPresentation, fContextInfoText); + resize(frame.fVisibleOffset); + + if (initial) { + if (fContentAssistant.addContentAssistListener(this, ContentAssistant.CONTEXT_INFO_POPUP)) { + if (fContentAssistSubjectControlAdapter.getControl() !is null) { + fTextWidgetSelectionListener= new class() SelectionAdapter { + /* + * @see dwt.events.SelectionAdapter#widgetSelected(dwt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + validateContextInformation(); + }}; + fContentAssistSubjectControlAdapter.addSelectionListener(fTextWidgetSelectionListener); + } + fContentAssistant.addToLayout(this, fContextInfoPopup, ContentAssistant.LayoutManager.LAYOUT_CONTEXT_INFO_POPUP, frame.fVisibleOffset); + fContextInfoPopup.setVisible(true); + } + } else { + fContentAssistant.layout(ContentAssistant.LayoutManager.LAYOUT_CONTEXT_INFO_POPUP, frame.fVisibleOffset); + } + } + + /** + * Computes all possible context information for the given offset. + * + * @param offset the offset + * @return all possible context information for the given offset + * @since 2.0 + */ + private IContextInformation[] computeContextInformation(int offset) { + return fContentAssistSubjectControlAdapter.computeContextInformation(fContentAssistant, offset); + } + + /** + *Returns the error message generated while computing context information. + * + * @return the error message + */ + private String getErrorMessage() { + return fContentAssistant.getErrorMessage(); + } + + /** + * Creates the context information popup. This is the tool tip like overlay window. + */ + private void createContextInfoPopup() { + if (Helper.okToUse(fContextInfoPopup)) + return; + + Control control= fContentAssistSubjectControlAdapter.getControl(); + Display display= control.getDisplay(); + + fContextInfoPopup= new Shell(control.getShell(), DWT.NO_TRIM | DWT.ON_TOP); + fContextInfoPopup.setBackground(display.getSystemColor(DWT.COLOR_BLACK)); + + fContextInfoText= new StyledText(fContextInfoPopup, DWT.MULTI | DWT.READ_ONLY | DWT.WRAP); + + Color c= fContentAssistant.getContextInformationPopupBackground(); + if (c is null) + c= display.getSystemColor(DWT.COLOR_INFO_BACKGROUND); + fContextInfoText.setBackground(c); + + c= fContentAssistant.getContextInformationPopupForeground(); + if (c is null) + c= display.getSystemColor(DWT.COLOR_INFO_FOREGROUND); + fContextInfoText.setForeground(c); + } + + /** + * Resizes the context information popup. + * + * @param offset the caret offset in widget coordinates + * @since 2.0 + */ + private void resize(int offset) { + Point size= fContextInfoText.computeSize(DWT.DEFAULT, DWT.DEFAULT, true); + final int TEXT_PAD= 0; + final int BORDER_PAD= 2; + final int PAD= TEXT_PAD + BORDER_PAD; + size.x += PAD; + Rectangle bounds= fContentAssistant.getLayoutManager().computeBoundsAboveBelow_package(fContextInfoPopup, size, offset); + if (bounds.width < size.x) + // we don't fit on the screen - try again and wrap + size= fContextInfoText.computeSize(bounds.width - PAD, DWT.DEFAULT, true); + + size.x += TEXT_PAD; + fContextInfoText.setSize(size); + fContextInfoText.setLocation(1,1); + size.x += BORDER_PAD; + size.y += BORDER_PAD; + fContextInfoPopup.setSize(size); + } + + /** + * Hides the context information popup. + */ + private void hideContextInfoPopup() { + + if (Helper.okToUse(fContextInfoPopup)) { + + int size= fContextFrameStack.size(); + if (size > 0) { + fLastContext= cast(ContextFrame) fContextFrameStack.pop(); + -- size; + } + + if (size > 0) { + ContextFrame current= cast(ContextFrame) fContextFrameStack.peek(); + internalShowContextFrame(current, false); + } else { + + fContentAssistant.removeContentAssistListener(this, ContentAssistant.CONTEXT_INFO_POPUP); + + if (fContentAssistSubjectControlAdapter.getControl() !is null) + fContentAssistSubjectControlAdapter.removeSelectionListener(fTextWidgetSelectionListener); + fTextWidgetSelectionListener= null; + + fContextInfoPopup.setVisible(false); + fContextInfoPopup.dispose(); + fContextInfoPopup= null; + + if (fTextPresentation !is null) { + fTextPresentation.clear(); + fTextPresentation= null; + } + } + } + + if (fContextInfoPopup is null) + fContentAssistant.contextInformationClosed_package(); + } + + /** + * Creates the context selector in case the user has the choice between multiple valid contexts + * at a given offset. + */ + private void createContextSelector() { + if (Helper.okToUse(fContextSelectorShell)) + return; + + Control control= fContentAssistSubjectControlAdapter.getControl(); + fContextSelectorShell= new Shell(control.getShell(), DWT.ON_TOP | DWT.RESIZE); + GridLayout layout= new GridLayout(); + layout.marginWidth= 0; + layout.marginHeight= 0; + fContextSelectorShell.setLayout(layout); + fContextSelectorShell.setBackground(control.getDisplay().getSystemColor(DWT.COLOR_BLACK)); + + + fContextSelectorTable= new Table(fContextSelectorShell, DWT.H_SCROLL | DWT.V_SCROLL); + fContextSelectorTable.setLocation(1, 1); + GridData gd= new GridData(GridData.FILL_BOTH); + gd.heightHint= fContextSelectorTable.getItemHeight() * 10; + gd.widthHint= 300; + fContextSelectorTable.setLayoutData(gd); + + fContextSelectorShell.pack(true); + + Color c= fContentAssistant.getContextSelectorBackground(); + if (c is null) + c= control.getDisplay().getSystemColor(DWT.COLOR_INFO_BACKGROUND); + fContextSelectorTable.setBackground(c); + + c= fContentAssistant.getContextSelectorForeground(); + if (c is null) + c= control.getDisplay().getSystemColor(DWT.COLOR_INFO_FOREGROUND); + fContextSelectorTable.setForeground(c); + + fContextSelectorTable.addSelectionListener(new class() SelectionListener { + public void widgetSelected(SelectionEvent e) { + } + + public void widgetDefaultSelected(SelectionEvent e) { + insertSelectedContext(); + hideContextSelector(); + } + }); + + fPopupCloser.install(fContentAssistant, fContextSelectorTable); + + fContextSelectorTable.setHeaderVisible(false); + fContentAssistant.addToLayout(this, fContextSelectorShell, ContentAssistant.LayoutManager.LAYOUT_CONTEXT_SELECTOR, fContentAssistant.getSelectionOffset()); + } + + /** + * Returns the minimal required height for the popup, may return 0 if the popup has not been + * created yet. + * + * @return the minimal height + * @since 3.3 + */ + int getMinimalHeight() { + int height= 0; + if (Helper.okToUse(fContextSelectorTable)) { + int items= fContextSelectorTable.getItemHeight() * 10; + Rectangle trim= fContextSelectorTable.computeTrim(0, 0, DWT.DEFAULT, items); + height= trim.height; + } + return height; + } + + /** + * Causes the context information of the context selected in the context selector + * to be displayed in the context information popup. + */ + private void insertSelectedContext() { + int i= fContextSelectorTable.getSelectionIndex(); + + if (i < 0 || i >= fContextSelectorInput.length) + return; + + int offset= fContentAssistSubjectControlAdapter.getSelectedRange().x; + internalShowContextInfo(createContextFrame(fContextSelectorInput[i], offset)); + } + + /** + * Sets the contexts in the context selector to the given set. + * + * @param contexts the possible contexts + */ + private void setContexts(IContextInformation[] contexts) { + if (Helper.okToUse(fContextSelectorTable)) { + + fContextSelectorInput= contexts; + + fContextSelectorTable.setRedraw(false); + fContextSelectorTable.removeAll(); + + TableItem item; + IContextInformation t; + for (int i= 0; i < contexts.length; i++) { + t= contexts[i]; + item= new TableItem(fContextSelectorTable, DWT.NULL); + if (t.getImage() !is null) + item.setImage(t.getImage()); + item.setText(t.getContextDisplayString()); + } + + fContextSelectorTable.select(0); + fContextSelectorTable.setRedraw(true); + } + } + + /** + * Displays the context selector. + */ + private void displayContextSelector() { + if (fContentAssistant.addContentAssistListener(this, ContentAssistant.CONTEXT_SELECTOR)) + fContextSelectorShell.setVisible(true); + } + + /** + * Hides the context selector. + */ + private void hideContextSelector() { + if (Helper.okToUse(fContextSelectorShell)) { + fContentAssistant.removeContentAssistListener(this, ContentAssistant.CONTEXT_SELECTOR); + + fPopupCloser.uninstall(); + fContextSelectorShell.setVisible(false); + fContextSelectorShell.dispose(); + fContextSelectorShell= null; + } + + if (!Helper.okToUse(fContextInfoPopup)) + fContentAssistant.contextInformationClosed_package(); + } + + /** + *Returns whether the context selector has the focus. + * + * @return true if the context selector has the focus + */ + public bool hasFocus() { + if (Helper.okToUse(fContextSelectorShell)) + return (fContextSelectorShell.isFocusControl() || fContextSelectorTable.isFocusControl()); + + return false; + } + + /** + * Hides context selector and context information popup. + */ + public void hide() { + hideContextSelector(); + hideContextInfoPopup(); + } + + /** + * Returns whether this context information popup is active. I.e., either + * a context selector or context information is displayed. + * + * @return true if the context selector is active + */ + public bool isActive() { + return (Helper.okToUse(fContextInfoPopup) || Helper.okToUse(fContextSelectorShell)); + } + + /* + * @see IContentAssistListener#verifyKey(VerifyEvent) + */ + public bool verifyKey(VerifyEvent e) { + if (Helper.okToUse(fContextSelectorShell)) + return contextSelectorKeyPressed(e); + if (Helper.okToUse(fContextInfoPopup)) + return contextInfoPopupKeyPressed(e); + return true; + } + + /** + * Processes a key stroke in the context selector. + * + * @param e the verify event describing the key stroke + * @return true if processing can be stopped + */ + private bool contextSelectorKeyPressed(VerifyEvent e) { + + char key= e.character; + if (key is 0) { + + int newSelection= fContextSelectorTable.getSelectionIndex(); + int visibleRows= (fContextSelectorTable.getSize().y / fContextSelectorTable.getItemHeight()) - 1; + int itemCount= fContextSelectorTable.getItemCount(); + switch (e.keyCode) { + case DWT.ARROW_UP : + newSelection -= 1; + if (newSelection < 0) + newSelection= itemCount - 1; + break; + + case DWT.ARROW_DOWN : + newSelection += 1; + if (newSelection > itemCount - 1) + newSelection= 0; + break; + + case DWT.PAGE_DOWN : + newSelection += visibleRows; + if (newSelection >= itemCount) + newSelection= itemCount - 1; + break; + + case DWT.PAGE_UP : + newSelection -= visibleRows; + if (newSelection < 0) + newSelection= 0; + break; + + case DWT.HOME : + newSelection= 0; + break; + + case DWT.END : + newSelection= itemCount - 1; + break; + + default : + if (e.keyCode !is DWT.CAPS_LOCK && e.keyCode !is DWT.MOD1 && e.keyCode !is DWT.MOD2 && e.keyCode !is DWT.MOD3 && e.keyCode !is DWT.MOD4) + hideContextSelector(); + return true; + } + + fContextSelectorTable.setSelection(newSelection); + fContextSelectorTable.showSelection(); + e.doit= false; + return false; + + } else if ('\t' is key) { + // switch focus to selector shell + e.doit= false; + fContextSelectorShell.setFocus(); + return false; + } else if (key is DWT.ESC) { + e.doit= false; + hideContextSelector(); + } + + return true; + } + + /** + * Processes a key stroke while the info popup is up. + * + * @param e the verify event describing the key stroke + * @return true if processing can be stopped + */ + private bool contextInfoPopupKeyPressed(KeyEvent e) { + + char key= e.character; + if (key is 0) { + + switch (e.keyCode) { + case DWT.ARROW_LEFT: + case DWT.ARROW_RIGHT: + validateContextInformation(); + break; + default: + if (e.keyCode !is DWT.CAPS_LOCK && e.keyCode !is DWT.MOD1 && e.keyCode !is DWT.MOD2 && e.keyCode !is DWT.MOD3 && e.keyCode !is DWT.MOD4) + hideContextInfoPopup(); + break; + } + + } else if (key is DWT.ESC) { + e.doit= false; + hideContextInfoPopup(); + } else { + validateContextInformation(); + } + return true; + } + + /* + * @see IEventConsumer#processEvent(VerifyEvent) + */ + public void processEvent(VerifyEvent event) { + if (Helper.okToUse(fContextSelectorShell)) + contextSelectorProcessEvent(event); + if (Helper.okToUse(fContextInfoPopup)) + contextInfoPopupProcessEvent(event); + } + + /** + * Processes a key stroke in the context selector. + * + * @param e the verify event describing the key stroke + */ + private void contextSelectorProcessEvent(VerifyEvent e) { + + if (e.start is e.end && e.text !is null && e.text.equals(fLineDelimiter)) { + e.doit= false; + insertSelectedContext(); + } + + hideContextSelector(); + } + + /** + * Processes a key stroke while the info popup is up. + * + * @param e the verify event describing the key stroke + */ + private void contextInfoPopupProcessEvent(VerifyEvent e) { + if (e.start !is e.end && (e.text is null || e.text.length() is 0)) + validateContextInformation(); + } + + /** + * Validates the context information for the viewer's actual cursor position. + */ + private void validateContextInformation() { + /* + * Post the code in the event queue in order to ensure that the + * action described by this verify key event has already been executed. + * Otherwise, we'd validate the context information based on the + * pre-key-stroke state. + */ + if (!Helper.okToUse(fContextInfoPopup)) + return; + + fContextInfoPopup.getDisplay().asyncExec(new class() Runnable { + + private ContextFrame fFrame; + + this() { + fFrame= cast(ContextFrame) fContextFrameStack.peek(); + } + + public void run() { + // only do this if no other frames have been added in between + if (!fContextFrameStack.isEmpty() && fFrame is fContextFrameStack.peek()) { + int offset= fContentAssistSubjectControlAdapter.getSelectedRange().x; + + // iterate all contexts on the stack + while (Helper.okToUse(fContextInfoPopup) && !fContextFrameStack.isEmpty()) { + ContextFrame top= cast(ContextFrame) fContextFrameStack.peek(); + if (top.fValidator is null || !top.fValidator.isContextInformationValid(offset)) { + hideContextInfoPopup(); // loop variant: reduces the number of contexts on the stack + } else if (top.fPresenter !is null && top.fPresenter.updatePresentation(offset, fTextPresentation)) { + int widgetOffset= fContentAssistSubjectControlAdapter.getWidgetSelectionRange().x; + TextPresentation.applyTextPresentation(fTextPresentation, fContextInfoText); + resize(widgetOffset); + break; + } else + break; + } + } + } + }); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/ContextInformationValidator.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/ContextInformationValidator.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.contentassist.ContextInformationValidator; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.ITextViewer; + + +/** + * A default implementation of the IContextInfomationValidator interface. + * This implementation determines whether the information is valid by asking the content + * assist processor for all context information objects for the current position. If the + * currently displayed information is in the result set, the context information is + * considered valid. + */ +public final class ContextInformationValidator : IContextInformationValidator { + + /** The content assist processor. */ + private IContentAssistProcessor fProcessor; + /** The context information to be validated. */ + private IContextInformation fContextInformation; + /** The associated text viewer. */ + private ITextViewer fViewer; + + /** + * Creates a new context information validator which is ready to be installed on + * a particular context information. + * + * @param processor the processor to be used for validation + */ + public this(IContentAssistProcessor processor) { + fProcessor= processor; + } + + /* + * @see IContextInformationValidator#install(IContextInformation, ITextViewer, int) + */ + public void install(IContextInformation contextInformation, ITextViewer viewer, int offset) { + fContextInformation= contextInformation; + fViewer= viewer; + } + + /* + * @see IContentAssistTipCloser#isContextInformationValid(int) + */ + public bool isContextInformationValid(int offset) { + IContextInformation[] infos= fProcessor.computeContextInformation(fViewer, offset); + if (infos !is null && infos.length > 0) { + for (int i= 0; i < infos.length; i++) + if (fContextInformation==/+eq+/infos[i]) + return true; + } + return false; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/Helper.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/Helper.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.contentassist.Helper; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.widgets.Widget; + + +/** + * Helper class for testing widget state. + */ +class Helper { + + /** + * Returns whether the widget is null or disposed. + * + * @param widget the widget to check + * @return true if the widget is neither null nor disposed + */ + public static bool okToUse(Widget widget) { + return (widget !is null && !widget.isDisposed()); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/ICompletionListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/ICompletionListener.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,95 @@ +/******************************************************************************* + * 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.text.contentassist.ICompletionListener; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * A completion listener is informed before the content assistant computes completion proposals. + *

                + * In order to provide backward compatibility for clients of ICompletionListener, extension + * interfaces are used to provide a means of evolution. The following extension interfaces exist: + *

                  + *
                • {@link dwtx.jface.text.contentassist.ICompletionListenerExtension} since version 3.4 introducing + * the following functions: + *
                    + *
                  • additional notification about restarting the current code assist session
                  • + *
                  + *
                • + *
                + *

                + * + *

                + * Clients may implement this interface. + *

                + * + * @since 3.2 + */ +public interface ICompletionListener { + /** + * Called when code assist is invoked when there is no current code assist session. + * + * @param event the content assist event + */ + void assistSessionStarted(ContentAssistEvent event); + + /** + * Called when a code assist session ends (for example, the proposal popup is closed). + * + * @param event the content assist event + */ + void assistSessionEnded(ContentAssistEvent event); + + /** + * Called when the selection in the proposal popup is changed or if the insert-mode changed. + * + * @param proposal the newly selected proposal, possibly null + * @param smartToggle true if the insert-mode toggle is being pressed, + * false otherwise + */ + void selectionChanged(ICompletionProposal proposal, bool smartToggle); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/ICompletionListenerExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/ICompletionListenerExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,67 @@ +/******************************************************************************* + * 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.text.contentassist.ICompletionListenerExtension; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Extends {@link dwtx.jface.text.contentassist.ICompletionListener} + * with an additional notification about restarting the current code assist session. + *

                + * Clients may implement this interface. + *

                + * + * @since 3.4 + */ +public interface ICompletionListenerExtension { + /** + * Called when code assist is invoked when there is already a current code assist session. + * + * @param event the content assist event + */ + void assistSessionRestarted(ContentAssistEvent event); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/ICompletionProposal.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/ICompletionProposal.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,175 @@ +/******************************************************************************* + * 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 + * 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.text.contentassist.ICompletionProposal; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + + + +import dwt.graphics.Image; +import dwt.graphics.Point; +import dwtx.jface.text.IDocument; + + +/** + * The interface of completion proposals generated by content assist processors. + * A completion proposal contains information used to present the proposed completion + * to the user, to insert the completion should the user select it, and to present + * context information for the chosen completion once it has been inserted. + *

                + * In order to provide backward compatibility for clients of ICompletionProposal, extension + * interfaces are used to provide a means of evolution. The following extension interfaces exist: + *

                  + *
                • {@link dwtx.jface.text.contentassist.ICompletionProposalExtension} since version 2.0 introducing + * the following functions: + *
                    + *
                  • handling of trigger characters other than ENTER
                  • + *
                  • completion proposal validation for a given offset
                  • + *
                  • context information can be freely positioned
                  • + *
                  + *
                • + *
                • {@link dwtx.jface.text.contentassist.ICompletionProposalExtension2} since version 2.1 introducing + * the following functions: + *
                    + *
                  • handling of trigger characters with modifiers
                  • + *
                  • visual indication for selection of a proposal
                  • + *
                  + *
                • + *
                • {@link dwtx.jface.text.contentassist.ICompletionProposalExtension3} since version 3.0 introducing + * the following functions: + *
                    + *
                  • provision of a custom information control creator
                  • + *
                  • provide a custom completion text and offset for prefix completion
                  • + *
                  + *
                • + *
                • {@link dwtx.jface.text.contentassist.ICompletionProposalExtension4} since version 3.1 introducing + * the following functions: + *
                    + *
                  • specify whether a proposal is automatically insertable
                  • + *
                  + *
                • + *
                • {@link dwtx.jface.text.contentassist.ICompletionProposalExtension5} since version 3.2 introducing + * the following function: + *
                    + *
                  • Allow background computation of the additional info
                  • + *
                  + *
                • + *
                • {@link dwtx.jface.text.contentassist.ICompletionProposalExtension6} since version 3.4 introducing + * the following function: + *
                    + *
                  • Allow styled ranges in the display string.
                  • + *
                  + *
                • + *
                + *

                + *

                + * This interface can be implemented by clients. By default, clients use + * {@link dwtx.jface.text.contentassist.CompletionProposal} as the + * standard implementer of this interface. + *

                + * + * @see IContentAssistProcessor + */ +public interface ICompletionProposal { + + /** + * Inserts the proposed completion into the given document. + * + * @param document the document into which to insert the proposed completion + */ + void apply(IDocument document); + + /** + * Returns the new selection after the proposal has been applied to + * the given document in absolute document coordinates. If it returns + * null, no new selection is set. + * + * A document change can trigger other document changes, which have + * to be taken into account when calculating the new selection. Typically, + * this would be done by installing a document listener or by using a + * document position during {@link #apply(IDocument)}. + * + * @param document the document into which the proposed completion has been inserted + * @return the new selection in absolute document coordinates + */ + Point getSelection(IDocument document); + + /** + * Returns optional additional information about the proposal. The additional information will + * be presented to assist the user in deciding if the selected proposal is the desired choice. + *

                + * If {@link ICompletionProposalExtension5} is implemented, this method should not be called any + * longer. This method may be deprecated in a future release. + *

                + * + * @return the additional information or null + */ + String getAdditionalProposalInfo(); + + /** + * Returns the string to be displayed in the list of completion proposals. + * + * @return the string to be displayed + */ + String getDisplayString(); + + /** + * Returns the image to be displayed in the list of completion proposals. + * The image would typically be shown to the left of the display string. + * + * @return the image to be shown or null if no image is desired + */ + Image getImage(); + + /** + * Returns optional context information associated with this proposal. + * The context information will automatically be shown if the proposal + * has been applied. + * + * @return the context information for this proposal or null + */ + IContextInformation getContextInformation(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/ICompletionProposalExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/ICompletionProposalExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.contentassist.ICompletionProposalExtension; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.IDocument; + + +/** + * Extends {@link dwtx.jface.text.contentassist.ICompletionProposal} + * with the following functions: + *
                  + *
                • handling of trigger characters other than ENTER
                • + *
                • completion proposal validation for a given offset
                • + *
                • context information can be freely positioned
                • + *
                + * + * @since 2.0 + */ +public interface ICompletionProposalExtension { + + /** + * Applies the proposed completion to the given document. The insertion + * has been triggered by entering the given character at the given offset. + * This method assumes that {@link #isValidFor(IDocument, int)} returns + * true if called for offset. + * + * @param document the document into which to insert the proposed completion + * @param trigger the trigger to apply the completion + * @param offset the offset at which the trigger has been activated + */ + void apply(IDocument document, char trigger, int offset); + + /** + * Returns whether this completion proposal is valid for the given + * position in the given document. + * + * @param document the document for which the proposal is tested + * @param offset the offset for which the proposal is tested + * @return true iff valid + */ + bool isValidFor(IDocument document, int offset); + + /** + * Returns the characters which trigger the application of this completion proposal. + * + * @return the completion characters for this completion proposal or null + * if no completion other than the new line character is possible + */ + char[] getTriggerCharacters(); + + /** + * Returns the position to which the computed context information refers to or + * -1 if no context information can be provided by this completion proposal. + * + * @return the position to which the context information refers to or -1 for no information + */ + int getContextInformationPosition(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/ICompletionProposalExtension2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/ICompletionProposalExtension2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.contentassist.ICompletionProposalExtension2; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.ITextViewer; + + +/** + * Extends {@link dwtx.jface.text.contentassist.ICompletionProposal} + * with the following functions: + *
                  + *
                • handling of trigger characters with modifiers
                • + *
                • visual indication for selection of a proposal
                • + *
                + * + * @since 2.1 + */ +public interface ICompletionProposalExtension2 { + + /** + * Applies the proposed completion to the given document. The insertion + * has been triggered by entering the given character with a modifier at the given offset. + * This method assumes that {@link #validate(IDocument, int, DocumentEvent)} + * returns true if called for offset. + * + * @param viewer the text viewer into which to insert the proposed completion + * @param trigger the trigger to apply the completion + * @param stateMask the state mask of the modifiers + * @param offset the offset at which the trigger has been activated + */ + void apply(ITextViewer viewer, char trigger, int stateMask, int offset); + + /** + * Called when the proposal is selected. + * + * @param viewer the text viewer. + * @param smartToggle the smart toggle key was pressed + */ + void selected(ITextViewer viewer, bool smartToggle); + + /** + * Called when the proposal is unselected. + * + * @param viewer the text viewer. + */ + void unselected(ITextViewer viewer); + + /** + * Requests the proposal to be validated with respect to the document event. + * If the proposal cannot be validated, the methods returns false. + * If the document event was null, only the caret offset was changed, but not the document. + * + * This method replaces {@link ICompletionProposalExtension#isValidFor(IDocument, int)} + * + * @param document the document + * @param offset the caret offset + * @param event the document event, may be null + * @return bool + */ + bool validate(IDocument document, int offset, DocumentEvent event); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/ICompletionProposalExtension3.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/ICompletionProposalExtension3.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,97 @@ +/******************************************************************************* + * 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 + * 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.text.contentassist.ICompletionProposalExtension3; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IInformationControlCreator; + + +/** + * Extends {@link dwtx.jface.text.contentassist.ICompletionProposal} + * with the following functions: + *
                  + *
                • provision of a custom information control creator
                • + *
                • provide a custom completion text and offset for prefix completion
                • + *
                + * + * @since 3.0 + */ +public interface ICompletionProposalExtension3 { + /** + * Returns the information control creator of this completion proposal. + * + * @return the information control creator, or null if no custom control creator is available + */ + IInformationControlCreator getInformationControlCreator(); + + /** + * Returns the string that would be inserted at the position returned from + * {@link #getPrefixCompletionStart(IDocument, int)} if this proposal was + * applied. If the replacement string cannot be determined, + * null may be returned. + * + * @param document the document that the receiver applies to + * @param completionOffset the offset into document where the + * completion takes place + * @return the replacement string or null if it cannot be + * determined + */ + CharSequence getPrefixCompletionText(IDocument document, int completionOffset); + + /** + * Returns the document offset at which the receiver would insert its + * proposal. + * + * @param document the document that the receiver applies to + * @param completionOffset the offset into document where the + * completion takes place + * @return the offset at which the proposal would insert its proposal + */ + int getPrefixCompletionStart(IDocument document, int completionOffset); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/ICompletionProposalExtension4.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/ICompletionProposalExtension4.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,75 @@ +/******************************************************************************* + * 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.text.contentassist.ICompletionProposalExtension4; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Extends + * {@link dwtx.jface.text.contentassist.ICompletionProposal} with + * the following functions: + *
                  + *
                • specify whether a proposal is automatically insertable
                • + *
                + * + * @since 3.1 + */ +public interface ICompletionProposalExtension4 { + + /** + * Returns true if the proposal may be automatically + * inserted, false otherwise. Automatic insertion can + * happen if the proposal is the only one being proposed, in which + * case the content assistant may decide to not prompt the user with + * a list of proposals, but simply insert the single proposal. A + * proposal may veto this behavior by returning false + * to a call to this method. + * + * @return true if the proposal may be inserted + * automatically, false if not + */ + bool isAutoInsertable(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/ICompletionProposalExtension5.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/ICompletionProposalExtension5.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,79 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.text.contentassist.ICompletionProposalExtension5; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.core.runtime.IProgressMonitor; + +/** + * Extends {@link dwtx.jface.text.contentassist.ICompletionProposal} with the following + * function: + *
                  + *
                • Allow background computation of the additional info.
                • + *
                + * + * @since 3.2 + */ +public interface ICompletionProposalExtension5 { + /** + * Returns additional information about the proposal. The additional information will be + * presented to assist the user in deciding if the selected proposal is the desired choice. + *

                + * This method may be called on a non-UI thread. + *

                + *

                + * By default, the returned information is converted to a string and displayed as text; if + * {@link ICompletionProposalExtension3#getInformationControlCreator()} is implemented, the + * information will be passed to a custom information control for display. + *

                + * + * @param monitor a monitor to report progress and to watch for + * {@link IProgressMonitor#isCanceled() cancelation}. + * @return the additional information, null for no information + */ + Object getAdditionalProposalInfo(IProgressMonitor monitor); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/ICompletionProposalExtension6.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/ICompletionProposalExtension6.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,76 @@ +/******************************************************************************* + * 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.text.contentassist.ICompletionProposalExtension6; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.viewers.StyledString; + + +/** + * Extends {@link dwtx.jface.text.contentassist.ICompletionProposal} with the following + * function: + *
                  + *
                • Allow styled ranges in the display string.
                • + *
                + * + * @since 3.4 + */ +public interface ICompletionProposalExtension6 { + + /** + * Returns the styled string used to display this proposal in the list of completion proposals. + * This can for example be used to draw mixed colored labels. + *

                + * Note: {@link ICompletionProposal#getDisplayString()} still needs to be + * correctly implemented as this method might be ignored in case of uninstalled owner draw + * support. + *

                + * + * @return the string builder used to display this proposal + */ + StyledString getStyledDisplayString(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/IContentAssistListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/IContentAssistListener.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.contentassist.IContentAssistListener; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + + + +import dwt.events.VerifyEvent; +import dwtx.jface.text.IEventConsumer; + + +/** + * An interface whereby listeners can not only receive key events, + * but can also consume them to prevent subsequent listeners from + * processing the event. + */ +interface IContentAssistListener : IEventConsumer { + + /** + * Verifies the key event. + * + * @param event the verify event + * @return true if processing should be continued by additional listeners + * @see dwt.custom.VerifyKeyListener#verifyKey(VerifyEvent) + */ + public bool verifyKey(VerifyEvent event); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/IContentAssistProcessor.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/IContentAssistProcessor.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.contentassist.IContentAssistProcessor; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.ITextViewer; + + +/** + * A content assist processor proposes completions and + * computes context information for a particular content type. + * A content assist processor is a {@link dwtx.jface.text.contentassist.IContentAssistant} + * plug-in. + *

                + * This interface must be implemented by clients. Implementers should be + * registered with a content assistant in order to get involved in the + * assisting process. + *

                +*/ +public interface IContentAssistProcessor { + + /** + * Returns a list of completion proposals based on the + * specified location within the document that corresponds + * to the current cursor position within the text viewer. + * + * @param viewer the viewer whose document is used to compute the proposals + * @param offset an offset within the document for which completions should be computed + * @return an array of completion proposals or null if no proposals are possible + */ + ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset); + + /** + * Returns information about possible contexts based on the + * specified location within the document that corresponds + * to the current cursor position within the text viewer. + * + * @param viewer the viewer whose document is used to compute the possible contexts + * @param offset an offset within the document for which context information should be computed + * @return an array of context information objects or null if no context could be found + */ + IContextInformation[] computeContextInformation(ITextViewer viewer, int offset); + + /** + * Returns the characters which when entered by the user should + * automatically trigger the presentation of possible completions. + * + * @return the auto activation characters for completion proposal or null + * if no auto activation is desired + */ + char[] getCompletionProposalAutoActivationCharacters(); + + /** + * Returns the characters which when entered by the user should + * automatically trigger the presentation of context information. + * + * @return the auto activation characters for presenting context information + * or null if no auto activation is desired + */ + char[] getContextInformationAutoActivationCharacters(); + + /** + * Returns the reason why this content assist processor + * was unable to produce any completion proposals or context information. + * + * @return an error message or null if no error occurred + */ + String getErrorMessage(); + + /** + * Returns a validator used to determine when displayed context information + * should be dismissed. May only return null if the processor is + * incapable of computing context information.

                + * + * @return a context information validator, or null if the processor + * is incapable of computing context information + */ + IContextInformationValidator getContextInformationValidator(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/IContentAssistant.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/IContentAssistant.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,165 @@ +/******************************************************************************* + * 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.text.contentassist.IContentAssistant; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.ITextViewer; + + +/** + * An IContentAssistant provides support on interactive content completion. + * The content assistant is a {@link dwtx.jface.text.ITextViewer} add-on. Its + * purpose is to propose, display, and insert completions of the content + * of the text viewer's document at the viewer's cursor position. In addition + * to handle completions, a content assistant can also be requested to provide + * context information. Context information is shown in a tool tip like popup. + * As it is not always possible to determine the exact context at a given + * document offset, a content assistant displays the possible contexts and requests + * the user to choose the one whose information should be displayed. + *

                + * A content assistant has a list of {@link dwtx.jface.text.contentassist.IContentAssistProcessor} + * objects each of which is registered for a particular document content + * type. The content assistant uses the processors to react on the request + * of completing documents or presenting context information. + *

                + *

                + * In order to provide backward compatibility for clients of IContentAssistant, extension + * interfaces are used to provide a means of evolution. The following extension interfaces exist: + *

                  + *
                • {@link dwtx.jface.text.contentassist.IContentAssistantExtension} since version 3.0 introducing + * the following functions: + *
                    + *
                  • handle documents with multiple partitions
                  • + *
                  • insertion of common completion prefixes
                  • + *
                  + *
                • + *
                • {@link dwtx.jface.text.contentassist.IContentAssistantExtension2} since version 3.2 introducing + * the following functions: + *
                    + *
                  • repeated invocation (cycling) mode
                  • + *
                  • completion listeners
                  • + *
                  • a local status line for the completion popup
                  • + *
                  • control over the behavior when no proposals are available
                  • + *
                  + *
                • + *
                • {@link dwtx.jface.text.contentassist.IContentAssistantExtension3} since version 3.2 introducing + * the following function: + *
                    + *
                  • a key-sequence to listen for in repeated invocation mode
                  • + *
                  + *
                • + *
                • {@link dwtx.jface.text.contentassist.IContentAssistantExtension4} since version 3.4 introducing + * the following function: + *
                    + *
                  • allows to get a handler for the given command identifier
                  • + *
                  + *
                • + *
                + *

                + *

                + * The interface can be implemented by clients. By default, clients use + * {@link dwtx.jface.text.contentassist.ContentAssistant} as the standard + * implementer of this interface. + *

                + * + * @see dwtx.jface.text.ITextViewer + * @see dwtx.jface.text.contentassist.IContentAssistProcessor + */ + public interface IContentAssistant { + + //------ proposal popup orientation styles ------------ + /** The context info list will overlay the list of completion proposals. */ + public const static int PROPOSAL_OVERLAY= 10; + /** The completion proposal list will be removed before the context info list will be shown. */ + public const static int PROPOSAL_REMOVE= 11; + /** The context info list will be presented without hiding or overlapping the completion proposal list. */ + public const static int PROPOSAL_STACKED= 12; + + //------ context info box orientation styles ---------- + /** Context info will be shown above the location it has been requested for without hiding the location. */ + public const static int CONTEXT_INFO_ABOVE= 20; + /** Context info will be shown below the location it has been requested for without hiding the location. */ + public const static int CONTEXT_INFO_BELOW= 21; + + + /** + * Installs content assist support on the given text viewer. + * + * @param textViewer the text viewer on which content assist will work + */ + void install(ITextViewer textViewer); + + /** + * Uninstalls content assist support from the text viewer it has + * previously be installed on. + */ + void uninstall(); + + /** + * Shows all possible completions of the content at the viewer's cursor position. + * + * @return an optional error message if no proposals can be computed + */ + String showPossibleCompletions(); + + /** + * Shows context information for the content at the viewer's cursor position. + * + * @return an optional error message if no context information can be computed + */ + String showContextInformation(); + + /** + * Returns the content assist processor to be used for the given content type. + * + * @param contentType the type of the content for which this + * content assistant is to be requested + * @return an instance content assist processor or + * null if none exists for the specified content type + */ + IContentAssistProcessor getContentAssistProcessor(String contentType); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/IContentAssistantExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/IContentAssistantExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.contentassist.IContentAssistantExtension; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Extends {@link dwtx.jface.text.contentassist.IContentAssistant} + * with the following functions: + *
                  + *
                • handle documents with multiple partitions
                • + *
                • insertion of common completion prefixes
                • + *
                + * + * @since 3.0 + */ +public interface IContentAssistantExtension { + + /** + * Returns the document partitioning this content assistant is using. + * + * @return the document partitioning this content assistant is using + */ + String getDocumentPartitioning(); + + /** + * Inserts the common prefix of the available completions. If no common + * prefix can be computed it is identical to + * {@link IContentAssistant#showPossibleCompletions()}. + * + * @return an optional error message if no proposals can be computed + */ + String completePrefix(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/IContentAssistantExtension2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/IContentAssistantExtension2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,116 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.text.contentassist.IContentAssistantExtension2; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Extends {@link dwtx.jface.text.contentassist.IContentAssistant} with the following + * functions: + *
                  + *
                • completion listeners
                • + *
                • repeated invocation mode
                • + *
                • a local status line for the completion popup
                • + *
                • control over the behavior when no proposals are available
                • + *
                + * + * @since 3.2 + */ +public interface IContentAssistantExtension2 { + + /** + * Adds a completion listener that will be informed before proposals are computed. + * + * @param listener the listener + */ + public void addCompletionListener(ICompletionListener listener); + + /** + * Removes a completion listener. + * + * @param listener the listener to remove + */ + public void removeCompletionListener(ICompletionListener listener); + + /** + * Enables repeated invocation mode, which will trigger re-computation of the proposals when + * code assist is executed repeatedly. The default is no false. + * + * @param cycling true to enable repetition mode, false to disable + */ + public void setRepeatedInvocationMode(bool cycling); + + /** + * Enables displaying an empty completion proposal pop-up. The default is not to show an empty + * list. + * + * @param showEmpty true to show empty lists + */ + public void setShowEmptyList(bool showEmpty); + + /** + * Enables displaying a status line below the proposal popup. The default is not to show the + * status line. The contents of the status line may be set via {@link #setStatusMessage(String)}. + * + * @param show true to show a message line, false to not show one. + */ + public void setStatusLineVisible(bool show); + + /** + * Sets the caption message displayed at the bottom of the completion proposal popup. + * + * @param message the message + */ + public void setStatusMessage(String message); + + /** + * Sets the text to be shown if no proposals are available and + * {@link #setShowEmptyList(bool) empty lists} are displayed. + * + * @param message the text for the empty list + */ + public void setEmptyMessage(String message); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/IContentAssistantExtension3.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/IContentAssistantExtension3.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,70 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.text.contentassist.IContentAssistantExtension3; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.bindings.keys.KeySequence; + +/** + * Extends {@link dwtx.jface.text.contentassist.IContentAssistant} with the following + * function: + *
                  + *
                • a key-sequence to listen for in repeated invocation mode
                • + *
                + * + * @since 3.2 + */ +public interface IContentAssistantExtension3 { + + /** + * Sets the key sequence to listen for in repeated invocation mode. If the key sequence is + * encountered, a step in the repetition iteration is triggered. + * + * @param sequence the key sequence used for the repeated invocation mode or null if none + */ + public void setRepeatedInvocationTrigger(KeySequence sequence); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/IContentAssistantExtension4.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/IContentAssistantExtension4.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,80 @@ +/******************************************************************************* + * 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.text.contentassist.IContentAssistantExtension4; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.core.commands.IHandler; + + +/** + * Extends {@link dwtx.jface.text.contentassist.IContentAssistant} with + * the following function: + *
                  + *
                • allows to get a handler for the given command identifier
                • + *
                + * + * @since 3.4 + */ +public interface IContentAssistantExtension4 { + + /** + * Returns the handler for the given command identifier. + *

                + * The same handler instance will be returned when called a more than once + * with the same command identifier. + *

                + * + * @param commandId the command identifier + * @return the handler for the given command identifier + * @throws IllegalArgumentException if the command is not supported by this + * content assistant + * @throws IllegalStateException if called when this content assistant is + * uninstalled + */ + IHandler getHandler(String commandId); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/IContextInformation.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/IContextInformation.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.contentassist.IContextInformation; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.graphics.Image; + + +/** + * The interface of context information presented to the user and + * generated by content assist processors. + *

                + * In order to provide backward compatibility for clients of + * IContextInformation, extension interfaces are used to + * provide a means of evolution. The following extension interfaces + * exist: + *

                  + *
                • {@link dwtx.jface.text.contentassist.IContextInformationExtension} + * since version 2.0 introducing the ability to freely position the + * context information.
                • + *
                + *

                + *

                + * The interface can be implemented by clients. By default, clients use + * {@link dwtx.jface.text.contentassist.ContextInformation} as + * the standard implementer of this interface. + *

                + * + * @see IContentAssistProcessor + */ +public interface IContextInformation { + + /** + * Returns the string to be displayed in the list of contexts. + * This method is used to supply a unique presentation for + * situations where the context is ambiguous. These strings are + * used to allow the user to select the specific context. + * + * @return the string to be displayed for the context + */ + String getContextDisplayString(); + + /** + * Returns the image for this context information. + * The image will be shown to the left of the display string. + * + * @return the image to be shown or null if no image is desired + */ + Image getImage(); + + /** + * Returns the string to be displayed in the tool tip like information popup. + * + * @return the string to be displayed + */ + String getInformationDisplayString(); + + /** + * Compares the given object with this receiver. Two context informations are + * equal if there information display strings and their context display strings + * are equal. + * + * @see Object#equals(Object) + */ + bool equals(Object object); +} + + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/IContextInformationExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/IContextInformationExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.contentassist.IContextInformationExtension; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Extends {@link dwtx.jface.text.contentassist.IContextInformation} with + * the ability to freely position the context information. + * + * @since 2.0 + */ +public interface IContextInformationExtension { + + /** + * Returns the start offset of the range for which this context + * information is valid or -1 if unknown. + * + * @return the start offset of the range for which this context + * information is valid + */ + int getContextInformationPosition(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/IContextInformationPresenter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/IContextInformationPresenter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.contentassist.IContextInformationPresenter; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.TextPresentation; + + +/** + * A context information presenter determines the presentation + * of context information depending on a given document position. + *

                + * The interface can be implemented by clients. + *

                + * + * @since 2.0 + */ +public interface IContextInformationPresenter { + + /** + * Installs this presenter for the given context information. + * + * @param info the context information which this presenter should style + * @param viewer the text viewer on which the information is presented + * @param offset the document offset for which the information has been computed + */ + void install(IContextInformation info, ITextViewer viewer, int offset); + + /** + * Updates the given presentation of the given context information + * at the given document position. Returns whether update changed the + * presentation. + * + * @param offset the current offset within the document + * @param presentation the presentation to be updated + * @return true if the given presentation has been changed + */ + bool updatePresentation(int offset, TextPresentation presentation); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/IContextInformationValidator.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/IContextInformationValidator.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.contentassist.IContextInformationValidator; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.ITextViewer; + + +/** + * A context information validator is used to determine if + * a displayed context information is still valid or should + * be dismissed. + *

                + * The interface can be implemented by clients. + *

                + * + * @see IContextInformationPresenter + */ +public interface IContextInformationValidator { + + /** + * Installs this validator for the given context information. + * + * @param info the context information which this validator should check + * @param viewer the text viewer on which the information is presented + * @param offset the document offset for which the information has been computed + */ + void install(IContextInformation info, ITextViewer viewer, int offset); + + /** + * Returns whether the information this validator is installed on is still valid + * at the given document position. + * + * @param offset the current offset within the document + * @return true if the information also valid at the given document position + */ + bool isContextInformationValid(int offset); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/JFaceTextMessages.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/JFaceTextMessages.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.contentassist.JFaceTextMessages; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.PopupCloser; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.dwthelper.ResourceBundle; + +/** + * Helper class to get NLSed messages. + */ +class JFaceTextMessages { + +// private static const String RESOURCE_BUNDLE= JFaceTextMessages.classinfo.getName(); + + private static ResourceBundle fgResourceBundle;//= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + static this() { + fgResourceBundle = ResourceBundle.getBundle( + getImportData!("dwtx.jface.text.contentassist.JFaceTextMessages.properties")); + } + + private this() { + } + + /** + * Gets a string from the resource bundle. + * + * @param key the string used to get the bundle value, must not be null + * @return the string from the resource bundle + */ + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" ~ key ~ "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/contentassist/PopupCloser.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/contentassist/PopupCloser.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,306 @@ +/******************************************************************************* + * 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 + * 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.text.contentassist.PopupCloser; + +import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport +import dwtx.jface.text.contentassist.Helper; // packageimport +import dwtx.jface.text.contentassist.IContentAssistant; // packageimport +import dwtx.jface.text.contentassist.CompletionProposal; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport +import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport +import dwtx.jface.text.contentassist.ICompletionListener; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport +import dwtx.jface.text.contentassist.ContextInformation; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport +import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport +import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport +import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport +import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport +import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport +import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport +import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport +import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport +import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport +import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport +import dwtx.jface.text.contentassist.IContextInformation; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport +import dwtx.jface.text.contentassist.ContentAssistant; // packageimport +import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport +import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport + + +import dwt.dwthelper.utils; + + + +import dwt.DWT; +import dwt.events.FocusEvent; +import dwt.events.FocusListener; +import dwt.events.SelectionEvent; +import dwt.events.SelectionListener; +import dwt.events.ShellAdapter; +import dwt.events.ShellEvent; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Listener; +import dwt.widgets.ScrollBar; +import dwt.widgets.Shell; +import dwt.widgets.Table; +import dwtx.jface.internal.text.DelayedInputChangeListener; +import dwtx.jface.internal.text.InformationControlReplacer; +import dwtx.jface.text.IDelayedInputChangeProvider; +import dwtx.jface.text.IInformationControl; +import dwtx.jface.text.IInformationControlExtension5; +import dwtx.jface.text.IInputChangedListener; + + +/** + * A generic closer class used to monitor various + * interface events in order to determine whether + * a content assistant should be terminated and all + * associated windows be closed. + */ +class PopupCloser : ShellAdapter , FocusListener, SelectionListener, Listener { + + /** The content assistant to be monitored. */ + private ContentAssistant fContentAssistant; + /** The table of a selector popup opened by the content assistant. */ + private Table fTable; + /** The scroll bar of the table for the selector popup. */ + private ScrollBar fScrollbar; + /** Indicates whether the scroll bar thumb has been grabbed. */ + private bool fScrollbarClicked= false; + /** + * The shell on which some listeners are registered. + * @since 3.1 + */ + private Shell fShell; + /** + * The display on which some filters are registered. + * @since 3.4 + */ + private Display fDisplay; + /** + * The additional info controller, or null. + * @since 3.4 + */ + private AdditionalInfoController fAdditionalInfoController; + + /** + * Installs this closer on the given table opened by the given content assistant. + * + * @param contentAssistant the content assistant + * @param table the table to be tracked + */ + public void install(ContentAssistant contentAssistant, Table table) { + install(contentAssistant, table, null); + } + + /** + * Installs this closer on the given table opened by the given content assistant. + * + * @param contentAssistant the content assistant + * @param table the table to be tracked + * @param additionalInfoController the additional info controller, or null + * @since 3.4 + */ + public void install(ContentAssistant contentAssistant, Table table, AdditionalInfoController additionalInfoController) { + fContentAssistant= contentAssistant; + fTable= table; + fAdditionalInfoController= additionalInfoController; + + if (Helper.okToUse(fTable)) { + fShell= fTable.getShell(); + fDisplay= fShell.getDisplay(); + + fShell.addShellListener(this); + fTable.addFocusListener(this); + fScrollbar= fTable.getVerticalBar(); + if (fScrollbar !is null) + fScrollbar.addSelectionListener(this); + + fDisplay.addFilter(DWT.Activate, this); + fDisplay.addFilter(DWT.MouseWheel, this); + + fDisplay.addFilter(DWT.Deactivate, this); + + fDisplay.addFilter(DWT.MouseUp, this); + } + } + + /** + * Uninstalls this closer if previously installed. + */ + public void uninstall() { + fContentAssistant= null; + if (Helper.okToUse(fShell)) + fShell.removeShellListener(this); + fShell= null; + if (Helper.okToUse(fScrollbar)) + fScrollbar.removeSelectionListener(this); + if (Helper.okToUse(fTable)) + fTable.removeFocusListener(this); + if (fDisplay !is null && ! fDisplay.isDisposed()) { + fDisplay.removeFilter(DWT.Activate, this); + fDisplay.removeFilter(DWT.MouseWheel, this); + + fDisplay.removeFilter(DWT.Deactivate, this); + + fDisplay.removeFilter(DWT.MouseUp, this); + } + } + + /* + * @see dwt.events.SelectionListener#widgetSelected(dwt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + fScrollbarClicked= true; + } + + /* + * @see dwt.events.SelectionListener#widgetDefaultSelected(dwt.events.SelectionEvent) + */ + public void widgetDefaultSelected(SelectionEvent e) { + fScrollbarClicked= true; + } + + /* + * @see dwt.events.FocusListener#focusGained(dwt.events.FocusEvent) + */ + public void focusGained(FocusEvent e) { + } + + /* + * @see dwt.events.FocusListener#focusLost(dwt.events.FocusEvent) + */ + public void focusLost(FocusEvent e) { + fScrollbarClicked= false; + Display d= fTable.getDisplay(); + d.asyncExec(dgRunnable((FocusEvent e_) { + if (Helper.okToUse(fTable) && !fTable.isFocusControl() && !fScrollbarClicked && fContentAssistant !is null) + fContentAssistant.popupFocusLost(e_); + }, e )); + } + + /* + * @see dwt.events.ShellAdapter#shellDeactivated(dwt.events.ShellEvent) + * @since 3.1 + */ + public void shellDeactivated(ShellEvent e) { + if (fContentAssistant !is null && ! fContentAssistant.hasProposalPopupFocus()) + fContentAssistant.hide_package(); + } + + + /* + * @see dwt.events.ShellAdapter#shellClosed(dwt.events.ShellEvent) + * @since 3.1 + */ + public void shellClosed(ShellEvent e) { + if (fContentAssistant !is null) + fContentAssistant.hide_package(); + } + + /* + * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event) + * @since 3.4 + */ + public void handleEvent(Event event) { + switch (event.type) { + case DWT.Activate: + case DWT.MouseWheel: + if (fAdditionalInfoController is null) + return; + if (event.widget is fShell || event.widget is fTable || event.widget is fScrollbar) + return; + + if (fAdditionalInfoController.getInternalAccessor().getInformationControlReplacer() is null) + fAdditionalInfoController.hideInformationControl_package(); + else if (!fAdditionalInfoController.getInternalAccessor().isReplaceInProgress()) { + IInformationControl infoControl= fAdditionalInfoController.getCurrentInformationControl2(); + // During isReplaceInProgress(), events can come from the replacing information control + if (cast(Control)event.widget && cast(IInformationControlExtension5)infoControl ) { + Control control= cast(Control) event.widget; + IInformationControlExtension5 iControl5= cast(IInformationControlExtension5) infoControl; + if (!(iControl5.containsControl(control))) + fAdditionalInfoController.hideInformationControl_package(); + else if (event.type is DWT.MouseWheel) + fAdditionalInfoController.getInternalAccessor().replaceInformationControl(false); + } else if (infoControl !is null && infoControl.isFocusControl()) { + fAdditionalInfoController.getInternalAccessor().replaceInformationControl(true); + } + } + break; + + case DWT.MouseUp: + if (fAdditionalInfoController is null || fAdditionalInfoController.getInternalAccessor().isReplaceInProgress()) + break; + if (cast(Control)event.widget) { + Control control= cast(Control) event.widget; + IInformationControl infoControl= fAdditionalInfoController.getCurrentInformationControl2(); + if ( cast(IInformationControlExtension5)infoControl ) { + final IInformationControlExtension5 iControl5= cast(IInformationControlExtension5) infoControl; + if (iControl5.containsControl(control)) { + if ( cast(IDelayedInputChangeProvider)infoControl ) { + final IDelayedInputChangeProvider delayedICP= cast(IDelayedInputChangeProvider) infoControl; + final IInputChangedListener inputChangeListener= new DelayedInputChangeListener(delayedICP, fAdditionalInfoController.getInternalAccessor().getInformationControlReplacer()); + delayedICP.setDelayedInputChangeListener(inputChangeListener); + // cancel automatic input updating after a small timeout: + control.getShell().getDisplay().timerExec(1000, new class() Runnable { + public void run() { + delayedICP.setDelayedInputChangeListener(null); + } + }); + } + + // XXX: workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=212392 : + control.getShell().getDisplay().asyncExec(new class() Runnable { + public void run() { + fAdditionalInfoController.getInternalAccessor().replaceInformationControl(true); + } + }); + } + } + } + break; + + case DWT.Deactivate: + if (fAdditionalInfoController is null) + break; + InformationControlReplacer replacer= fAdditionalInfoController.getInternalAccessor().getInformationControlReplacer(); + if (replacer !is null && fContentAssistant !is null) { + IInformationControl iControl= replacer.getCurrentInformationControl2(); + if (cast(Control)event.widget && cast(IInformationControlExtension5)iControl ) { + Control control= cast(Control) event.widget; + IInformationControlExtension5 iControl5= cast(IInformationControlExtension5) iControl; + if (iControl5.containsControl(control)) { + control.getDisplay().asyncExec(new class() Runnable { + public void run() { + if (fContentAssistant !is null && ! fContentAssistant.hasProposalPopupFocus()) + fContentAssistant.hide_package(); + } + }); + } + } + } + break; + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/formatter/ContentFormatter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/formatter/ContentFormatter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,812 @@ +/******************************************************************************* + * 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 + * 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.text.formatter.ContentFormatter; + +import dwtx.jface.text.formatter.MultiPassContentFormatter; // packageimport +import dwtx.jface.text.formatter.ContextBasedFormattingStrategy; // packageimport +import dwtx.jface.text.formatter.FormattingContext; // packageimport +import dwtx.jface.text.formatter.IFormattingStrategy; // packageimport +import dwtx.jface.text.formatter.IContentFormatterExtension; // packageimport +import dwtx.jface.text.formatter.IFormattingStrategyExtension; // packageimport +import dwtx.jface.text.formatter.IContentFormatter; // packageimport +import dwtx.jface.text.formatter.FormattingContextProperties; // packageimport +import dwtx.jface.text.formatter.IFormattingContext; // packageimport + +import dwt.dwthelper.utils; + + +import dwtx.dwtxhelper.Collection; + + + + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.BadPositionCategoryException; +import dwtx.jface.text.DefaultPositionUpdater; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentExtension3; +import dwtx.jface.text.IPositionUpdater; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITypedRegion; +import dwtx.jface.text.Position; +import dwtx.jface.text.TextUtilities; +import dwtx.jface.text.TypedPosition; + + +/** + * Standard implementation of IContentFormatter. + * The formatter supports two operation modes: partition aware and + * partition unaware.

                + * In the partition aware mode, the formatter determines the + * partitioning of the document region to be formatted. For each + * partition it determines all document positions which are affected + * when text changes are applied to the partition. Those which overlap + * with the partition are remembered as character positions. These + * character positions are passed over to the formatting strategy + * registered for the partition's content type. The formatting strategy + * returns a string containing the formatted document partition as well + * as the adapted character positions. The formatted partition replaces + * the old content of the partition. The remembered document positions + * are updated with the adapted character positions. In addition, all + * other document positions are accordingly adapted to the formatting + * changes.

                + * In the partition unaware mode, the document's partitioning is ignored + * and the document is considered consisting of only one partition of + * the content type IDocument.DEFAULT_CONTENT_TYPE. The + * formatting process is similar to the partition aware mode, with the + * exception of having only one partition.

                + * Usually, clients instantiate this class and configure it before using it. + * + * @see IContentFormatter + * @see IDocument + * @see ITypedRegion + * @see Position + */ +public class ContentFormatter : IContentFormatter { + + /** + * Defines a reference to either the offset or the end offset of + * a particular position. + */ + static class PositionReference : Comparable { + + /** The referenced position */ + protected Position fPosition; + /** The reference to either the offset or the end offset */ + protected bool fRefersToOffset; + /** The original category of the referenced position */ + protected String fCategory; + + /** + * Creates a new position reference. + * + * @param position the position to be referenced + * @param refersToOffset true if position offset should be referenced + * @param category the category the given position belongs to + */ + protected this(Position position, bool refersToOffset, String category) { + fPosition= position; + fRefersToOffset= refersToOffset; + fCategory= category; + } + + /** + * Returns the offset of the referenced position. + * + * @return the offset of the referenced position + */ + protected int getOffset() { + return fPosition.getOffset(); + } + + /** + * Manipulates the offset of the referenced position. + * + * @param offset the new offset of the referenced position + */ + protected void setOffset(int offset) { + fPosition.setOffset(offset); + } + + /** + * Returns the length of the referenced position. + * + * @return the length of the referenced position + */ + protected int getLength() { + return fPosition.getLength(); + } + + /** + * Manipulates the length of the referenced position. + * + * @param length the new length of the referenced position + */ + protected void setLength(int length) { + fPosition.setLength(length); + } + + /** + * Returns whether this reference points to the offset or end offset + * of the references position. + * + * @return true if the offset of the position is referenced, false otherwise + */ + protected bool refersToOffset() { + return fRefersToOffset; + } + + /** + * Returns the category of the referenced position. + * + * @return the category of the referenced position + */ + protected String getCategory() { + return fCategory; + } + + /** + * Returns the referenced position. + * + * @return the referenced position + */ + protected Position getPosition() { + return fPosition; + } + + /** + * Returns the referenced character position + * + * @return the referenced character position + */ + protected int getCharacterPosition() { + if (fRefersToOffset) + return getOffset(); + return getOffset() + getLength(); + } + + /* + * @see Comparable#compareTo(Object) + */ + public int compareTo(Object obj) { + + if ( cast(PositionReference)obj ) { + PositionReference r= cast(PositionReference) obj; + return getCharacterPosition() - r.getCharacterPosition(); + } + + throw new ClassCastException(); + } + } + + /** + * The position updater used to update the remembered partitions. + * + * @see IPositionUpdater + * @see DefaultPositionUpdater + */ + class NonDeletingPositionUpdater : DefaultPositionUpdater { + + /** + * Creates a new updater for the given category. + * + * @param category the category + */ + protected this(String category) { + super(category); + } + + /* + * @see DefaultPositionUpdater#notDeleted() + */ + protected bool notDeleted() { + return true; + } + } + + /** + * The position updater which runs as first updater on the document's positions. + * Used to remove all affected positions from their categories to avoid them + * from being regularly updated. + * + * @see IPositionUpdater + */ + class RemoveAffectedPositions : IPositionUpdater { + /* + * @see IPositionUpdater#update(DocumentEvent) + */ + public void update(DocumentEvent event) { + removeAffectedPositions(event.getDocument()); + } + } + + /** + * The position updater which runs as last updater on the document's positions. + * Used to update all affected positions and adding them back to their + * original categories. + * + * @see IPositionUpdater + */ + class UpdateAffectedPositions : IPositionUpdater { + + /** The affected positions */ + private int[] fPositions; + /** The offset */ + private int fOffset; + + /** + * Creates a new updater. + * + * @param positions the affected positions + * @param offset the offset + */ + public this(int[] positions, int offset) { + fPositions= positions; + fOffset= offset; + } + + /* + * @see IPositionUpdater#update(DocumentEvent) + */ + public void update(DocumentEvent event) { + updateAffectedPositions(event.getDocument(), fPositions, fOffset); + } + } + + + /** Internal position category used for the formatter partitioning */ + private const static String PARTITIONING= "__formatter_partitioning"; //$NON-NLS-1$ + + /** The map of IFormattingStrategy objects */ + private Map fStrategies; + /** The indicator of whether the formatter operates in partition aware mode or not */ + private bool fIsPartitionAware= true; + + /** The partition information managing document position categories */ + private String[] fPartitionManagingCategories; + /** The list of references to offset and end offset of all overlapping positions */ + private List fOverlappingPositionReferences; + /** Position updater used for partitioning positions */ + private IPositionUpdater fPartitioningUpdater; + /** + * The document partitioning used by this formatter. + * @since 3.0 + */ + private String fPartitioning; + /** + * The document this formatter works on. + * @since 3.0 + */ + private IDocument fDocument; + /** + * The external partition managing categories. + * @since 3.0 + */ + private String[] fExternalPartitonManagingCategories; + /** + * Indicates whether fPartitionManagingCategories must be computed. + * @since 3.0 + */ + private bool fNeedsComputation= true; + + + /** + * Creates a new content formatter. The content formatter operates by default + * in the partition-aware mode. There are no preconfigured formatting strategies. + * Will use the default document partitioning if not further configured. + */ + public this() { + fPartitioning= IDocumentExtension3.DEFAULT_PARTITIONING; + } + + /** + * Registers a strategy for a particular content type. If there is already a strategy + * registered for this type, the new strategy is registered instead of the old one. + * If the given content type is null the given strategy is registered for + * all content types as is called only once per formatting session. + * + * @param strategy the formatting strategy to register, or null to remove an existing one + * @param contentType the content type under which to register + */ + public void setFormattingStrategy(IFormattingStrategy strategy, String contentType) { + + Assert.isNotNull(contentType); + + if (fStrategies is null) + fStrategies= new HashMap(); + + if (strategy is null) + fStrategies.remove(contentType); + else + fStrategies.put(contentType, cast(Object)strategy); + } + + /** + * Informs this content formatter about the names of those position categories + * which are used to manage the document's partitioning information and thus should + * be ignored when this formatter updates positions. + * + * @param categories the categories to be ignored + * @deprecated incompatible with an open set of document partitionings. The provided information is only used + * if this formatter can not compute the partition managing position categories. + */ + public void setPartitionManagingPositionCategories(String[] categories) { + fExternalPartitonManagingCategories= TextUtilities.copy(categories); + } + + /** + * Sets the document partitioning to be used by this formatter. + * + * @param partitioning the document partitioning + * @since 3.0 + */ + public void setDocumentPartitioning(String partitioning) { + fPartitioning= partitioning; + } + + /** + * Sets the formatter's operation mode. + * + * @param enable indicates whether the formatting process should be partition ware + */ + public void enablePartitionAwareFormatting(bool enable) { + fIsPartitionAware= enable; + } + + /* + * @see IContentFormatter#getFormattingStrategy(String) + */ + public IFormattingStrategy getFormattingStrategy(String contentType) { + + Assert.isNotNull(contentType); + + if (fStrategies is null) + return null; + + return cast(IFormattingStrategy) fStrategies.get(contentType); + } + + /* + * @see IContentFormatter#format(IDocument, IRegion) + */ + public void format(IDocument document, IRegion region) { + fNeedsComputation= true; + fDocument= document; + try { + + if (fIsPartitionAware) + formatPartitions(region); + else + formatRegion(region); + + } finally { + fNeedsComputation= true; + fDocument= null; + } + } + + /** + * Determines the partitioning of the given region of the document. + * Informs the formatting strategies of each partition about the start, + * the process, and the termination of the formatting session. + * + * @param region the document region to be formatted + * @since 3.0 + */ + private void formatPartitions(IRegion region) { + + addPartitioningUpdater(); + + try { + + TypedPosition[] ranges= getPartitioning(region); + if (ranges !is null) { + start(ranges, getIndentation(region.getOffset())); + format(ranges); + stop(ranges); + } + + } catch (BadLocationException x) { + } + + removePartitioningUpdater(); + } + + /** + * Formats the given region with the strategy registered for the default + * content type. The strategy is informed about the start, the process, and + * the termination of the formatting session. + * + * @param region the region to be formatted + * @since 3.0 + */ + private void formatRegion(IRegion region) { + + IFormattingStrategy strategy= getFormattingStrategy(IDocument.DEFAULT_CONTENT_TYPE); + if (strategy !is null) { + strategy.formatterStarts(getIndentation(region.getOffset())); + format(strategy, new TypedPosition(region.getOffset(), region.getLength(), IDocument.DEFAULT_CONTENT_TYPE)); + strategy.formatterStops(); + } + } + + /** + * Returns the partitioning of the given region of the document to be formatted. + * As one partition after the other will be formatted and formatting will + * probably change the length of the formatted partition, it must be kept + * track of the modifications in order to submit the correct partition to all + * formatting strategies. For this, all partitions are remembered as positions + * in a dedicated position category. (As formatting strategies might rely on each + * other, calling them in reversed order is not an option.) + * + * @param region the region for which the partitioning must be determined + * @return the partitioning of the specified region + * @exception BadLocationException of region is invalid in the document + * @since 3.0 + */ + private TypedPosition[] getPartitioning(IRegion region) { + + ITypedRegion[] regions= TextUtilities.computePartitioning(fDocument, fPartitioning, region.getOffset(), region.getLength(), false); + TypedPosition[] positions= new TypedPosition[regions.length]; + + for (int i= 0; i < regions.length; i++) { + positions[i]= new TypedPosition(regions[i]); + try { + fDocument.addPosition(PARTITIONING, positions[i]); + } catch (BadPositionCategoryException x) { + // should not happen + } + } + + return positions; + } + + /** + * Fires formatterStarts to all formatter strategies + * which will be involved in the forthcoming formatting process. + * + * @param regions the partitioning of the document to be formatted + * @param indentation the initial indentation + */ + private void start(TypedPosition[] regions, String indentation) { + for (int i= 0; i < regions.length; i++) { + IFormattingStrategy s= getFormattingStrategy(regions[i].getType()); + if (s !is null) + s.formatterStarts(indentation); + } + } + + /** + * Formats one partition after the other using the formatter strategy registered for + * the partition's content type. + * + * @param ranges the partitioning of the document region to be formatted + * @since 3.0 + */ + private void format(TypedPosition[] ranges) { + for (int i= 0; i < ranges.length; i++) { + IFormattingStrategy s= getFormattingStrategy(ranges[i].getType()); + if (s !is null) { + format(s, ranges[i]); + } + } + } + + /** + * Formats the given region of the document using the specified formatting + * strategy. In order to maintain positions correctly, first all affected + * positions determined, after all document listeners have been informed about + * the coming change, the affected positions are removed to avoid that they + * are regularly updated. After all position updaters have run, the affected + * positions are updated with the formatter's information and added back to + * their categories, right before the first document listener is informed about + * that a change happened. + * + * @param strategy the strategy to be used + * @param region the region to be formatted + * @since 3.0 + */ + private void format(IFormattingStrategy strategy, TypedPosition region) { + try { + + final int offset= region.getOffset(); + int length= region.getLength(); + + String content= fDocument.get(offset, length); + final int[] positions= getAffectedPositions(offset, length); + String formatted= strategy.format(content, isLineStart(offset), getIndentation(offset), positions); + + if (formatted !is null && !formatted.equals(content)) { + + IPositionUpdater first= new RemoveAffectedPositions(); + fDocument.insertPositionUpdater(first, 0); + IPositionUpdater last= new UpdateAffectedPositions(positions, offset); + fDocument.addPositionUpdater(last); + + fDocument.replace(offset, length, formatted); + + fDocument.removePositionUpdater(first); + fDocument.removePositionUpdater(last); + } + + } catch (BadLocationException x) { + // should not happen + } + } + + /** + * Fires formatterStops to all formatter strategies which were + * involved in the formatting process which is about to terminate. + * + * @param regions the partitioning of the document which has been formatted + */ + private void stop(TypedPosition[] regions) { + for (int i= 0; i < regions.length; i++) { + IFormattingStrategy s= getFormattingStrategy(regions[i].getType()); + if (s !is null) + s.formatterStops(); + } + } + + /** + * Installs those updaters which the formatter needs to keep track of the partitions. + * @since 3.0 + */ + private void addPartitioningUpdater() { + fPartitioningUpdater= new NonDeletingPositionUpdater(PARTITIONING); + fDocument.addPositionCategory(PARTITIONING); + fDocument.addPositionUpdater(fPartitioningUpdater); + } + + /** + * Removes the formatter's internal position updater and category. + * + * @since 3.0 + */ + private void removePartitioningUpdater() { + + try { + + fDocument.removePositionUpdater(fPartitioningUpdater); + fDocument.removePositionCategory(PARTITIONING); + fPartitioningUpdater= null; + + } catch (BadPositionCategoryException x) { + // should not happen + } + } + + /** + * Returns the partition managing position categories for the formatted document. + * + * @return the position managing position categories + * @since 3.0 + */ + private String[] getPartitionManagingCategories() { + if (fNeedsComputation) { + fNeedsComputation= false; + fPartitionManagingCategories= TextUtilities.computePartitionManagingCategories(fDocument); + if (fPartitionManagingCategories is null) + fPartitionManagingCategories= fExternalPartitonManagingCategories; + } + return fPartitionManagingCategories; + } + + /** + * Determines whether the given document position category should be ignored + * by this formatter's position updating. + * + * @param category the category to check + * @return true if the category should be ignored, false otherwise + */ + private bool ignoreCategory(String category) { + + if (PARTITIONING.equals(category)) + return true; + + String[] categories= getPartitionManagingCategories(); + if (categories !is null) { + for (int i= 0; i < categories.length; i++) { + if (categories[i].equals(category)) + return true; + } + } + + return false; + } + + /** + * Determines all embracing, overlapping, and follow up positions + * for the given region of the document. + * + * @param offset the offset of the document region to be formatted + * @param length the length of the document to be formatted + * @since 3.0 + */ + private void determinePositionsToUpdate(int offset, int length) { + + String[] categories= fDocument.getPositionCategories(); + if (categories !is null) { + for (int i= 0; i < categories.length; i++) { + + if (ignoreCategory(categories[i])) + continue; + + try { + + Position[] positions= fDocument.getPositions(categories[i]); + + for (int j= 0; j < positions.length; j++) { + + Position p= positions[j]; + if (p.overlapsWith(offset, length)) { + + if (offset < p.getOffset()) + fOverlappingPositionReferences.add(new PositionReference(p, true, categories[i])); + + if (p.getOffset() + p.getLength() < offset + length) + fOverlappingPositionReferences.add(new PositionReference(p, false, categories[i])); + } + } + + } catch (BadPositionCategoryException x) { + // can not happen + } + } + } + } + + /** + * Returns all offset and the end offset of all positions overlapping with the + * specified document range. + * + * @param offset the offset of the document region to be formatted + * @param length the length of the document to be formatted + * @return all character positions of the interleaving positions + * @since 3.0 + */ + private int[] getAffectedPositions(int offset, int length) { + + fOverlappingPositionReferences= new ArrayList(); + + determinePositionsToUpdate(offset, length); + + Collections.sort(fOverlappingPositionReferences); + + int[] positions= new int[fOverlappingPositionReferences.size()]; + for (int i= 0; i < positions.length; i++) { + PositionReference r= cast(PositionReference) fOverlappingPositionReferences.get(i); + positions[i]= r.getCharacterPosition() - offset; + } + + return positions; + } + + /** + * Removes the affected positions from their categories to avoid + * that they are invalidly updated. + * + * @param document the document + */ + private void removeAffectedPositions(IDocument document) { + int size= fOverlappingPositionReferences.size(); + for (int i= 0; i < size; i++) { + PositionReference r= cast(PositionReference) fOverlappingPositionReferences.get(i); + try { + document.removePosition(r.getCategory(), r.getPosition()); + } catch (BadPositionCategoryException x) { + // can not happen + } + } + } + + /** + * Updates all the overlapping positions. Note, all other positions are + * automatically updated by their document position updaters. + * + * @param document the document to has been formatted + * @param positions the adapted character positions to be used to update the document positions + * @param offset the offset of the document region that has been formatted + */ + protected void updateAffectedPositions(IDocument document, int[] positions, int offset) { + + if (document !is fDocument) + return; + + if (positions.length is 0) + return; + + for (int i= 0; i < positions.length; i++) { + + PositionReference r= cast(PositionReference) fOverlappingPositionReferences.get(i); + + if (r.refersToOffset()) + r.setOffset(offset + positions[i]); + else + r.setLength((offset + positions[i]) - r.getOffset()); + + Position p= r.getPosition(); + String category= r.getCategory(); + if (!document.containsPosition(category, p.offset, p.length)) { + try { + if (positionAboutToBeAdded(document, category, p)) + document.addPosition(r.getCategory(), p); + } catch (BadPositionCategoryException x) { + // can not happen + } catch (BadLocationException x) { + // should not happen + } + } + + } + + fOverlappingPositionReferences= null; + } + + /** + * The given position is about to be added to the given position category of the given document.

                + * This default implementation return true. + * + * @param document the document + * @param category the position category + * @param position the position that will be added + * @return true if the position can be added, false if it should be ignored + */ + protected bool positionAboutToBeAdded(IDocument document, String category, Position position) { + return true; + } + + /** + * Returns the indentation of the line of the given offset. + * + * @param offset the offset + * @return the indentation of the line of the offset + * @since 3.0 + */ + private String getIndentation(int offset) { + + try { + int start= fDocument.getLineOfOffset(offset); + start= fDocument.getLineOffset(start); + + int end= start; + char c= fDocument.getChar(end); + while ('\t' is c || ' ' is c) + c= fDocument.getChar(++end); + + return fDocument.get(start, end - start); + } catch (BadLocationException x) { + } + + return ""; //$NON-NLS-1$ + } + + /** + * Determines whether the offset is the beginning of a line in the given document. + * + * @param offset the offset + * @return true if offset is the beginning of a line + * @exception BadLocationException if offset is invalid in document + * @since 3.0 + */ + private bool isLineStart(int offset) { + int start= fDocument.getLineOfOffset(offset); + start= fDocument.getLineOffset(start); + return (start is offset); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/formatter/ContextBasedFormattingStrategy.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/formatter/ContextBasedFormattingStrategy.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.formatter.ContextBasedFormattingStrategy; + +import dwtx.jface.text.formatter.MultiPassContentFormatter; // packageimport +import dwtx.jface.text.formatter.FormattingContext; // packageimport +import dwtx.jface.text.formatter.IFormattingStrategy; // packageimport +import dwtx.jface.text.formatter.IContentFormatterExtension; // packageimport +import dwtx.jface.text.formatter.IFormattingStrategyExtension; // packageimport +import dwtx.jface.text.formatter.IContentFormatter; // packageimport +import dwtx.jface.text.formatter.FormattingContextProperties; // packageimport +import dwtx.jface.text.formatter.ContentFormatter; // packageimport +import dwtx.jface.text.formatter.IFormattingContext; // packageimport + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + +/** + * Formatting strategy for context based content formatting. Retrieves the preferences + * set on the formatting context's {@link FormattingContextProperties#CONTEXT_PREFERENCES} + * property and makes them available to subclasses. + *

                + * + * @since 3.0 + */ +public abstract class ContextBasedFormattingStrategy : IFormattingStrategy, IFormattingStrategyExtension { + + /** The current preferences for formatting */ + private Map fCurrentPreferences= null; + + /** The list of preferences for initiated the formatting steps */ + private const LinkedList fPreferences; + + this(){ + fPreferences= new LinkedList(); + } + + /* + * @see dwtx.jface.text.formatter.IFormattingStrategyExtension#format() + */ + public void format() { + fCurrentPreferences= cast(Map)fPreferences.removeFirst(); + } + + /* + * @see dwtx.jface.text.formatter.IFormattingStrategy#format(java.lang.String, bool, java.lang.String, int[]) + */ + public String format(String content, bool start, String indentation, int[] positions) { + return null; + } + + /* + * @see dwtx.jface.text.formatter.IFormattingStrategyExtension#formatterStarts(dwtx.jface.text.formatter.IFormattingContext) + */ + public void formatterStarts(IFormattingContext context) { + fPreferences.addLast(context.getProperty(stringcast(FormattingContextProperties.CONTEXT_PREFERENCES))); + } + + /* + * @see IFormattingStrategy#formatterStarts(String) + */ + public void formatterStarts(String indentation) { + // Do nothing + } + + /* + * @see dwtx.jface.text.formatter.IFormattingStrategyExtension#formatterStops() + */ + public void formatterStops() { + fPreferences.clear(); + + fCurrentPreferences= null; + } + + /** + * Returns the preferences used for the current formatting step. + * + * @return The preferences for the current formatting step + */ + public final Map getPreferences() { + return fCurrentPreferences; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/formatter/FormattingContext.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/formatter/FormattingContext.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.formatter.FormattingContext; + +import dwtx.jface.text.formatter.MultiPassContentFormatter; // packageimport +import dwtx.jface.text.formatter.ContextBasedFormattingStrategy; // packageimport +import dwtx.jface.text.formatter.IFormattingStrategy; // packageimport +import dwtx.jface.text.formatter.IContentFormatterExtension; // packageimport +import dwtx.jface.text.formatter.IFormattingStrategyExtension; // packageimport +import dwtx.jface.text.formatter.IContentFormatter; // packageimport +import dwtx.jface.text.formatter.FormattingContextProperties; // packageimport +import dwtx.jface.text.formatter.ContentFormatter; // packageimport +import dwtx.jface.text.formatter.IFormattingContext; // packageimport + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + +import dwtx.jface.preference.IPreferenceStore; + +/** + * Default implementation of IFormattingContext. + * + * @since 3.0 + */ +public class FormattingContext : IFormattingContext { + + /** Map to store the properties */ + private const Map fMap; + + this(){ + fMap= new HashMap(); + } + + /* + * @see dwtx.jface.text.formatter.IFormattingContext#dispose() + */ + public void dispose() { + fMap.clear(); + } + + /* + * @see dwtx.jface.text.formatter.IFormattingContext#getPreferenceKeys() + */ + public String[] getPreferenceKeys() { + return null; + } + + /* + * @see dwtx.jface.text.formatter.IFormattingContext#getProperty(java.lang.Object) + */ + public Object getProperty(Object key) { + return fMap.get(key); + } + + /* + * @see dwtx.jface.text.formatter.IFormattingContext#isBooleanPreference(java.lang.String) + */ + public bool isBooleanPreference(String key) { + return false; + } + + /* + * @see dwtx.jface.text.formatter.IFormattingContext#isDoublePreference(java.lang.String) + */ + public bool isDoublePreference(String key) { + return false; + } + + /* + * @see dwtx.jface.text.formatter.IFormattingContext#isFloatPreference(java.lang.String) + */ + public bool isFloatPreference(String key) { + return false; + } + + /* + * @see dwtx.jface.text.formatter.IFormattingContext#isIntegerPreference(java.lang.String) + */ + public bool isIntegerPreference(String key) { + return false; + } + + /* + * @see dwtx.jface.text.formatter.IFormattingContext#isLongPreference(java.lang.String) + */ + public bool isLongPreference(String key) { + return false; + } + + /* + * @see dwtx.jface.text.formatter.IFormattingContext#isStringPreference(java.lang.String) + */ + public bool isStringPreference(String key) { + return false; + } + + /* + * @see dwtx.jface.text.formatter.IFormattingContext#mapToStore(java.util.Map, dwtx.jface.preference.IPreferenceStore) + */ + public void mapToStore(Map map, IPreferenceStore store) { + + final String[] preferences= getPreferenceKeys(); + + String result= null; + String preference= null; + + for (int index= 0; index < preferences.length; index++) { + + preference= preferences[index]; + result= stringcast(map.get(preference)); + + if (result !is null) { + + try { + if (isBooleanPreference(preference)) { + store.setValue(preference, result.equals(IPreferenceStore.TRUE)); + } else if (isIntegerPreference(preference)) { + store.setValue(preference, Integer.parseInt(result)); + } else if (isStringPreference(preference)) { + store.setValue(preference, result); + } else if (isDoublePreference(preference)) { + store.setValue(preference, Double.parseDouble(result)); + } else if (isFloatPreference(preference)) { + store.setValue(preference, Float.parseFloat(result)); + } else if (isLongPreference(preference)) { + store.setValue(preference, Long.parseLong(result)); + } + } catch (NumberFormatException exception) { + // Do nothing + } + } + } + } + + /* + * @see dwtx.jface.text.formatter.IFormattingContext#setProperty(java.lang.Object, java.lang.Object) + */ + public void setProperty(Object key, Object property) { + fMap.put(key, property); + } + + /* + * @see dwtx.jface.text.formatter.IFormattingContext#storeToMap(dwtx.jface.preference.IPreferenceStore, java.util.Map, bool) + */ + public void storeToMap(IPreferenceStore store, Map map, bool useDefault) { + + final String[] preferences= getPreferenceKeys(); + + String preference= null; + for (int index= 0; index < preferences.length; index++) { + + preference= preferences[index]; + + if (isBooleanPreference(preference)) { + map.put(preference, (useDefault ? store.getDefaultBoolean(preference) : store.getBoolean(preference)) ? IPreferenceStore.TRUE : IPreferenceStore.FALSE); + } else if (isIntegerPreference(preference)) { + map.put(preference, String_valueOf(useDefault ? store.getDefaultInt(preference) : store.getInt(preference))); + } else if (isStringPreference(preference)) { + map.put(preference, useDefault ? store.getDefaultString(preference) : store.getString(preference)); + } else if (isDoublePreference(preference)) { + map.put(preference, String_valueOf(useDefault ? store.getDefaultDouble(preference) : store.getDouble(preference))); + } else if (isFloatPreference(preference)) { + map.put(preference, String_valueOf(useDefault ? store.getDefaultFloat(preference) : store.getFloat(preference))); + } else if (isLongPreference(preference)) { + map.put(preference, String_valueOf(useDefault ? store.getDefaultLong(preference) : store.getLong(preference))); + } + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/formatter/FormattingContextProperties.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/formatter/FormattingContextProperties.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.formatter.FormattingContextProperties; + +import dwtx.jface.text.formatter.MultiPassContentFormatter; // packageimport +import dwtx.jface.text.formatter.ContextBasedFormattingStrategy; // packageimport +import dwtx.jface.text.formatter.FormattingContext; // packageimport +import dwtx.jface.text.formatter.IFormattingStrategy; // packageimport +import dwtx.jface.text.formatter.IContentFormatterExtension; // packageimport +import dwtx.jface.text.formatter.IFormattingStrategyExtension; // packageimport +import dwtx.jface.text.formatter.IContentFormatter; // packageimport +import dwtx.jface.text.formatter.ContentFormatter; // packageimport +import dwtx.jface.text.formatter.IFormattingContext; // packageimport + +import dwt.dwthelper.utils; + +/** + * Keys used by IFormattingContext objects to register specific + * properties needed during the formatting process of a content formatter + * implementing IContentFormatterExtension. + * + * @see IFormattingContext + * @see IFormattingStrategyExtension + * @see IContentFormatterExtension + * @since 3.0 + */ +public class FormattingContextProperties { + + /** + * Property key of the document property. The property must implement + * java.lang#Boolean. If set to true the whole + * document is formatted. + *

                + * Value: "formatting.context.document" + */ + public static const String CONTEXT_DOCUMENT= "formatting.context.document"; //$NON-NLS-1$ + + /** + * Property key of the partition property. The property must implement + * dwtx.jface.text#TypedPosition. The partition + * a context based formatting strategy should format. + *

                + * Value: "formatting.context.partition" + */ + public static const String CONTEXT_PARTITION= "formatting.context.partition"; //$NON-NLS-1$ + + /** + * Property key of the preferences property. The property must implement + * java.util#Map. The formatting preferences mapping preference + * keys to values. + *

                + * Value: "formatting.context.preferences" + */ + public static const String CONTEXT_PREFERENCES= "formatting.context.preferences"; //$NON-NLS-1$ + + /** + * Property key of the region property. The property must implement dwtx.jface.text#IRegion. + * The region to format. If set, {@link FormattingContextProperties#CONTEXT_DOCUMENT} should be false + * for this to take effect. + *

                + * Value: "formatting.context.region" + */ + public static const String CONTEXT_REGION= "formatting.context.region"; //$NON-NLS-1$ + + /** + * Property key of the medium property. The property must implement dwtx.jface.text#IDocument. + * The document to format. + *

                + * Value: "formatting.context.medium" + */ + public static const String CONTEXT_MEDIUM= "formatting.context.medium"; //$NON-NLS-1$ + + /** + * Ensure that this class cannot be instantiated. + */ + private this() { + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/formatter/IContentFormatter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/formatter/IContentFormatter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.formatter.IContentFormatter; + +import dwtx.jface.text.formatter.MultiPassContentFormatter; // packageimport +import dwtx.jface.text.formatter.ContextBasedFormattingStrategy; // packageimport +import dwtx.jface.text.formatter.FormattingContext; // packageimport +import dwtx.jface.text.formatter.IFormattingStrategy; // packageimport +import dwtx.jface.text.formatter.IContentFormatterExtension; // packageimport +import dwtx.jface.text.formatter.IFormattingStrategyExtension; // packageimport +import dwtx.jface.text.formatter.FormattingContextProperties; // packageimport +import dwtx.jface.text.formatter.ContentFormatter; // packageimport +import dwtx.jface.text.formatter.IFormattingContext; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; + + +/** + * The interface of a document content formatter. The formatter formats ranges + * within documents. The documents are modified by the formatter.

                + * The content formatter is assumed to determine the partitioning of the document + * range to be formatted. For each partition, the formatter determines based + * on the partition's content type the formatting strategy to be used. Before + * the first strategy is activated all strategies are informed about the + * start of the formatting process. After that, the formatting strategies are + * activated in the sequence defined by the partitioning of the document range to be + * formatted. It is assumed that a strategy must be finished before the next strategy + * can be activated. After the last strategy has been finished, all strategies are + * informed about the termination of the formatting process.

                + *

                + * The interface can be implemented by clients. By default, clients use ContentFormatter + * or MultiPassContentFormatter as the standard implementers of this interface.

                + * + * @see IDocument + * @see IFormattingStrategy + */ +public interface IContentFormatter { + + /** + * Formats the given region of the specified document.The formatter may safely + * assume that it is the only subject that modifies the document at this point in time. + * + * @param document the document to be formatted + * @param region the region within the document to be formatted + */ + void format(IDocument document, IRegion region); + + /** + * Returns the formatting strategy registered for the given content type. + * + * @param contentType the content type for which to look up the formatting strategy + * @return the formatting strategy for the given content type, or + * null if there is no such strategy + */ + IFormattingStrategy getFormattingStrategy(String contentType); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/formatter/IContentFormatterExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/formatter/IContentFormatterExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.formatter.IContentFormatterExtension; + +import dwtx.jface.text.formatter.MultiPassContentFormatter; // packageimport +import dwtx.jface.text.formatter.ContextBasedFormattingStrategy; // packageimport +import dwtx.jface.text.formatter.FormattingContext; // packageimport +import dwtx.jface.text.formatter.IFormattingStrategy; // packageimport +import dwtx.jface.text.formatter.IFormattingStrategyExtension; // packageimport +import dwtx.jface.text.formatter.IContentFormatter; // packageimport +import dwtx.jface.text.formatter.FormattingContextProperties; // packageimport +import dwtx.jface.text.formatter.ContentFormatter; // packageimport +import dwtx.jface.text.formatter.IFormattingContext; // packageimport + +import dwt.dwthelper.utils; + +import dwtx.jface.text.IDocument; + +/** + * Extension interface for {@link IContentFormatter}. + *

                + * Updates the content formatter to be able to pass {@link IFormattingContext} + * context objects to {@link IFormattingStrategyExtension} objects + * operating in context based mode. + *

                + * Clients using context based formatting call the method + * format(IDocument, IFormattingContext) with a properly + * initialized formatting context.
                + * The formatting context must be set up according to the desired formatting mode: + *

                  + *
                • For whole document formatting set the property {@link FormattingContextProperties#CONTEXT_DOCUMENT}. + * This is equivalent to setting {@link FormattingContextProperties#CONTEXT_REGION} with a region spanning + * the whole document.
                • + *
                • For multiple region formatting set the property {@link FormattingContextProperties#CONTEXT_REGION}. + * Note that the content formatter automatically aligns the region to a block selected region, + * and if the region spans multiple partitions, it also completes eventual partitions covered only + * partially by the region.
                • + *
                + * Depending on the registered formatting strategies, more context information must + * be passed in the formatting context, like e.g. {@link FormattingContextProperties#CONTEXT_PREFERENCES}. + *

                + * Note that in context based mode the content formatter is fully reentrant, but not + * thread-safe. + *

                + * + * @see IFormattingContext + * @see FormattingContextProperties + * @since 3.0 + */ +public interface IContentFormatterExtension { + + /** + * Formats the given region of the specified document. + *

                + * The formatter may safely assume that it is the only subject that + * modifies the document at this point in time. This method is fully + * reentrant, but not thread-safe. + *

                + * The formatting process performed by format(IDocument, IFormattingContext) + * happens as follows: + *

                  + *
                • In a first pass the content formatter formats the range of the + * document to be formatted by using the master formatting strategy. This + * happens regardless of the content type of the underlying partition. + *
                • + *
                • In the second pass, the range is formatted again, this time using + * the registered slave formatting strategies. For each partition contained + * in the range to be formatted, the content formatter determines its + * content type and formats the partition with the correct formatting + * strategy. + *
                • + * + * @param document + * The document to be formatted + * @param context + * The formatting context to pass to the formatting strategies. + * This argument must not be null. + */ + void format(IDocument document, IFormattingContext context); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/formatter/IFormattingContext.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/formatter/IFormattingContext.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.formatter.IFormattingContext; + +import dwtx.jface.text.formatter.MultiPassContentFormatter; // packageimport +import dwtx.jface.text.formatter.ContextBasedFormattingStrategy; // packageimport +import dwtx.jface.text.formatter.FormattingContext; // packageimport +import dwtx.jface.text.formatter.IFormattingStrategy; // packageimport +import dwtx.jface.text.formatter.IContentFormatterExtension; // packageimport +import dwtx.jface.text.formatter.IFormattingStrategyExtension; // packageimport +import dwtx.jface.text.formatter.IContentFormatter; // packageimport +import dwtx.jface.text.formatter.FormattingContextProperties; // packageimport +import dwtx.jface.text.formatter.ContentFormatter; // packageimport + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + +import dwtx.jface.preference.IPreferenceStore; + +/** + * Formatting context used in formatting strategies implementing interface + * IFormattingStrategyExtension. + * + * @see IFormattingStrategyExtension + * @since 3.0 + */ +public interface IFormattingContext { + + /** + * Dispose of the formatting context. + *

                  + * Must be called after the formatting context has been used in a + * formatting process. + */ + void dispose(); + + /** + * Returns the preference keys used for the retrieval of formatting + * preferences. + * + * @return The preference keys for formatting + */ + String[] getPreferenceKeys(); + + /** + * Retrieves the property key from the formatting context + * + * @param key + * Key of the property to store in the context + * @return The property key if available, null + * otherwise + */ + Object getProperty(Object key); + + /** + * Is this preference key for a bool preference? + * + * @param key + * The preference key to query its type + * @return true iff this key is for a bool preference, + * false otherwise. + */ + bool isBooleanPreference(String key); + + /** + * Is this preference key for a double preference? + * + * @param key + * The preference key to query its type + * @return true iff this key is for a double preference, + * false otherwise. + */ + bool isDoublePreference(String key); + + /** + * Is this preference key for a float preference? + * + * @param key + * The preference key to query its type + * @return true iff this key is for a float preference, + * false otherwise. + */ + bool isFloatPreference(String key); + + /** + * Is this preference key for an integer preference? + * + * @param key + * The preference key to query its type + * @return true iff this key is for an integer preference, + * false otherwise. + */ + bool isIntegerPreference(String key); + + /** + * Is this preference key for a long preference? + * + * @param key + * The preference key to query its type + * @return true iff this key is for a long preference, + * false otherwise. + */ + bool isLongPreference(String key); + + /** + * Is this preference key for a string preference? + * + * @param key + * The preference key to query its type + * @return true iff this key is for a string preference, + * false otherwise. + */ + bool isStringPreference(String key); + + /** + * Stores the preferences from a map to a preference store. + *

                  + * Note that the preference keys returned by + * {@link #getPreferenceKeys()} must not be used in the preference store. + * Otherwise the preferences are overwritten. + *

                  + * + * @param map + * Map to retrieve the preferences from + * @param store + * Preference store to store the preferences in + */ + void mapToStore(Map map, IPreferenceStore store); + + /** + * Stores the property key in the formatting context. + * + * @param key + * Key of the property to store in the context + * @param property + * Property to store in the context. If already present, the new + * property overwrites the present one. + */ + void setProperty(Object key, Object property); + + /** + * Retrieves the preferences from a preference store in a map. + *

                  + * Note that the preference keys returned by + * {@link #getPreferenceKeys()} must not be used in the map. Otherwise the + * preferences are overwritten. + *

                  + * + * @param store + * Preference store to retrieve the preferences from + * @param map + * Map to store the preferences in + * @param useDefault + * true if the default preferences should be + * used, false otherwise + */ + void storeToMap(IPreferenceStore store, Map map, bool useDefault); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/formatter/IFormattingStrategy.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/formatter/IFormattingStrategy.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.formatter.IFormattingStrategy; + +import dwtx.jface.text.formatter.MultiPassContentFormatter; // packageimport +import dwtx.jface.text.formatter.ContextBasedFormattingStrategy; // packageimport +import dwtx.jface.text.formatter.FormattingContext; // packageimport +import dwtx.jface.text.formatter.IContentFormatterExtension; // packageimport +import dwtx.jface.text.formatter.IFormattingStrategyExtension; // packageimport +import dwtx.jface.text.formatter.IContentFormatter; // packageimport +import dwtx.jface.text.formatter.FormattingContextProperties; // packageimport +import dwtx.jface.text.formatter.ContentFormatter; // packageimport +import dwtx.jface.text.formatter.IFormattingContext; // packageimport + +import dwt.dwthelper.utils; + + +/** + * A formatting strategy is assumed to be specialized on formatting text + * of a particular content type. Each formatting process calls the strategy's + * methods in the following sequence: + *
                    + *
                  • formatterStarts + *
                  • format + *
                  • formatterStops + *
                  + *

                  + * This interface must be implemented by clients. Implementers should be registered with + * a content formatter in order get involved in the formatting process.

                  + */ +public interface IFormattingStrategy { + + /** + * Informs the strategy about the start of a formatting process in which it will + * participate. + * + * @param initialIndentation the indent string of the first line at which the + * overall formatting process starts. + */ + void formatterStarts(String initialIndentation); + + /** + * Formats the given string. During the formatting process this strategy must update + * the given character positions according to the changes applied to the given string. + * + * @param content the initial string to be formatted + * @param isLineStart indicates whether the beginning of content is a line start in its document + * @param indentation the indentation string to be used + * @param positions the character positions to be updated + * @return the formatted string + */ + String format(String content, bool isLineStart, String indentation, int[] positions); + + /** + * Informs the strategy that the formatting process in which it has participated + * has been finished. + */ + void formatterStops(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/formatter/IFormattingStrategyExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/formatter/IFormattingStrategyExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.formatter.IFormattingStrategyExtension; + +import dwtx.jface.text.formatter.MultiPassContentFormatter; // packageimport +import dwtx.jface.text.formatter.ContextBasedFormattingStrategy; // packageimport +import dwtx.jface.text.formatter.FormattingContext; // packageimport +import dwtx.jface.text.formatter.IFormattingStrategy; // packageimport +import dwtx.jface.text.formatter.IContentFormatterExtension; // packageimport +import dwtx.jface.text.formatter.IContentFormatter; // packageimport +import dwtx.jface.text.formatter.FormattingContextProperties; // packageimport +import dwtx.jface.text.formatter.ContentFormatter; // packageimport +import dwtx.jface.text.formatter.IFormattingContext; // packageimport + +import dwt.dwthelper.utils; + +/** + * Extension interface for IFormattingStrategy. + *

                  + * Updates formatting strategies to be able to receive a more general IFormattingContext + * object from its associated content formatters. + *

                  + * Each formatting process calls the strategy's methods in the following + * sequence: + *

                    + *
                  • formatterStarts + *
                  • format + *
                  • formatterStops + *
                  + *

                  + * Note that multiple calls to formatterStarts can be issued to + * a strategy before launching the formatting process with format. + *

                  + * This interface must be implemented by clients. Implementers should be + * registered with a content formatter in order get involved in the formatting + * process. + * + * @see IFormattingContext + * @since 3.0 + */ +public interface IFormattingStrategyExtension { + + /** + * Formats the region with the properties indicated in the formatting + * context previously supplied by formatterStarts(IFormattingContext). + */ + void format(); + + /** + * Informs the strategy about the start of a formatting process in which it + * will participate. + * + * @param context + * Formatting context used in the corresponding formatting + * process. + */ + void formatterStarts(IFormattingContext context); + + /** + * Informs the strategy that the formatting process in which it has + * participated has been finished. + */ + void formatterStops(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/formatter/MultiPassContentFormatter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/formatter/MultiPassContentFormatter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,333 @@ +/******************************************************************************* + * 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 + * 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.text.formatter.MultiPassContentFormatter; + +import dwtx.jface.text.formatter.ContextBasedFormattingStrategy; // packageimport +import dwtx.jface.text.formatter.FormattingContext; // packageimport +import dwtx.jface.text.formatter.IFormattingStrategy; // packageimport +import dwtx.jface.text.formatter.IContentFormatterExtension; // packageimport +import dwtx.jface.text.formatter.IFormattingStrategyExtension; // packageimport +import dwtx.jface.text.formatter.IContentFormatter; // packageimport +import dwtx.jface.text.formatter.FormattingContextProperties; // packageimport +import dwtx.jface.text.formatter.ContentFormatter; // packageimport +import dwtx.jface.text.formatter.IFormattingContext; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.DefaultPositionUpdater; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITypedRegion; +import dwtx.jface.text.TextUtilities; +import dwtx.jface.text.TypedPosition; + +/** + * Content formatter for edit-based formatting strategies. + *

                  + * Two kinds of formatting strategies can be registered with this formatter: + *

                    + *
                  • one master formatting strategy for the default content type
                  • + *
                  • one formatting strategy for each non-default content type
                  • + *
                  + * The master formatting strategy always formats the whole region to be + * formatted in the first pass. In a second pass, all partitions of the region + * to be formatted that are not of master content type are formatted using the + * slave formatting strategy registered for the underlying content type. All + * formatting strategies must implement {@link IFormattingStrategyExtension}. + *

                  + * Regions to be formatted with the master formatting strategy always have + * an offset aligned to the line start. Regions to be formatted with slave formatting + * strategies are aligned on partition boundaries. + * + * @see IFormattingStrategyExtension + * @since 3.0 + */ +public class MultiPassContentFormatter : IContentFormatter, IContentFormatterExtension { + + /** + * Position updater that shifts otherwise deleted positions to the next + * non-whitespace character. The length of the positions are truncated to + * one if the position was shifted. + */ + protected class NonDeletingPositionUpdater : DefaultPositionUpdater { + + /** + * Creates a new non-deleting position updater. + * + * @param category The position category to update its positions + */ + public this(String category) { + super(category); + } + + /* + * @see dwtx.jface.text.DefaultPositionUpdater#notDeleted() + */ + protected final bool notDeleted() { + + if (fOffset < fPosition.offset && (fPosition.offset + fPosition.length < fOffset + fLength)) { + + int offset= fOffset + fLength; + if (offset < fDocument.getLength()) { + + try { + + bool moved= false; + char character= fDocument.getChar(offset); + + while (offset < fDocument.getLength() && Character.isWhitespace(character)) { + + moved= true; + character= fDocument.getChar(offset++); + } + + if (moved) + offset--; + + } catch (BadLocationException exception) { + // Can not happen + } + + fPosition.offset= offset; + fPosition.length= 0; + } + } + return true; + } + } + + /** The master formatting strategy */ + private IFormattingStrategyExtension fMaster= null; + /** The partitioning of this content formatter */ + private const String fPartitioning; + /** The slave formatting strategies */ + private const Map fSlaves; + /** The default content type */ + private const String fType; + + /** + * Creates a new content formatter. + * + * @param partitioning the document partitioning for this formatter + * @param type the default content type + */ + public this(String partitioning, String type) { + fSlaves= new HashMap(); + + fPartitioning= partitioning; + fType= type; + } + + /* + * @see dwtx.jface.text.formatter.IContentFormatterExtension#format(dwtx.jface.text.IDocument, dwtx.jface.text.formatter.IFormattingContext) + */ + public final void format(IDocument medium, IFormattingContext context) { + + context.setProperty(stringcast(FormattingContextProperties.CONTEXT_MEDIUM), cast(Object)medium); + + final Boolean document= cast(Boolean)context.getProperty(stringcast(FormattingContextProperties.CONTEXT_DOCUMENT)); + if (document is null || !document.booleanValue()) { + + final IRegion region= cast(IRegion)context.getProperty(stringcast(FormattingContextProperties.CONTEXT_REGION)); + if (region !is null) { + try { + formatMaster(context, medium, region.getOffset(), region.getLength()); + } finally { + formatSlaves(context, medium, region.getOffset(), region.getLength()); + } + } + } else { + try { + formatMaster(context, medium, 0, medium.getLength()); + } finally { + formatSlaves(context, medium, 0, medium.getLength()); + } + } + } + + /* + * @see dwtx.jface.text.formatter.IContentFormatter#format(dwtx.jface.text.IDocument, dwtx.jface.text.IRegion) + */ + public final void format(IDocument medium, IRegion region) { + + final FormattingContext context= new FormattingContext(); + + context.setProperty(stringcast(FormattingContextProperties.CONTEXT_DOCUMENT), Boolean.FALSE); + context.setProperty(stringcast(FormattingContextProperties.CONTEXT_REGION), cast(Object)region); + + format(medium, context); + } + + /** + * Formats the document specified in the formatting context with the master + * formatting strategy. + *

                  + * The master formatting strategy covers all regions of the document. The + * offset of the region to be formatted is aligned on line start boundaries, + * whereas the end index of the region remains the same. For this formatting + * type the document partitioning is not taken into account. + * + * @param context The formatting context to use + * @param document The document to operate on + * @param offset The offset of the region to format + * @param length The length of the region to format + */ + protected void formatMaster(IFormattingContext context, IDocument document, int offset, int length) { + + try { + + final int delta= offset - document.getLineInformationOfOffset(offset).getOffset(); + offset -= delta; + length += delta; + + } catch (BadLocationException exception) { + // Do nothing + } + + if (fMaster !is null) { + + context.setProperty(stringcast(FormattingContextProperties.CONTEXT_PARTITION), new TypedPosition(offset, length, fType)); + + fMaster.formatterStarts(context); + fMaster.format(); + fMaster.formatterStops(); + } + } + + /** + * Formats the document specified in the formatting context with the + * formatting strategy registered for the content type. + *

                  + * For this formatting type only slave strategies are used. The region to be + * formatted is aligned on partition boundaries of the underlying content + * type. The exact formatting strategy is determined by the underlying + * content type of the document partitioning. + * + * @param context The formatting context to use + * @param document The document to operate on + * @param offset The offset of the region to format + * @param length The length of the region to format + * @param type The content type of the region to format + */ + protected void formatSlave(IFormattingContext context, IDocument document, int offset, int length, String type) { + + final IFormattingStrategyExtension strategy= cast(IFormattingStrategyExtension)fSlaves.get(type); + if (strategy !is null) { + + context.setProperty(stringcast(FormattingContextProperties.CONTEXT_PARTITION), new TypedPosition(offset, length, type)); + + strategy.formatterStarts(context); + strategy.format(); + strategy.formatterStops(); + } + } + + /** + * Formats the document specified in the formatting context with the slave + * formatting strategies. + *

                  + * For each content type of the region to be formatted in the document + * partitioning, the registered slave formatting strategy is used to format + * that particular region. The region to be formatted is aligned on + * partition boundaries of the underlying content type. If the content type + * is the document's default content type, nothing happens. + * + * @param context The formatting context to use + * @param document The document to operate on + * @param offset The offset of the region to format + * @param length The length of the region to format + */ + protected void formatSlaves(IFormattingContext context, IDocument document, int offset, int length) { + + Map partitioners= new HashMap(0); + try { + + final ITypedRegion[] partitions= TextUtilities.computePartitioning(document, fPartitioning, offset, length, false); + + if (!fType.equals(partitions[0].getType())) + partitions[0]= TextUtilities.getPartition(document, fPartitioning, partitions[0].getOffset(), false); + + if (partitions.length > 1) { + + if (!fType.equals(partitions[partitions.length - 1].getType())) + partitions[partitions.length - 1]= TextUtilities.getPartition(document, fPartitioning, partitions[partitions.length - 1].getOffset(), false); + } + + String type= null; + ITypedRegion partition= null; + + partitioners= TextUtilities.removeDocumentPartitioners(document); + + for (int index= partitions.length - 1; index >= 0; index--) { + + partition= partitions[index]; + type= partition.getType(); + + if (!fType.equals(type)) + formatSlave(context, document, partition.getOffset(), partition.getLength(), type); + } + + } catch (BadLocationException exception) { + // Should not happen + } finally { + TextUtilities.addDocumentPartitioners(document, partitioners); + } + } + + /* + * @see dwtx.jface.text.formatter.IContentFormatter#getFormattingStrategy(java.lang.String) + */ + public final IFormattingStrategy getFormattingStrategy(String type) { + return null; + } + + /** + * Registers a master formatting strategy. + *

                  + * The strategy may already be registered with a certain content type as + * slave strategy. The master strategy is registered for the default content + * type of documents. If a master strategy has already been registered, it + * is overridden by the new one. + * + * @param strategy The master formatting strategy, must implement + * {@link IFormattingStrategyExtension} + */ + public final void setMasterStrategy(IFormattingStrategy strategy) { + Assert.isTrue( null !is cast(IFormattingStrategyExtension)strategy ); + fMaster= cast(IFormattingStrategyExtension) strategy; + } + + /** + * Registers a slave formatting strategy for a certain content type. + *

                  + * The strategy may already be registered as master strategy. An + * already registered slave strategy for the specified content type + * will be replaced. However, the same strategy may be registered with + * several content types. Slave strategies cannot be registered for the + * default content type of documents. + * + * @param strategy The slave formatting strategy + * @param type The content type to register this strategy with, + * must implement {@link IFormattingStrategyExtension} + */ + public final void setSlaveStrategy(IFormattingStrategy strategy, String type) { + Assert.isTrue( null !is cast(IFormattingStrategyExtension)strategy ); + if (!fType.equals(type)) + fSlaves.put(type, cast(Object)strategy); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/hyperlink/AbstractHyperlinkDetector.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/hyperlink/AbstractHyperlinkDetector.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,90 @@ +/******************************************************************************* + * 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.text.hyperlink.AbstractHyperlinkDetector; + +import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport +import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport +import dwtx.jface.text.hyperlink.IHyperlink; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.core.runtime.Assert; +import dwtx.core.runtime.IAdaptable; + + +/** + * A hyperlink detector that can provide adapters through + * a context that can be set by the creator of this hyperlink + * detector. + *

                  + * Clients may subclass. + *

                  + * + * @since 3.3 + */ +public abstract class AbstractHyperlinkDetector : IHyperlinkDetector, IHyperlinkDetectorExtension { + + /** + * The context of this hyperlink detector. + */ + private IAdaptable fContext; + + /** + * Sets this hyperlink detector's context which + * is responsible to provide the adapters. + * + * @param context the context for this hyperlink detector + * @throws IllegalArgumentException if the context is null + * @throws IllegalStateException if this method is called more than once + */ + public final void setContext(IAdaptable context) { + Assert.isLegal(context !is null); + if (fContext !is null) + throw new IllegalStateException(); + fContext= context; + } + + /* + * @see dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension#dispose() + */ + public void dispose() { + fContext= null; + } + + /** + * Returns an object which is an instance of the given class + * and provides additional context for this hyperlink detector. + * + * @param adapterClass the adapter class to look up + * @return an instance that can be cast to the given class, + * or null if this object does not + * have an adapter for the given class + */ + protected final Object getAdapter(ClassInfo adapterClass) { + Assert.isLegal(adapterClass !is null); + if (fContext !is null) + return fContext.getAdapter(adapterClass); + return null; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/hyperlink/DefaultHyperlinkPresenter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/hyperlink/DefaultHyperlinkPresenter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,396 @@ +/******************************************************************************* + * 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 + * 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.text.hyperlink.DefaultHyperlinkPresenter; + +import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport +import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport +import dwtx.jface.text.hyperlink.IHyperlink; // packageimport + + +import dwt.dwthelper.utils; + + + + + +import dwt.DWT; +import dwt.custom.StyleRange; +import dwt.custom.StyledText; +import dwt.graphics.Color; +import dwt.graphics.Cursor; +import dwt.graphics.RGB; +import dwt.widgets.Display; +import dwtx.core.runtime.Assert; +import dwtx.jface.preference.IPreferenceStore; +import dwtx.jface.preference.PreferenceConverter; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentListener; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextInputListener; +import dwtx.jface.text.ITextPresentationListener; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.ITextViewerExtension2; +import dwtx.jface.text.ITextViewerExtension4; +import dwtx.jface.text.Position; +import dwtx.jface.text.Region; +import dwtx.jface.text.TextPresentation; +import dwtx.jface.util.IPropertyChangeListener; +import dwtx.jface.util.PropertyChangeEvent; + + +/** + * The default hyperlink presenter underlines the + * link and colors the line and the text with + * the given color. + *

                  + * It can only be used together with the {@link HyperlinkManager#FIRST} + * or the {@link HyperlinkManager#LONGEST_REGION_FIRST} hyperlink strategy. + *

                  + * + * @since 3.1 + */ +public class DefaultHyperlinkPresenter : IHyperlinkPresenter, IHyperlinkPresenterExtension, ITextPresentationListener, ITextInputListener, IDocumentListener, IPropertyChangeListener { + + /** + * A named preference that holds the color used for hyperlinks. + *

                  + * Value is of type String. A RGB color value encoded as a string + * using class PreferenceConverter + *

                  + * + * @see dwtx.jface.resource.StringConverter + * @see dwtx.jface.preference.PreferenceConverter + */ + public const static String HYPERLINK_COLOR= "hyperlinkColor"; //$NON-NLS-1$ + + + /** The text viewer. */ + private ITextViewer fTextViewer; + /** The hand cursor. */ + private Cursor fCursor; + /** The link color. */ + private Color fColor; + /** The link color specification. May be null. */ + private RGB fRGB; + /** Tells whether to dispose the color on uninstall. */ + private bool fDisposeColor; + /** The currently active region. */ + private IRegion fActiveRegion; + /** The currently active style range as position. */ + private Position fRememberedPosition; + /** The optional preference store. May be null. */ + private IPreferenceStore fPreferenceStore; + + + /** + * Creates a new default hyperlink presenter which uses + * {@link #HYPERLINK_COLOR} to read the color from the given preference store. + * + * @param store the preference store + */ + public this(IPreferenceStore store) { + fPreferenceStore= store; + fDisposeColor= true; + } + + /** + * Creates a new default hyperlink presenter. + * + * @param color the hyperlink color, to be disposed by the caller + */ + public this(Color color) { + fDisposeColor= false; + fColor= color; + } + + /** + * Creates a new default hyperlink presenter. + * + * @param color the hyperlink color + */ + public this(RGB color) { + fRGB= color; + fDisposeColor= true; + } + + /* + * @see dwtx.jdt.internal.ui.javaeditor.IHyperlinkControl#canShowMultipleHyperlinks() + */ + public bool canShowMultipleHyperlinks() { + return false; + } + + /* + * @see dwtx.jdt.internal.ui.javaeditor.IHyperlinkControl#activate(dwtx.jdt.internal.ui.javaeditor.IHyperlink[]) + */ + public void showHyperlinks(IHyperlink[] hyperlinks) { + Assert.isLegal(hyperlinks !is null && hyperlinks.length is 1); + highlightRegion(hyperlinks[0].getHyperlinkRegion()); + activateCursor(); + } + + /** + * {@inheritDoc} + * + * @since 3.4 + */ + public bool canHideHyperlinks() { + return true; + } + + /* + * @see dwtx.jdt.internal.ui.javaeditor.IHyperlinkControl#deactivate() + */ + public void hideHyperlinks() { + repairRepresentation(); + fRememberedPosition= null; + } + + /* + * @see dwtx.jdt.internal.ui.javaeditor.IHyperlinkControl#install(dwtx.jface.text.ITextViewer) + */ + public void install(ITextViewer textViewer) { + Assert.isNotNull(cast(Object)textViewer); + fTextViewer= textViewer; + fTextViewer.addTextInputListener(this); + if ( cast(ITextViewerExtension4)fTextViewer ) + (cast(ITextViewerExtension4)fTextViewer).addTextPresentationListener(this); + + StyledText text= fTextViewer.getTextWidget(); + if (text !is null && !text.isDisposed()) { + if (fPreferenceStore !is null) + fColor= createColor(fPreferenceStore, HYPERLINK_COLOR, text.getDisplay()); + else if (fRGB !is null) + fColor= new Color(text.getDisplay(), fRGB); + } + + if (fPreferenceStore !is null) + fPreferenceStore.addPropertyChangeListener(this); + } + + /* + * @see dwtx.jdt.internal.ui.javaeditor.IHyperlinkControl#uninstall() + */ + public void uninstall() { + fTextViewer.removeTextInputListener(this); + IDocument document= fTextViewer.getDocument(); + if (document !is null) + document.removeDocumentListener(this); + + if (fColor !is null) { + if (fDisposeColor) + fColor.dispose(); + fColor= null; + } + + if (fCursor !is null) { + fCursor.dispose(); + fCursor= null; + } + + if ( cast(ITextViewerExtension4)fTextViewer ) + (cast(ITextViewerExtension4)fTextViewer).removeTextPresentationListener(this); + fTextViewer= null; + + if (fPreferenceStore !is null) + fPreferenceStore.removePropertyChangeListener(this); + } + + public void setColor(Color color) { + Assert.isNotNull(cast(Object)fTextViewer); + fColor= color; + } + + /* + * @see dwtx.jface.text.ITextPresentationListener#applyTextPresentation(dwtx.jface.text.TextPresentation) + */ + public void applyTextPresentation(TextPresentation textPresentation) { + if (fActiveRegion is null) + return; + IRegion region= textPresentation.getExtent(); + if (fActiveRegion.getOffset() + fActiveRegion.getLength() >= region.getOffset() && region.getOffset() + region.getLength() > fActiveRegion.getOffset()) { + StyleRange styleRange= new StyleRange(fActiveRegion.getOffset(), fActiveRegion.getLength(), fColor, null); + styleRange.underline= true; + textPresentation.mergeStyleRange(styleRange); + } + } + + private void highlightRegion(IRegion region) { + + if ((cast(Object)region).opEquals(cast(Object)fActiveRegion)) + return; + + repairRepresentation(); + + StyledText text= fTextViewer.getTextWidget(); + if (text is null || text.isDisposed()) + return; + + // Invalidate region is> apply text presentation + fActiveRegion= region; + if ( cast(ITextViewerExtension2)fTextViewer ) + (cast(ITextViewerExtension2)fTextViewer).invalidateTextPresentation(region.getOffset(), region.getLength()); + else + fTextViewer.invalidateTextPresentation(); + } + + private void activateCursor() { + StyledText text= fTextViewer.getTextWidget(); + if (text is null || text.isDisposed()) + return; + Display display= text.getDisplay(); + if (fCursor is null) + fCursor= new Cursor(display, DWT.CURSOR_HAND); + text.setCursor(fCursor); + } + + private void resetCursor() { + StyledText text= fTextViewer.getTextWidget(); + if (text !is null && !text.isDisposed()) + text.setCursor(null); + + if (fCursor !is null) { + fCursor.dispose(); + fCursor= null; + } + } + + private void repairRepresentation() { + + if (fActiveRegion is null) + return; + + int offset= fActiveRegion.getOffset(); + int length= fActiveRegion.getLength(); + fActiveRegion= null; + + resetCursor(); + + // Invalidate is> remove applied text presentation + if ( cast(ITextViewerExtension2)fTextViewer ) + (cast(ITextViewerExtension2) fTextViewer).invalidateTextPresentation(offset, length); + else + fTextViewer.invalidateTextPresentation(); + + } + + /* + * @see dwtx.jface.text.IDocumentListener#documentAboutToBeChanged(dwtx.jface.text.DocumentEvent) + */ + public void documentAboutToBeChanged(DocumentEvent event) { + if (fActiveRegion !is null) { + fRememberedPosition= new Position(fActiveRegion.getOffset(), fActiveRegion.getLength()); + try { + event.getDocument().addPosition(fRememberedPosition); + } catch (BadLocationException x) { + fRememberedPosition= null; + } + } + } + + /* + * @see dwtx.jface.text.IDocumentListener#documentChanged(dwtx.jface.text.DocumentEvent) + */ + public void documentChanged(DocumentEvent event) { + if (fRememberedPosition !is null) { + if (!fRememberedPosition.isDeleted()) { + event.getDocument().removePosition(fRememberedPosition); + fActiveRegion= new Region(fRememberedPosition.getOffset(), fRememberedPosition.getLength()); + } else { + fActiveRegion= new Region(event.getOffset(), event.getLength()); + } + fRememberedPosition= null; + + StyledText widget= fTextViewer.getTextWidget(); + if (widget !is null && !widget.isDisposed()) { + widget.getDisplay().asyncExec(new class() Runnable { + public void run() { + hideHyperlinks(); + } + }); + } + } + } + + /* + * @see dwtx.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument) + */ + public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { + if (oldInput is null) + return; + hideHyperlinks(); + oldInput.removeDocumentListener(this); + } + + /* + * @see dwtx.jface.text.ITextInputListener#inputDocumentChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument) + */ + public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { + if (newInput is null) + return; + newInput.addDocumentListener(this); + } + + /** + * Creates a color from the information stored in the given preference store. + * + * @param store the preference store + * @param key the key + * @param display the display + * @return the color or null if there is no such information available + */ + private Color createColor(IPreferenceStore store, String key, Display display) { + + RGB rgb= null; + + if (store.contains(key)) { + + if (store.isDefault(key)) + rgb= PreferenceConverter.getDefaultColor(store, key); + else + rgb= PreferenceConverter.getColor(store, key); + + if (rgb !is null) + return new Color(display, rgb); + } + + return null; + } + + /* + * @see dwtx.jface.util.IPropertyChangeListener#propertyChange(dwtx.jface.util.PropertyChangeEvent) + */ + public void propertyChange(PropertyChangeEvent event) { + if (!HYPERLINK_COLOR.equals(event.getProperty())) + return; + + if (fDisposeColor && fColor !is null && !fColor.isDisposed()) + fColor.dispose(); + fColor= null; + + StyledText textWidget= fTextViewer.getTextWidget(); + if (textWidget !is null && !textWidget.isDisposed()) + fColor= createColor(fPreferenceStore, HYPERLINK_COLOR, textWidget.getDisplay()); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/hyperlink/HyperlinkManager.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/hyperlink/HyperlinkManager.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,610 @@ +/******************************************************************************* + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Steffen Pingel (Tasktop Technologies Inc.) - [navigation] hyperlink decoration is not erased when mouse is moved out of Text widget - https://bugs.eclipse.org/bugs/show_bug.cgi?id=100278 + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.text.hyperlink.HyperlinkManager; + +import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport +import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport +import dwtx.jface.text.hyperlink.IHyperlink; // packageimport + + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; + +import dwt.DWT; +import dwt.custom.StyledText; +import dwt.events.FocusEvent; +import dwt.events.FocusListener; +import dwt.events.KeyEvent; +import dwt.events.KeyListener; +import dwt.events.MouseEvent; +import dwt.events.MouseListener; +import dwt.events.MouseMoveListener; +import dwt.events.MouseTrackListener; +import dwt.graphics.Point; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Listener; +import dwtx.core.runtime.Assert; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextListener; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.ITextViewerExtension5; +import dwtx.jface.text.Region; +import dwtx.jface.text.TextEvent; + + +/** + * Default implementation of a hyperlink manager. + * + * @since 3.1 + */ +public class HyperlinkManager : ITextListener, Listener, KeyListener, MouseListener, MouseMoveListener, FocusListener, MouseTrackListener { + + /** + * Detection strategy. + */ + public static final class DETECTION_STRATEGY { + + String fName; + + private this(String name) { + fName= name; + } + + /* + * @see java.lang.Object#toString() + */ + public override String toString() { + return fName; + } + } + + + /** + * The first detected hyperlink is passed to the + * hyperlink presenter and no further detector + * is consulted. + */ + private static DETECTION_STRATEGY FIRST_; + public static DETECTION_STRATEGY FIRST(){ + if( FIRST_ is null ){ + synchronized( HyperlinkManager.classinfo ){ + if( FIRST_ is null ){ + FIRST_ = new DETECTION_STRATEGY("first"); //$NON-NLS-1$ + } + } + } + return FIRST_; + } + + /** + * All detected hyperlinks from all detectors are collected + * and passed to the hyperlink presenter. + *

                  + * This strategy is only allowed if {@link IHyperlinkPresenter#canShowMultipleHyperlinks()} + * returns true. + *

                  + */ + private static DETECTION_STRATEGY ALL_; + public static DETECTION_STRATEGY ALL(){ + if( ALL_ is null ){ + synchronized( HyperlinkManager.classinfo ){ + if( ALL_ is null ){ + ALL_ = new DETECTION_STRATEGY("all"); //$NON-NLS-1$ + } + } + } + return ALL_; + } + + /** + * All detected hyperlinks from all detectors are collected + * and all those with the longest region are passed to the + * hyperlink presenter. + *

                  + * This strategy is only allowed if {@link IHyperlinkPresenter#canShowMultipleHyperlinks()} + * returns true. + *

                  + */ + private static DETECTION_STRATEGY LONGEST_REGION_ALL_; + public static DETECTION_STRATEGY LONGEST_REGION_ALL(){ + if( LONGEST_REGION_ALL_ is null ){ + synchronized( HyperlinkManager.classinfo ){ + if( LONGEST_REGION_ALL_ is null ){ + LONGEST_REGION_ALL_ = new DETECTION_STRATEGY("all with same longest region"); //$NON-NLS-1$ + } + } + } + return LONGEST_REGION_ALL_; + } + + /** + * All detected hyperlinks from all detectors are collected + * and form all those with the longest region only the first + * one is passed to the hyperlink presenter. + */ + private static DETECTION_STRATEGY LONGEST_REGION_FIRST_; + public static DETECTION_STRATEGY LONGEST_REGION_FIRST(){ + if( LONGEST_REGION_FIRST_ is null ){ + synchronized( HyperlinkManager.classinfo ){ + if( LONGEST_REGION_FIRST_ is null ){ + LONGEST_REGION_FIRST_ = new DETECTION_STRATEGY("first with longest region"); //$NON-NLS-1$ + } + } + } + return LONGEST_REGION_FIRST_; + } + + + /** The text viewer on which this hyperlink manager works. */ + private ITextViewer fTextViewer; + /** The session is active. */ + private bool fActive; + /** The key modifier mask. */ + private int fHyperlinkStateMask; + /** + * The active key modifier mask. + * @since 3.3 + */ + private int fActiveHyperlinkStateMask; + /** The active hyperlinks. */ + private IHyperlink[] fActiveHyperlinks; + /** The hyperlink detectors. */ + private IHyperlinkDetector[] fHyperlinkDetectors; + /** The hyperlink presenter. */ + private IHyperlinkPresenter fHyperlinkPresenter; + /** The detection strategy. */ + private const DETECTION_STRATEGY fDetectionStrategy; + + + /** + * Creates a new hyperlink manager. + * + * @param detectionStrategy the detection strategy one of {{@link #ALL}, {@link #FIRST}, {@link #LONGEST_REGION_ALL}, {@link #LONGEST_REGION_FIRST}} + */ + public this(DETECTION_STRATEGY detectionStrategy) { + Assert.isNotNull(detectionStrategy); + fDetectionStrategy= detectionStrategy; + } + + /** + * Installs this hyperlink manager with the given arguments. + * + * @param textViewer the text viewer + * @param hyperlinkPresenter the hyperlink presenter + * @param hyperlinkDetectors the array of hyperlink detectors, must not be empty + * @param eventStateMask the DWT event state mask to activate hyperlink mode + */ + public void install(ITextViewer textViewer, IHyperlinkPresenter hyperlinkPresenter, IHyperlinkDetector[] hyperlinkDetectors, int eventStateMask) { + Assert.isNotNull(cast(Object)textViewer); + Assert.isNotNull(cast(Object)hyperlinkPresenter); + fTextViewer= textViewer; + fHyperlinkPresenter= hyperlinkPresenter; + Assert.isLegal(fHyperlinkPresenter.canShowMultipleHyperlinks() || fDetectionStrategy is FIRST || fDetectionStrategy is LONGEST_REGION_FIRST); + setHyperlinkDetectors(hyperlinkDetectors); + setHyperlinkStateMask(eventStateMask); + + StyledText text= fTextViewer.getTextWidget(); + if (text is null || text.isDisposed()) + return; + + text.getDisplay().addFilter(DWT.KeyUp, this); + text.addKeyListener(this); + text.addMouseListener(this); + text.addMouseMoveListener(this); + text.addFocusListener(this); + text.addMouseTrackListener(this); + + fTextViewer.addTextListener(this); + + fHyperlinkPresenter.install(fTextViewer); + } + + /** + * Sets the hyperlink detectors for this hyperlink manager. + *

                  + * It is allowed to call this method after this + * hyperlink manger has been installed. + *

                  + * + * @param hyperlinkDetectors and array of hyperlink detectors, must not be empty + */ + public void setHyperlinkDetectors(IHyperlinkDetector[] hyperlinkDetectors) { + Assert.isTrue(hyperlinkDetectors !is null && hyperlinkDetectors.length > 0); + if (fHyperlinkDetectors is null){ + fHyperlinkDetectors= hyperlinkDetectors; + } + else { + synchronized (/+fHyperlinkDetectors+/this) { + fHyperlinkDetectors= hyperlinkDetectors; + } + } + } + + /** + * Sets the DWT event state mask which in combination + * with the left mouse button triggers the hyperlink mode. + *

                  + * It is allowed to call this method after this + * hyperlink manger has been installed. + *

                  + * + * @param eventStateMask the DWT event state mask to activate hyperlink mode + */ + public void setHyperlinkStateMask(int eventStateMask) { + fHyperlinkStateMask= eventStateMask; + } + + /** + * Uninstalls this hyperlink manager. + */ + public void uninstall() { + deactivate(); + + StyledText text= fTextViewer.getTextWidget(); + if (text !is null && !text.isDisposed()) { + text.removeKeyListener(this); + text.getDisplay().removeFilter(DWT.KeyUp, this); + text.removeMouseListener(this); + text.removeMouseMoveListener(this); + text.removeFocusListener(this); + text.removeMouseTrackListener(this); + } + fTextViewer.removeTextListener(this); + + fHyperlinkPresenter.uninstall(); + + fHyperlinkPresenter= null; + fTextViewer= null; + fHyperlinkDetectors= null; + } + + /** + * Deactivates the currently shown hyperlinks. + */ + protected void deactivate() { + fHyperlinkPresenter.hideHyperlinks(); + fActive= false; + } + + /** + * Finds hyperlinks at the current offset. + * + * @return the hyperlinks or null if none. + */ + protected IHyperlink[] findHyperlinks() { + int offset= getCurrentTextOffset(); + if (offset is -1) + return null; + + bool canShowMultipleHyperlinks= fHyperlinkPresenter.canShowMultipleHyperlinks(); + IRegion region= new Region(offset, 0); + List allHyperlinks= new ArrayList(fHyperlinkDetectors.length * 2); + synchronized (/+fHyperlinkDetectors+/this) { + for (int i= 0, length= fHyperlinkDetectors.length; i < length; i++) { + IHyperlinkDetector detector= fHyperlinkDetectors[i]; + if (detector is null) + continue; + + if ( cast(IHyperlinkDetectorExtension2)detector ) { + int stateMask= (cast(IHyperlinkDetectorExtension2)detector).getStateMask(); + if (stateMask !is -1 && stateMask !is fActiveHyperlinkStateMask) + continue; + else if (stateMask is -1 && fActiveHyperlinkStateMask !is fHyperlinkStateMask) + continue; + } else if (fActiveHyperlinkStateMask !is fHyperlinkStateMask) + continue; + + IHyperlink[] hyperlinks= detector.detectHyperlinks(fTextViewer, region, canShowMultipleHyperlinks); + if (hyperlinks is null) + continue; + + Assert.isLegal(hyperlinks.length > 0); + + if (fDetectionStrategy is FIRST) { + if (hyperlinks.length is 1) + return hyperlinks; + return [hyperlinks[0]]; + } + allHyperlinks.addAll(Arrays.asList(arraycast!(Object)(hyperlinks))); + } + } + + if (allHyperlinks.isEmpty()) + return null; + + if (fDetectionStrategy !is ALL) { + int maxLength= computeLongestHyperlinkLength(allHyperlinks); + Iterator iter= (new ArrayList(allHyperlinks)).iterator(); + while (iter.hasNext()) { + IHyperlink hyperlink= cast(IHyperlink)iter.next(); + if (hyperlink.getHyperlinkRegion().getLength() < maxLength) + allHyperlinks.remove(cast(Object)hyperlink); + } + } + + if (fDetectionStrategy is LONGEST_REGION_FIRST) + return [cast(IHyperlink)allHyperlinks.get(0)]; + + return arraycast!(IHyperlink)(allHyperlinks.toArray()); + + } + + /** + * Computes the length of the longest detected + * hyperlink. + * + * @param hyperlinks + * @return the length of the longest detected + */ + protected int computeLongestHyperlinkLength(List hyperlinks) { + Assert.isLegal(hyperlinks !is null && !hyperlinks.isEmpty()); + Iterator iter= hyperlinks.iterator(); + int length= Integer.MIN_VALUE; + while (iter.hasNext()) { + IRegion region= (cast(IHyperlink)iter.next()).getHyperlinkRegion(); + if (region.getLength() < length) + continue; + length= region.getLength(); + } + return length; + } + + /** + * Returns the current text offset. + * + * @return the current text offset + */ + protected int getCurrentTextOffset() { + + try { + StyledText text= fTextViewer.getTextWidget(); + if (text is null || text.isDisposed()) + return -1; + + Display display= text.getDisplay(); + Point absolutePosition= display.getCursorLocation(); + Point relativePosition= text.toControl(absolutePosition); + + int widgetOffset= text.getOffsetAtLocation(relativePosition); + Point p= text.getLocationAtOffset(widgetOffset); + if (p.x > relativePosition.x) + widgetOffset--; + + if ( cast(ITextViewerExtension5)fTextViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5)fTextViewer; + return extension.widgetOffset2ModelOffset(widgetOffset); + } + + return widgetOffset + fTextViewer.getVisibleRegion().getOffset(); + + } catch (IllegalArgumentException e) { + return -1; + } + } + + /* + * @see dwt.events.KeyListener#keyPressed(dwt.events.KeyEvent) + */ + public void keyPressed(KeyEvent event) { + + if (fActive) { + deactivate(); + return; + } + + if (!isRegisteredStateMask(event.keyCode)) { + deactivate(); + return; + } + + fActive= true; + fActiveHyperlinkStateMask= event.keyCode; + +// removed for #25871 (hyperlinks could interact with typing) +// +// ITextViewer viewer= getSourceViewer(); +// if (viewer is null) +// return; +// +// IRegion region= getCurrentTextRegion(viewer); +// if (region is null) +// return; +// +// highlightRegion(viewer, region); +// activateCursor(viewer); + } + + /* + * @see dwt.events.KeyListener#keyReleased(dwt.events.KeyEvent) + */ + public void keyReleased(KeyEvent event) { + } + + /* + * @see dwt.events.MouseListener#mouseDoubleClick(dwt.events.MouseEvent) + */ + public void mouseDoubleClick(MouseEvent e) { + + } + + /* + * @see dwt.events.MouseListener#mouseDown(dwt.events.MouseEvent) + */ + public void mouseDown(MouseEvent event) { + + if (!fActive) + return; + + if (event.stateMask !is fActiveHyperlinkStateMask) { + deactivate(); + return; + } + + if (event.button !is 1) { + deactivate(); + return; + } + } + + /* + * @see dwt.events.MouseListener#mouseUp(dwt.events.MouseEvent) + */ + public void mouseUp(MouseEvent e) { + + if (!fActive) { + fActiveHyperlinks= null; + return; + } + + if (e.button !is 1) + fActiveHyperlinks= null; + + deactivate(); + + if (fActiveHyperlinks !is null) + fActiveHyperlinks[0].open(); + } + + /* + * @see dwt.events.MouseMoveListener#mouseMove(dwt.events.MouseEvent) + */ + public void mouseMove(MouseEvent event) { + if ( cast(IHyperlinkPresenterExtension)fHyperlinkPresenter ) { + if (!(cast(IHyperlinkPresenterExtension)fHyperlinkPresenter).canHideHyperlinks()) + return; + } + + if (!isRegisteredStateMask(event.stateMask)) { + if (fActive) + deactivate(); + + return; + } + + fActive= true; + fActiveHyperlinkStateMask= event.stateMask; + + StyledText text= fTextViewer.getTextWidget(); + if (text is null || text.isDisposed()) { + deactivate(); + return; + } + + if ((event.stateMask & DWT.BUTTON1) !is 0 && text.getSelectionCount() !is 0) { + deactivate(); + return; + } + + fActiveHyperlinks= findHyperlinks(); + if (fActiveHyperlinks is null || fActiveHyperlinks.length is 0) { + fHyperlinkPresenter.hideHyperlinks(); + return; + } + + fHyperlinkPresenter.showHyperlinks(fActiveHyperlinks); + + } + + /** + * Checks whether the given state mask is registered. + * + * @param stateMask + * @return true if a detector is registered for the given state mask + * @since 3.3 + */ + private bool isRegisteredStateMask(int stateMask) { + if (stateMask is fHyperlinkStateMask) + return true; + + synchronized (/+fHyperlinkDetectors+/this) { + for (int i= 0; i < fHyperlinkDetectors.length; i++) { + if (cast(IHyperlinkDetectorExtension2)fHyperlinkDetectors[i] ) { + if (stateMask is (cast(IHyperlinkDetectorExtension2)fHyperlinkDetectors[i]).getStateMask()) + return true; + } + } + } + return false; + } + + /* + * @see dwt.events.FocusListener#focusGained(dwt.events.FocusEvent) + */ + public void focusGained(FocusEvent e) {} + + /* + * @see dwt.events.FocusListener#focusLost(dwt.events.FocusEvent) + */ + public void focusLost(FocusEvent event) { + deactivate(); + } + + /* + * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event) + * @since 3.2 + */ + public void handleEvent(Event event) { + //key up + deactivate(); + } + + /* + * @see dwtx.jface.text.ITextListener#textChanged(TextEvent) + * @since 3.2 + */ + public void textChanged(TextEvent event) { + if (event.getDocumentEvent() !is null) + deactivate(); + } + + /** + * {@inheritDoc} + * + * @since 3.4 + */ + public void mouseExit(MouseEvent e) { + if ( cast(IHyperlinkPresenterExtension)fHyperlinkPresenter ) { + if (!(cast(IHyperlinkPresenterExtension)fHyperlinkPresenter).canHideHyperlinks()) + return; + } + deactivate(); + } + + /** + * {@inheritDoc} + * + * @since 3.4 + */ + public void mouseEnter(MouseEvent e) { + } + + /** + * {@inheritDoc} + * + * @since 3.4 + */ + public void mouseHover(MouseEvent e) { + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/hyperlink/HyperlinkMessages.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/hyperlink/HyperlinkMessages.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,66 @@ +/******************************************************************************* + * 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.text.hyperlink.HyperlinkMessages; + +import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport +import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport +import dwtx.jface.text.hyperlink.IHyperlink; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.dwthelper.ResourceBundle; + + +/** + * Helper class to get NLSed messages. + * + * @since 3.4 + */ +class HyperlinkMessages { +// private static const String BUNDLE_NAME= HyperlinkMessages.classinfo.getName(); + + private static const ResourceBundle RESOURCE_BUNDLE;//= ResourceBundle.getBundle(BUNDLE_NAME); + + static this() { + RESOURCE_BUNDLE = ResourceBundle.getBundle( + getImportData!("dwtx.jface.text.hyperlink.HyperlinkMessages.properties")); + } + + private this() { + } + + /** + * Gets a string from the resource bundle. + * + * @param key the string used to get the bundle value, must not be + * null + * @return the string from the resource bundle + */ + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' ~ key ~ '!'; + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/hyperlink/IHyperlink.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/hyperlink/IHyperlink.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.hyperlink.IHyperlink; + +import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport +import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.IRegion; + + +/** + * Represents a hyperlink. + *

                  + * Clients may implement this interface. + *

                  + * + * @since 3.1 + */ +public interface IHyperlink { + + /** + * The region covered by this type of hyperlink. + * + * @return the hyperlink region + */ + IRegion getHyperlinkRegion(); + + /** + * Optional label for this type of hyperlink. + *

                  + * This type label can be used by {@link IHyperlinkPresenter}s + * which show several hyperlinks at once. + *

                  + * + * @return the type label or null if none + */ + String getTypeLabel(); + + /** + * Optional text for this hyperlink. + *

                  + * This can be used in situations where there are + * several targets for the same hyperlink location. + *

                  + * + * @return the text or null if none + */ + String getHyperlinkText(); + + /** + * Opens the given hyperlink. + */ + void open(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/hyperlink/IHyperlinkDetector.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/hyperlink/IHyperlinkDetector.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,78 @@ +/******************************************************************************* + * 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.text.hyperlink.IHyperlinkDetector; + +import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport +import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport +import dwtx.jface.text.hyperlink.IHyperlink; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.source.SourceViewerConfiguration; + + +/** + * A hyperlink detector tries to find a hyperlink at + * a given location in a given text viewer. + *

                  + * In order to provide backward compatibility for clients of IHyperlinkDetector, extension + * interfaces are used to provide a means of evolution. The following extension interfaces exist: + *

                    + *
                  • {@link IHyperlinkDetectorExtension} since version 3.3, + * adds the ability to dispose a hyperlink detector + *
                  • + *
                  • {@link IHyperlinkDetectorExtension2} since version 3.3, + * adds the ability to specify the state mask of the modifier + * keys that need to be pressed for this hyperlink detector + *
                  • + *

                  + *

                  + * Clients may implement this interface. + *

                  + * + * @see SourceViewerConfiguration#getHyperlinkDetectors(dwtx.jface.text.source.ISourceViewer) + * @since 3.1 + */ +public interface IHyperlinkDetector { + + /** + * Tries to detect hyperlinks for the given region in + * the given text viewer and returns them. + *

                  + * In most of the cases only one hyperlink should be returned. + *

                  + * @param textViewer the text viewer on which the hover popup should be shown + * @param region the text range in the text viewer which is used to detect the hyperlinks + * @param canShowMultipleHyperlinks tells whether the caller is able to show multiple links + * to the user. + * If true {@link IHyperlink#open()} should directly open + * the link and not show any additional UI to select from a list. + * If false this method should only return one hyperlink + * which upon {@link IHyperlink#open()} may allow to select from a list. + * @return the hyperlinks or null if no hyperlink was detected + */ + IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, bool canShowMultipleHyperlinks); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/hyperlink/IHyperlinkDetectorExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/hyperlink/IHyperlinkDetectorExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,48 @@ +/******************************************************************************* + * 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.text.hyperlink.IHyperlinkDetectorExtension; + +import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport +import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport +import dwtx.jface.text.hyperlink.IHyperlink; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Extends {@link IHyperlinkDetector} with ability + * to dispose a hyperlink detector. + *

                  + * Clients may implement this interface. + *

                  + * + * @since 3.3 + */ +public interface IHyperlinkDetectorExtension { + + /** + * Disposes this hyperlink detector. + */ + void dispose(); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/hyperlink/IHyperlinkDetectorExtension2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/hyperlink/IHyperlinkDetectorExtension2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,51 @@ +/******************************************************************************* + * 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.text.hyperlink.IHyperlinkDetectorExtension2; + +import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport +import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport +import dwtx.jface.text.hyperlink.IHyperlink; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Extends {@link IHyperlinkDetector} with ability + * to specify the state mask of the modifier keys that + * need to be pressed for this hyperlink detector. + *

                  + * Clients may implement this interface. + *

                  + * + * @since 3.3 + */ +public interface IHyperlinkDetectorExtension2 { + + /** + * Returns the state mask of the modifier keys that + * need to be pressed for this hyperlink detector. + * + * @return the state mask + */ + int getStateMask(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/hyperlink/IHyperlinkPresenter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/hyperlink/IHyperlinkPresenter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,94 @@ +/******************************************************************************* + * 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 + * 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.text.hyperlink.IHyperlinkPresenter; + +import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport +import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport +import dwtx.jface.text.hyperlink.IHyperlink; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.ITextViewer; + + +/** + * A hyperlink presenter shows hyperlinks on the installed text viewer + * and allows to pick one on of the hyperlinks. + *

                  + * In order to provide backward compatibility for clients of IHyperlinkDetector, extension + * interfaces are used to provide a means of evolution. The following extension interfaces exist: + *

                    + *
                  • {@link IHyperlinkPresenterExtension} since version 3.4, + * adds the ability to query whether the currently shown hyperlinks + * can be hidden. + *
                  • + *

                  + *

                  + * Clients may implement this interface. A default implementation is provided + * through {@link dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter}. + *

                  + * + * @see IHyperlinkPresenterExtension + * @since 3.1 + */ +public interface IHyperlinkPresenter { + + /** + * Tells whether this presenter is able to handle + * more than one hyperlink. + * + * @return true if this presenter can handle more than one hyperlink + */ + bool canShowMultipleHyperlinks(); + + /** + * Tells this hyperlink presenter to show the given + * hyperlinks on the installed text viewer. + * + * @param hyperlinks the hyperlinks to show + * @throws IllegalArgumentException if + *
                    + *
                  • hyperlinks is empty
                  • + *
                  • {@link #canShowMultipleHyperlinks()} returns false and hyperlinks contains more than one element
                  • + *
                  + */ + void showHyperlinks(IHyperlink[] hyperlinks) ; + + /** + * Tells this hyperlink presenter to hide the hyperlinks + * requested to be shown by {@link #showHyperlinks(IHyperlink[])}. + */ + void hideHyperlinks(); + + /** + * Installs this hyperlink presenter on the given text viewer. + * + * @param textViewer the text viewer + */ + void install(ITextViewer textViewer); + + /** + * Uninstalls this hyperlink presenter. + */ + void uninstall(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/hyperlink/IHyperlinkPresenterExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/hyperlink/IHyperlinkPresenterExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,52 @@ +/******************************************************************************* + * 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.text.hyperlink.IHyperlinkPresenterExtension; + +import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport +import dwtx.jface.text.hyperlink.IHyperlink; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Extends {@link IHyperlinkPresenter} with ability + * to query whether the currently shown hyperlinks + * can be hidden. + *

                  + * Clients may implement this interface. + *

                  + * + * @since 3.4 + */ +public interface IHyperlinkPresenterExtension { + + /** + * Tells whether the currently shown hyperlinks + * can be hidden. + * + * @return true if the hyperlink manager can hide the current hyperlinks + */ + bool canHideHyperlinks(); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/hyperlink/MultipleHyperlinkPresenter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/hyperlink/MultipleHyperlinkPresenter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,754 @@ +/******************************************************************************* + * 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.text.hyperlink.MultipleHyperlinkPresenter; + +import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport +import dwtx.jface.text.hyperlink.IHyperlink; // packageimport + +import dwt.dwthelper.utils; + +import dwt.DWT; +import dwt.events.KeyAdapter; +import dwt.events.KeyEvent; +import dwt.events.KeyListener; +import dwt.events.MouseAdapter; +import dwt.events.MouseEvent; +import dwt.events.MouseMoveListener; +import dwt.events.SelectionAdapter; +import dwt.events.SelectionEvent; +import dwt.events.ShellAdapter; +import dwt.events.ShellEvent; +import dwt.graphics.Color; +import dwt.graphics.Point; +import dwt.graphics.RGB; +import dwt.graphics.Rectangle; +import dwt.layout.GridLayout; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Listener; +import dwt.widgets.Shell; +import dwt.widgets.Table; +import dwt.widgets.TableItem; +import dwtx.jface.preference.IPreferenceStore; +import dwtx.jface.text.AbstractInformationControl; +import dwtx.jface.text.AbstractInformationControlManager; +import dwtx.jface.text.IInformationControl; +import dwtx.jface.text.IInformationControlCreator; +import dwtx.jface.text.IInformationControlExtension2; +import dwtx.jface.text.IInformationControlExtension3; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextHover; +import dwtx.jface.text.ITextHoverExtension; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.IWidgetTokenKeeper; +import dwtx.jface.text.IWidgetTokenKeeperExtension; +import dwtx.jface.text.IWidgetTokenOwner; +import dwtx.jface.text.IWidgetTokenOwnerExtension; +import dwtx.jface.text.JFaceTextUtil; +import dwtx.jface.text.Region; +import dwtx.jface.util.Geometry; +import dwtx.jface.viewers.ColumnLabelProvider; +import dwtx.jface.viewers.IStructuredContentProvider; +import dwtx.jface.viewers.TableViewer; +import dwtx.jface.viewers.Viewer; + + +/** + * A hyperlink presenter capable of showing multiple hyperlinks in a hover. + * + * @since 3.4 + */ +public class MultipleHyperlinkPresenter : DefaultHyperlinkPresenter { + + /** + * An information control capable of showing a list of hyperlinks. The hyperlinks can be opened. + */ + private static class LinkListInformationControl : AbstractInformationControl , IInformationControlExtension2 { + + private static final class LinkContentProvider : IStructuredContentProvider { + + /* + * @see dwtx.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object inputElement) { + return arrayFromObject!(Object)( inputElement); + } + + /* + * @see dwtx.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + } + + /* + * @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) { + } + } + + private static final class LinkLabelProvider : ColumnLabelProvider { + /* + * @see dwtx.jface.viewers.ColumnLabelProvider#getText(java.lang.Object) + */ + public String getText(Object element) { + IHyperlink link= cast(IHyperlink)element; + String text= link.getHyperlinkText(); + if (text !is null) + return text; + return HyperlinkMessages.getString("LinkListInformationControl.unknownLink"); //$NON-NLS-1$ + } + } + + private const MultipleHyperlinkHoverManager fManager; + + private IHyperlink[] fInput; + private Composite fParent; + private Table fTable; + + private Color fForegroundColor; + private Color fBackgroundColor; + + + /** + * Creates a link list information control with the given shell as parent. + * + * @param parentShell the parent shell + * @param manager the hover manager + * @param foregroundColor the foreground color, must not be disposed + * @param backgroundColor the background color, must not be disposed + */ + public this(Shell parentShell, MultipleHyperlinkHoverManager manager, Color foregroundColor, Color backgroundColor) { + super(parentShell, false); + fManager= manager; + fForegroundColor= foregroundColor; + fBackgroundColor= backgroundColor; + create(); + } + + /* + * @see dwtx.jface.text.IInformationControl#setInformation(java.lang.String) + */ + public void setInformation(String information) { + //replaced by IInformationControlExtension2#setInput(java.lang.Object) + } + + /* + * @see dwtx.jface.text.IInformationControlExtension2#setInput(java.lang.Object) + */ + public void setInput(Object input) { + fInput= arrayFromObject!(IHyperlink)( input); + deferredCreateContent(fParent); + } + + /* + * @see dwtx.jface.text.AbstractInformationControl#createContent(dwt.widgets.Composite) + */ + protected void createContent(Composite parent) { + fParent= parent; + if ("win32".equals(DWT.getPlatform())) { //$NON-NLS-1$ + GridLayout layout= new GridLayout(); + layout.marginWidth= 0; + layout.marginRight= 4; + fParent.setLayout(layout); + } + fParent.setForeground(fForegroundColor); + fParent.setBackground(fBackgroundColor); + } + + /* + * @see dwtx.jface.text.AbstractInformationControl#computeSizeHint() + */ + public Point computeSizeHint() { + Point preferedSize= getShell().computeSize(DWT.DEFAULT, DWT.DEFAULT, true); + + Point constraints= getSizeConstraints(); + if (constraints is null) + return preferedSize; + + if (fTable.getVerticalBar() is null || fTable.getHorizontalBar() is null) + return Geometry.min(constraints, preferedSize); + + int scrollBarWidth= fTable.getVerticalBar().getSize().x; + int scrollBarHeight= fTable.getHorizontalBar().getSize().y; + + int width; + if (preferedSize.y - scrollBarHeight <= constraints.y) { + width= preferedSize.x - scrollBarWidth; + fTable.getVerticalBar().setVisible(false); + } else { + width= Math.min(preferedSize.x, constraints.x); + } + + int height; + if (preferedSize.x - scrollBarWidth <= constraints.x) { + height= preferedSize.y - scrollBarHeight; + fTable.getHorizontalBar().setVisible(false); + } else { + height= Math.min(preferedSize.y, constraints.y); + } + + return new Point(width, height); + } + + private void deferredCreateContent(Composite parent) { + fTable= new Table(parent, DWT.SINGLE | DWT.FULL_SELECTION); + fTable.setLinesVisible(false); + fTable.setHeaderVisible(false); + fTable.setForeground(fForegroundColor); + fTable.setBackground(fBackgroundColor); + + final TableViewer viewer= new TableViewer(fTable); + viewer.setContentProvider(new LinkContentProvider()); + viewer.setLabelProvider(new LinkLabelProvider()); + viewer.setInput(new ArrayWrapperObject( arraycast!(Object)(fInput))); + fTable.setSelection(0); + + registerTableListeners(); + + getShell().addShellListener(new class() ShellAdapter { + + /* + * @see dwt.events.ShellAdapter#shellActivated(dwt.events.ShellEvent) + */ + public void shellActivated(ShellEvent e) { + if (viewer.getTable().getSelectionCount() is 0) { + viewer.getTable().setSelection(0); + } + + viewer.getTable().setFocus(); + } + }); + } + + private void registerTableListeners() { + + fTable.addMouseMoveListener(new class() MouseMoveListener { + TableItem fLastItem= null; + + public void mouseMove(MouseEvent e) { + if (fTable.opEquals(e.getSource())) { + Object o= fTable.getItem(new Point(e.x, e.y)); + if ( cast(TableItem)o ) { + TableItem item= cast(TableItem) o; + if (!o.opEquals(fLastItem)) { + fLastItem= cast(TableItem) o; + fTable.setSelection([ fLastItem ]); + } else if (e.y < fTable.getItemHeight() / 4) { + // Scroll up + int index= fTable.indexOf(item); + if (index > 0) { + fLastItem= fTable.getItem(index - 1); + fTable.setSelection([ fLastItem ]); + } + } else if (e.y > fTable.getBounds().height - fTable.getItemHeight() / 4) { + // Scroll down + int index= fTable.indexOf(item); + if (index < fTable.getItemCount() - 1) { + fLastItem= fTable.getItem(index + 1); + fTable.setSelection([ fLastItem ]); + } + } + } + } + } + }); + + fTable.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + openSelectedLink(); + } + }); + + fTable.addMouseListener(new class() MouseAdapter { + public void mouseUp(MouseEvent e) { + if (fTable.getSelectionCount() < 1) + return; + + if (e.button !is 1) + return; + + if (fTable.opEquals(e.getSource())) { + Object o= fTable.getItem(new Point(e.x, e.y)); + TableItem selection= fTable.getSelection()[0]; + if (selection.opEquals(o)) + openSelectedLink(); + } + } + }); + + fTable.addKeyListener(new class() KeyAdapter { + public void keyPressed(KeyEvent e) { + if (e.keyCode is 0x0D) // return + openSelectedLink(); + } + }); + } + + /* + * @see dwtx.jface.text.IInformationControlExtension#hasContents() + */ + public bool hasContents() { + return true; + } + + /** + * Opens the currently selected link. + */ + private void openSelectedLink() { + TableItem selection= fTable.getSelection()[0]; + IHyperlink link= cast(IHyperlink)selection.getData(); + fManager.hideInformationControl(); + link.open(); + } + } + + private class MultipleHyperlinkHover : ITextHover, ITextHoverExtension { + + /** + * @see dwtx.jface.text.ITextHover#getHoverInfo(dwtx.jface.text.ITextViewer, dwtx.jface.text.IRegion) + * @deprecated + */ + public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) { + return null; + } + + /* + * @see dwtx.jface.text.ITextHover#getHoverRegion(dwtx.jface.text.ITextViewer, int) + */ + public IRegion getHoverRegion(ITextViewer textViewer, int offset) { + return fSubjectRegion; + } + + /* + * @see dwtx.jface.text.ITextHoverExtension2#getHoverInfo2(dwtx.jface.text.ITextViewer, dwtx.jface.text.IRegion) + */ + public Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion) { + return new ArrayWrapperObject( arraycast!(Object)(fHyperlinks)); + } + + /* + * @see dwtx.jface.text.ITextHoverExtension#getHoverControlCreator() + */ + public IInformationControlCreator getHoverControlCreator() { + return new class() IInformationControlCreator { + public IInformationControl createInformationControl(Shell parent) { + Color foregroundColor= fTextViewer.getTextWidget().getForeground(); + Color backgroundColor= fTextViewer.getTextWidget().getBackground(); + return new LinkListInformationControl(parent, fManager, foregroundColor, backgroundColor); + } + }; + } + } + + private static class MultipleHyperlinkHoverManager : AbstractInformationControlManager , IWidgetTokenKeeper, IWidgetTokenKeeperExtension { + + private class Closer : IInformationControlCloser, Listener, KeyListener { + + private Control fSubjectControl; + private Display fDisplay; + private IInformationControl fControl; + private Rectangle fSubjectArea; + + /* + * @see dwtx.jface.text.AbstractInformationControlManager.IInformationControlCloser#setInformationControl(dwtx.jface.text.IInformationControl) + */ + public void setInformationControl(IInformationControl control) { + fControl= control; + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager.IInformationControlCloser#setSubjectControl(dwt.widgets.Control) + */ + public void setSubjectControl(Control subject) { + fSubjectControl= subject; + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager.IInformationControlCloser#start(dwt.graphics.Rectangle) + */ + public void start(Rectangle subjectArea) { + fSubjectArea= subjectArea; + + fDisplay= fSubjectControl.getDisplay(); + if (!fDisplay.isDisposed()) { + fDisplay.addFilter(DWT.FocusOut, this); + fDisplay.addFilter(DWT.MouseMove, this); + fTextViewer.getTextWidget().addKeyListener(this); + } + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager.IInformationControlCloser#stop() + */ + public void stop() { + if (fDisplay !is null && !fDisplay.isDisposed()) { + fDisplay.removeFilter(DWT.FocusOut, this); + fDisplay.removeFilter(DWT.MouseMove, this); + fTextViewer.getTextWidget().removeKeyListener(this); + } + + fSubjectArea= null; + } + + /* + * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event) + */ + public void handleEvent(Event event) { + switch (event.type) { + case DWT.FocusOut: + if (!fControl.isFocusControl()) + disposeInformationControl(); + break; + case DWT.MouseMove: + handleMouseMove(event); + break; + } + } + + /** + * Handle mouse movement events. + * + * @param event the event + */ + private void handleMouseMove(Event event) { + if (!(cast(Control)event.widget )) + return; + + if (fControl.isFocusControl()) + return; + + Control eventControl= cast(Control) event.widget; + + //transform coordinates to subject control: + Point mouseLoc= event.display.map(eventControl, fSubjectControl, event.x, event.y); + + if (fSubjectArea.contains(mouseLoc)) + return; + + if (inKeepUpZone(mouseLoc.x, mouseLoc.y, (cast(IInformationControlExtension3) fControl).getBounds())) + return; + + hideInformationControl(); + } + + /** + * Tests whether a given mouse location is within the keep-up zone. + * The hover should not be hidden as long as the mouse stays inside this zone. + * + * @param x the x coordinate, relative to the subject control + * @param y the y coordinate, relative to the subject control + * @param controlBounds the bounds of the current control + * + * @return true iff the mouse event occurred in the keep-up zone + */ + private bool inKeepUpZone(int x, int y, Rectangle controlBounds) { + // +-----------+ + // |subjectArea| + // +-----------+ + // |also keepUp| + // ++-----------+-------+ + // | totalBounds | + // +--------------------+ + if (fSubjectArea.contains(x, y)) + return true; + + Rectangle iControlBounds= fSubjectControl.getDisplay().map(null, fSubjectControl, controlBounds); + Rectangle totalBounds= Geometry.copy(iControlBounds); + if (totalBounds.contains(x, y)) + return true; + + int keepUpY= fSubjectArea.y + fSubjectArea.height; + Rectangle alsoKeepUp= new Rectangle(fSubjectArea.x, keepUpY, fSubjectArea.width, totalBounds.y - keepUpY); + return alsoKeepUp.contains(x, y); + } + + /* + * @see dwt.events.KeyListener#keyPressed(dwt.events.KeyEvent) + */ + public void keyPressed(KeyEvent e) { + } + + /* + * @see dwt.events.KeyListener#keyReleased(dwt.events.KeyEvent) + */ + public void keyReleased(KeyEvent e) { + hideInformationControl(); + } + + } + + /** + * Priority of the hover managed by this manager. + * Default value: One higher then for the hovers + * managed by TextViewerHoverManager. + */ + private static const int WIDGET_TOKEN_PRIORITY= 1; + + private const MultipleHyperlinkHover fHover; + private const ITextViewer fTextViewer; + private const MultipleHyperlinkPresenter fHyperlinkPresenter; + private Closer fCloser; + private bool fIsControlVisible; + + + /** + * Create a new MultipleHyperlinkHoverManager. The MHHM can show and hide + * the given MultipleHyperlinkHover inside the given ITextViewer. + * + * @param hover the hover to manage + * @param viewer the viewer to show the hover in + * @param hyperlinkPresenter the hyperlink presenter using this manager to present hyperlinks + */ + public this(MultipleHyperlinkHover hover, ITextViewer viewer, MultipleHyperlinkPresenter hyperlinkPresenter) { + super(hover.getHoverControlCreator()); + + fHover= hover; + fTextViewer= viewer; + fHyperlinkPresenter= hyperlinkPresenter; + + fCloser= new Closer(); + setCloser(fCloser); + fIsControlVisible= false; + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#computeInformation() + */ + protected void computeInformation() { + IRegion region= fHover.getHoverRegion(fTextViewer, -1); + if (region is null) { + setInformation(cast(Object)null, cast(Rectangle)null); + return; + } + + Rectangle area= JFaceTextUtil.computeArea(region, fTextViewer); + if (area is null || area.isEmpty()) { + setInformation(cast(Object)null, cast(Rectangle)null); + return; + } + + Object information= fHover.getHoverInfo2(fTextViewer, region); + setCustomInformationControlCreator(fHover.getHoverControlCreator()); + setInformation(information, area); + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#computeInformationControlLocation(dwt.graphics.Rectangle, dwt.graphics.Point) + */ + protected Point computeInformationControlLocation(Rectangle subjectArea, Point controlSize) { + Point result= super.computeInformationControlLocation(subjectArea, controlSize); + + Point cursorLocation= fTextViewer.getTextWidget().getDisplay().getCursorLocation(); + if (cursorLocation.x <= result.x + controlSize.x) + return result; + + result.x= cursorLocation.x + 20 - controlSize.x; + return result; + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#showInformationControl(dwt.graphics.Rectangle) + */ + protected void showInformationControl(Rectangle subjectArea) { + if ( cast(IWidgetTokenOwnerExtension)fTextViewer ) { + if ((cast(IWidgetTokenOwnerExtension) fTextViewer).requestWidgetToken(this, WIDGET_TOKEN_PRIORITY)) + super.showInformationControl(subjectArea); + } else if ( cast(IWidgetTokenOwner)fTextViewer ) { + if ((cast(IWidgetTokenOwner) fTextViewer).requestWidgetToken(this)) + super.showInformationControl(subjectArea); + } else { + super.showInformationControl(subjectArea); + } + + fIsControlVisible= true; + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#hideInformationControl() + */ + protected void hideInformationControl() { + super.hideInformationControl(); + + if ( cast(IWidgetTokenOwner)fTextViewer ) { + (cast(IWidgetTokenOwner) fTextViewer).releaseWidgetToken(this); + } + + fIsControlVisible= false; + fHyperlinkPresenter.hideHyperlinks(); + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#disposeInformationControl() + */ + public void disposeInformationControl() { + super.disposeInformationControl(); + + if ( cast(IWidgetTokenOwner)fTextViewer ) { + (cast(IWidgetTokenOwner) fTextViewer).releaseWidgetToken(this); + } + + fIsControlVisible= false; + fHyperlinkPresenter.hideHyperlinks(); + } + + /* + * @see dwtx.jface.text.IWidgetTokenKeeper#requestWidgetToken(dwtx.jface.text.IWidgetTokenOwner) + */ + public bool requestWidgetToken(IWidgetTokenOwner owner) { + hideInformationControl(); + return true; + } + + /* + * @see dwtx.jface.text.IWidgetTokenKeeperExtension#requestWidgetToken(dwtx.jface.text.IWidgetTokenOwner, int) + */ + public bool requestWidgetToken(IWidgetTokenOwner owner, int priority) { + if (priority < WIDGET_TOKEN_PRIORITY) + return false; + + hideInformationControl(); + return true; + } + + /* + * @see dwtx.jface.text.IWidgetTokenKeeperExtension#setFocus(dwtx.jface.text.IWidgetTokenOwner) + */ + public bool setFocus(IWidgetTokenOwner owner) { + return false; + } + + /** + * Returns true if the information control managed by + * this manager is visible, false otherwise. + * + * @return true if information control is visible + */ + public bool isInformationControlVisible() { + return fIsControlVisible; + } + } + + private ITextViewer fTextViewer; + + private IHyperlink[] fHyperlinks; + private Region fSubjectRegion; + private MultipleHyperlinkHoverManager fManager; + + /** + * Creates a new multiple hyperlink presenter which uses + * {@link #HYPERLINK_COLOR} to read the color from the given preference store. + * + * @param store the preference store + */ + public this(IPreferenceStore store) { + super(store); + } + + /** + * Creates a new multiple hyperlink presenter. + * + * @param color the hyperlink color, to be disposed by the caller + */ + public this(RGB color) { + super(color); + } + + /* + * @see dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter#install(dwtx.jface.text.ITextViewer) + */ + public void install(ITextViewer viewer) { + super.install(viewer); + fTextViewer= viewer; + + fManager= new MultipleHyperlinkHoverManager(new MultipleHyperlinkHover(), fTextViewer, this); + fManager.install(viewer.getTextWidget()); + fManager.setSizeConstraints(100, 12, false, true); + } + + /* + * @see dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter#uninstall() + */ + public void uninstall() { + super.uninstall(); + + if (fTextViewer !is null) { + fManager.dispose(); + + fTextViewer= null; + } + } + + /* + * @see dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter#canShowMultipleHyperlinks() + */ + public bool canShowMultipleHyperlinks() { + return true; + } + + /* + * @see dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter#canHideHyperlinks() + */ + public bool canHideHyperlinks() { + return !fManager.isInformationControlVisible(); + } + + /* + * @see dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter#hideHyperlinks() + */ + public void hideHyperlinks() { + super.hideHyperlinks(); + + fHyperlinks= null; + } + + /* + * @see dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter#showHyperlinks(dwtx.jface.text.hyperlink.IHyperlink[]) + */ + public void showHyperlinks(IHyperlink[] hyperlinks) { + super.showHyperlinks([ hyperlinks[0] ]); + + fSubjectRegion= null; + fHyperlinks= hyperlinks; + + if (hyperlinks.length is 1) + return; + + int start= hyperlinks[0].getHyperlinkRegion().getOffset(); + int end= start + hyperlinks[0].getHyperlinkRegion().getLength(); + + for (int i= 1; i < hyperlinks.length; i++) { + int hstart= hyperlinks[i].getHyperlinkRegion().getOffset(); + int hend= hstart + hyperlinks[i].getHyperlinkRegion().getLength(); + + start= Math.min(start, hstart); + end= Math.max(end, hend); + } + + fSubjectRegion= new Region(start, end - start); + + fManager.showInformation(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/hyperlink/URLHyperlink.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/hyperlink/URLHyperlink.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,106 @@ +/******************************************************************************* + * 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 + * 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.text.hyperlink.URLHyperlink; + +import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport +import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport +import dwtx.jface.text.hyperlink.IHyperlink; // packageimport + + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.MessageFormat; + +import dwt.program.Program; +import dwtx.core.runtime.Assert; +import dwtx.jface.text.IRegion; + + + + + +/** + * URL hyperlink. + * + * @since 3.1 + */ +public class URLHyperlink : IHyperlink { + + private String fURLString; + private IRegion fRegion; + + /** + * Creates a new URL hyperlink. + * + * @param region + * @param urlString + */ + public this(IRegion region, String urlString) { + Assert.isNotNull(urlString); + Assert.isNotNull(cast(Object)region); + + fRegion= region; + fURLString= urlString; + } + + /* + * @see dwtx.jdt.internal.ui.javaeditor.IHyperlink#getHyperlinkRegion() + */ + public IRegion getHyperlinkRegion() { + return fRegion; + } + + /* + * @see dwtx.jdt.internal.ui.javaeditor.IHyperlink#open() + */ + public void open() { + if (fURLString !is null) { + Program.launch(fURLString); + fURLString= null; + return; + } + } + + /* + * @see dwtx.jdt.internal.ui.javaeditor.IHyperlink#getTypeLabel() + */ + public String getTypeLabel() { + return null; + } + + /* + * @see dwtx.jdt.internal.ui.javaeditor.IHyperlink#getHyperlinkText() + */ + public String getHyperlinkText() { + return MessageFormat.format(HyperlinkMessages.getString("URLHyperlink.hyperlinkText"), stringcast(fURLString) ); //$NON-NLS-1$ + } + + /** + * Returns the URL string of this hyperlink. + * + * @return the URL string + * @since 3.2 + */ + public String getURLString() { + return fURLString; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/hyperlink/URLHyperlinkDetector.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/hyperlink/URLHyperlinkDetector.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,154 @@ +/******************************************************************************* + * 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 + * Benjamin Muskalla - https://bugs.eclipse.org/bugs/show_bug.cgi?id=156433 + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.text.hyperlink.URLHyperlinkDetector; + +import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport +import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport +import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport +import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport +import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport +import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport +import dwtx.jface.text.hyperlink.IHyperlink; // packageimport + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.MalformedURLException; +import dwtx.dwtxhelper.URL; +import dwtx.dwtxhelper.StringTokenizer; + +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.Region; + + +/** + * URL hyperlink detector. + * + * @since 3.1 + */ +public class URLHyperlinkDetector : AbstractHyperlinkDetector { + + + /** + * Creates a new URL hyperlink detector. + * + * @since 3.2 + */ + public this() { + } + + /** + * Creates a new URL hyperlink detector. + * + * @param textViewer the text viewer in which to detect the hyperlink + * @deprecated As of 3.2, replaced by {@link URLHyperlinkDetector} + */ + public this(ITextViewer textViewer) { + } + + /* + * @see dwtx.jface.text.hyperlink.IHyperlinkDetector#detectHyperlinks(dwtx.jface.text.ITextViewer, dwtx.jface.text.IRegion, bool) + */ + public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, bool canShowMultipleHyperlinks) { + if (region is null || textViewer is null) + return null; + + IDocument document= textViewer.getDocument(); + + int offset= region.getOffset(); + + String urlString= null; + if (document is null) + return null; + + IRegion lineInfo; + String line; + try { + lineInfo= document.getLineInformationOfOffset(offset); + line= document.get(lineInfo.getOffset(), lineInfo.getLength()); + } catch (BadLocationException ex) { + return null; + } + + int offsetInLine= offset - lineInfo.getOffset(); + + bool startDoubleQuote= false; + int urlOffsetInLine= 0; + int urlLength= 0; + + int urlSeparatorOffset= line.indexOf("://"); //$NON-NLS-1$ + while (urlSeparatorOffset >= 0) { + + // URL protocol (left to "://") + urlOffsetInLine= urlSeparatorOffset; + char ch; + do { + urlOffsetInLine--; + ch= ' '; + if (urlOffsetInLine > -1) + ch= line.charAt(urlOffsetInLine); + startDoubleQuote= ch is '"'; + } while (Character.isUnicodeIdentifierStart(ch)); + urlOffsetInLine++; + + // Right to "://" + StringTokenizer tokenizer= new StringTokenizer(line.substring(urlSeparatorOffset + 3), " \t\n\r\f<>", false); //$NON-NLS-1$ + if (!tokenizer.hasMoreTokens()) + return null; + + urlLength= tokenizer.nextToken().length() + 3 + urlSeparatorOffset - urlOffsetInLine; + if (offsetInLine >= urlOffsetInLine && offsetInLine <= urlOffsetInLine + urlLength) + break; + + urlSeparatorOffset= line.indexOf("://", urlSeparatorOffset + 1); //$NON-NLS-1$ + } + + if (urlSeparatorOffset < 0) + return null; + + if (startDoubleQuote) { + int endOffset= -1; + int nextDoubleQuote= line.indexOf('"', urlOffsetInLine); + int nextWhitespace= line.indexOf(' ', urlOffsetInLine); + if (nextDoubleQuote !is -1 && nextWhitespace !is -1) + endOffset= Math.min(nextDoubleQuote, nextWhitespace); + else if (nextDoubleQuote !is -1) + endOffset= nextDoubleQuote; + else if (nextWhitespace !is -1) + endOffset= nextWhitespace; + if (endOffset !is -1) + urlLength= endOffset - urlOffsetInLine; + } + + // Set and validate URL string + try { + urlString= line.substring(urlOffsetInLine, urlOffsetInLine + urlLength); + new URL(urlString); + } catch (MalformedURLException ex) { + urlString= null; + return null; + } + + IRegion urlRegion= new Region(lineInfo.getOffset() + urlOffsetInLine, urlLength); + return [new URLHyperlink(urlRegion, urlString)]; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/information/IInformationPresenter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/information/IInformationPresenter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,84 @@ +/******************************************************************************* + * 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 + * 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.text.information.IInformationPresenter; + +import dwtx.jface.text.information.InformationPresenter; // packageimport +import dwtx.jface.text.information.IInformationProvider; // packageimport +import dwtx.jface.text.information.IInformationProviderExtension; // packageimport +import dwtx.jface.text.information.IInformationPresenterExtension; // packageimport +import dwtx.jface.text.information.IInformationProviderExtension2; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.ITextViewer; + + +/** + * An information presenter shows information available at the text viewer's + * current document position. An IInformationPresenter is a + * {@link dwtx.jface.text.ITextViewer} add-on. + *

                  + * An information presenters has a list of {@link dwtx.jface.text.information.IInformationProvider} objects + * each of which is registered for a particular document content type. + * The presenter uses the strategy objects to retrieve the information to present. + *

                  + *

                  + * In order to provide backward compatibility for clients of IInformationPresenter, extension + * interfaces are used to provide a means of evolution. The following extension interfaces exist: + *

                    + *
                  • {@link IInformationPresenterExtension} since version 3.0 introducing + * the ability to handle documents with multiple partitions
                  • + *
                  + *

                  + *

                  + * The interface can be implemented by clients. By default, clients use + * {@link dwtx.jface.text.information.InformationPresenter} as the standard implementer of this interface. + *

                  + * + * @see dwtx.jface.text.information.IInformationPresenterExtension + * @see dwtx.jface.text.ITextViewer + * @see dwtx.jface.text.information.IInformationProvider + * @since 2.0 + */ +public interface IInformationPresenter { + + /** + * Installs the information presenter on the given text viewer. After this method has been + * finished, the presenter is operational, i.e. the method {@link #showInformation()} + * can be called until {@link #uninstall()} is called. + * + * @param textViewer the viewer on which the presenter is installed + */ + void install(ITextViewer textViewer); + + /** + * Removes the information presenter from the text viewer it has previously been + * installed on. + */ + void uninstall(); + + /** + * Shows information related to the cursor position of the text viewer + * this information presenter is installed on. + */ + void showInformation(); + + /** + * Returns the information provider to be used for the given content type. + * + * @param contentType the type of the content for which information will be requested + * @return an information provider or null if none exists for the specified content type + */ + IInformationProvider getInformationProvider(String contentType); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/information/IInformationPresenterExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/information/IInformationPresenterExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,40 @@ +/******************************************************************************* + * 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 + * 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.text.information.IInformationPresenterExtension; + +import dwtx.jface.text.information.InformationPresenter; // packageimport +import dwtx.jface.text.information.IInformationProvider; // packageimport +import dwtx.jface.text.information.IInformationProviderExtension; // packageimport +import dwtx.jface.text.information.IInformationProviderExtension2; // packageimport +import dwtx.jface.text.information.IInformationPresenter; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Extends {@link dwtx.jface.text.information.IInformationPresenter} with + * the ability to handle documents with multiple partitions. + * + * @see dwtx.jface.text.information.IInformationPresenter + * + * @since 3.0 + */ +public interface IInformationPresenterExtension { + + /** + * Returns the document partitioning this information presenter is using. + * + * @return the document partitioning this information presenter is using + */ + String getDocumentPartitioning(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/information/IInformationProvider.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/information/IInformationProvider.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,78 @@ +/******************************************************************************* + * 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 + * 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.text.information.IInformationProvider; + +import dwtx.jface.text.information.InformationPresenter; // packageimport +import dwtx.jface.text.information.IInformationProviderExtension; // packageimport +import dwtx.jface.text.information.IInformationPresenterExtension; // packageimport +import dwtx.jface.text.information.IInformationProviderExtension2; // packageimport +import dwtx.jface.text.information.IInformationPresenter; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextViewer; + + +/** + * Provides information related to the content of a text viewer. + *

                  + * In order to provide backward compatibility for clients of IInformationProvider, extension + * interfaces are used to provide a means of evolution. The following extension interfaces exist: + *

                    + *
                  • {@link IInformationProviderExtension} since version 2.1 introducing + * the ability to provide the element for a given subject
                  • + *
                  • {@link IInformationProviderExtension2} since version 3.0 introducing + * the ability to provide its own information control creator
                  • + *
                  + *

                  + *

                  + * Clients may implement this interface. + *

                  + * + * @see dwtx.jface.text.information.IInformationProviderExtension + * @see dwtx.jface.text.information.IInformationProviderExtension2 + * @see dwtx.jface.text.information.IInformationPresenter + * @see dwtx.jface.text.ITextViewer + * @since 2.0 + */ +public interface IInformationProvider { + + /** + * Returns the region of the text viewer's document close to the given + * offset that contains a subject about which information can be provided.

                  + * For example, if information can be provided on a per code block basis, + * the offset should be used to find the enclosing code block and the source + * range of the block should be returned. + * + * @param textViewer the text viewer in which information has been requested + * @param offset the offset at which information has been requested + * @return the region of the text viewer's document containing the information subject + */ + IRegion getSubject(ITextViewer textViewer, int offset); + + /** + * Returns the information about the given subject or null if + * no information is available. It depends on the concrete configuration in which + * format the information is to be provided. For example, information presented + * in an information control displaying HTML, should be provided in HTML. + * + * @param textViewer the viewer in whose document the subject is contained + * @param subject the text region constituting the information subject + * @return the information about the subject + * @see IInformationPresenter + * @deprecated As of 2.1, replaced by {@link IInformationProviderExtension#getInformation2(ITextViewer, IRegion)} + */ + String getInformation(ITextViewer textViewer, IRegion subject); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/information/IInformationProviderExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/information/IInformationProviderExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.information.IInformationProviderExtension; + +import dwtx.jface.text.information.InformationPresenter; // packageimport +import dwtx.jface.text.information.IInformationProvider; // packageimport +import dwtx.jface.text.information.IInformationPresenterExtension; // packageimport +import dwtx.jface.text.information.IInformationProviderExtension2; // packageimport +import dwtx.jface.text.information.IInformationPresenter; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextViewer; + + +/** + * Extends {@link dwtx.jface.text.information.IInformationProvider} with + * the ability to provide the element for a given subject. + * + * @see dwtx.jface.text.information.IInformationProvider + * @since 2.1 + */ +public interface IInformationProviderExtension { + + /** + * Returns the element for the given subject or null if + * no element is available. + *

                  + * Implementers should ignore the text returned by {@link IInformationProvider#getInformation(ITextViewer, IRegion)}. + *

                  + * + * @param textViewer the viewer in whose document the subject is contained + * @param subject the text region constituting the information subject + * @return the element for the subject + * + * @see IInformationProvider#getInformation(ITextViewer, IRegion) + * @see dwtx.jface.text.ITextViewer + */ + Object getInformation2(ITextViewer textViewer, IRegion subject); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/information/IInformationProviderExtension2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/information/IInformationProviderExtension2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,42 @@ +/******************************************************************************* + * 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 + * 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.text.information.IInformationProviderExtension2; + +import dwtx.jface.text.information.InformationPresenter; // packageimport +import dwtx.jface.text.information.IInformationProvider; // packageimport +import dwtx.jface.text.information.IInformationProviderExtension; // packageimport +import dwtx.jface.text.information.IInformationPresenterExtension; // packageimport +import dwtx.jface.text.information.IInformationPresenter; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.IInformationControlCreator; + +/** + * Extends {@link dwtx.jface.text.information.IInformationProvider} with + * the ability to provide its own information presenter control creator. + * + * @see dwtx.jface.text.IInformationControlCreator + * @see dwtx.jface.text.information.IInformationProvider + * @since 3.0 + */ +public interface IInformationProviderExtension2 { + + /** + * Returns the information control creator of this information provider. + * + * @return the information control creator or null if none is available + */ + IInformationControlCreator getInformationPresenterControlCreator(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/information/InformationPresenter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/information/InformationPresenter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,504 @@ +/******************************************************************************* + * 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 + * 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.text.information.InformationPresenter; + +import dwtx.jface.text.information.IInformationProvider; // packageimport +import dwtx.jface.text.information.IInformationProviderExtension; // packageimport +import dwtx.jface.text.information.IInformationPresenterExtension; // packageimport +import dwtx.jface.text.information.IInformationProviderExtension2; // packageimport +import dwtx.jface.text.information.IInformationPresenter; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + +import dwt.custom.StyledText; +import dwt.events.ControlEvent; +import dwt.events.ControlListener; +import dwt.events.FocusEvent; +import dwt.events.FocusListener; +import dwt.events.KeyEvent; +import dwt.events.KeyListener; +import dwt.events.MouseEvent; +import dwt.events.MouseListener; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwtx.core.runtime.Assert; +import dwtx.jface.text.AbstractInformationControlManager; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocumentExtension3; +import dwtx.jface.text.IInformationControl; +import dwtx.jface.text.IInformationControlCreator; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.ITextViewerExtension5; +import dwtx.jface.text.IViewportListener; +import dwtx.jface.text.IWidgetTokenKeeper; +import dwtx.jface.text.IWidgetTokenKeeperExtension; +import dwtx.jface.text.IWidgetTokenOwner; +import dwtx.jface.text.IWidgetTokenOwnerExtension; +import dwtx.jface.text.Region; +import dwtx.jface.text.TextUtilities; + + +/** + * Standard implementation of IInformationPresenter. + * This implementation extends AbstractInformationControlManager. + * The information control is made visible on request by calling + * {@link #showInformationControl(Rectangle)}. + *

                  + * Usually, clients instantiate this class and configure it before using it. The configuration + * must be consistent: This means the used {@link dwtx.jface.text.IInformationControlCreator} + * must create an information control expecting information in the same format the configured + * {@link dwtx.jface.text.information.IInformationProvider}s use to encode the information they provide. + *

                  + * + * @since 2.0 + */ +public class InformationPresenter : AbstractInformationControlManager , IInformationPresenter, IInformationPresenterExtension, IWidgetTokenKeeper, IWidgetTokenKeeperExtension { + + alias AbstractInformationControlManager.install install; + public override void showInformation(){ + super.showInformation(); + } + + /** + * Priority of the info controls managed by this information presenter. + * Default value: 5. + * + * @since 3.0 + */ + /* + * 5 as value has been chosen in order to beat the hovers of {@link dwtx.jface.text.TextViewerHoverManager} + */ + public static const int WIDGET_PRIORITY= 5; + + + /** + * Internal information control closer. Listens to several events issued by its subject control + * and closes the information control when necessary. + */ + class Closer : IInformationControlCloser, ControlListener, MouseListener, FocusListener, IViewportListener, KeyListener { + + /** The subject control. */ + private Control fSubjectControl; + /** The information control. */ + private IInformationControl fInformationControlToClose; + /** Indicates whether this closer is active. */ + private bool fIsActive= false; + + /* + * @see IInformationControlCloser#setSubjectControl(Control) + */ + public void setSubjectControl(Control control) { + fSubjectControl= control; + } + + /* + * @see IInformationControlCloser#setInformationControl(IInformationControl) + */ + public void setInformationControl(IInformationControl control) { + fInformationControlToClose= control; + } + + /* + * @see IInformationControlCloser#start(Rectangle) + */ + public void start(Rectangle informationArea) { + + if (fIsActive) + return; + fIsActive= true; + + if (fSubjectControl !is null && !fSubjectControl.isDisposed()) { + fSubjectControl.addControlListener(this); + fSubjectControl.addMouseListener(this); + fSubjectControl.addFocusListener(this); + fSubjectControl.addKeyListener(this); + } + + if (fInformationControlToClose !is null) + fInformationControlToClose.addFocusListener(this); + + fTextViewer.addViewportListener(this); + } + + /* + * @see IInformationControlCloser#stop() + */ + public void stop() { + + if (!fIsActive) + return; + fIsActive= false; + + fTextViewer.removeViewportListener(this); + + if (fInformationControlToClose !is null) + fInformationControlToClose.removeFocusListener(this); + + if (fSubjectControl !is null && !fSubjectControl.isDisposed()) { + fSubjectControl.removeControlListener(this); + fSubjectControl.removeMouseListener(this); + fSubjectControl.removeFocusListener(this); + fSubjectControl.removeKeyListener(this); + } + } + + /* + * @see ControlListener#controlResized(ControlEvent) + */ + public void controlResized(ControlEvent e) { + hideInformationControl(); + } + + /* + * @see ControlListener#controlMoved(ControlEvent) + */ + public void controlMoved(ControlEvent e) { + hideInformationControl(); + } + + /* + * @see MouseListener#mouseDown(MouseEvent) + */ + public void mouseDown(MouseEvent e) { + hideInformationControl(); + } + + /* + * @see MouseListener#mouseUp(MouseEvent) + */ + public void mouseUp(MouseEvent e) { + } + + /* + * @see MouseListener#mouseDoubleClick(MouseEvent) + */ + public void mouseDoubleClick(MouseEvent e) { + hideInformationControl(); + } + + /* + * @see FocusListener#focusGained(FocusEvent) + */ + public void focusGained(FocusEvent e) { + } + + /* + * @see FocusListener#focusLost(FocusEvent) + */ + public void focusLost(FocusEvent e) { + Display d= fSubjectControl.getDisplay(); + d.asyncExec(new class() Runnable { + // Without the asyncExec, mouse clicks to the workbench window are swallowed. + public void run() { + if (fInformationControlToClose is null || !fInformationControlToClose.isFocusControl()) + hideInformationControl(); + } + }); + } + + /* + * @see IViewportListenerListener#viewportChanged(int) + */ + public void viewportChanged(int topIndex) { + hideInformationControl(); + } + + /* + * @see KeyListener#keyPressed(KeyEvent) + */ + public void keyPressed(KeyEvent e) { + hideInformationControl(); + } + + /* + * @see KeyListener#keyReleased(KeyEvent) + */ + public void keyReleased(KeyEvent e) { + } + } + + + /** The text viewer this information presenter works on */ + private ITextViewer fTextViewer; + /** The map of IInformationProvider objects */ + private Map fProviders; + /** The offset to override selection. */ + private int fOffset= -1; + /** + * The document partitioning for this information presenter. + * @since 3.0 + */ + private String fPartitioning; + + /** + * Creates a new information presenter that uses the given information control creator. + * The presenter is not installed on any text viewer yet. By default, an information + * control closer is set that closes the information control in the event of key strokes, + * resizing, moves, focus changes, mouse clicks, and disposal - all of those applied to + * the information control's parent control. Also, the setup ensures that the information + * control when made visible will request the focus. By default, the default document + * partitioning {@link IDocumentExtension3#DEFAULT_PARTITIONING} is used. + * + * @param creator the information control creator to be used + */ + public this(IInformationControlCreator creator) { + super(creator); + setCloser(new Closer()); + takesFocusWhenVisible(true); + fPartitioning= IDocumentExtension3.DEFAULT_PARTITIONING; + } + + /** + * Sets the document partitioning to be used by this information presenter. + * + * @param partitioning the document partitioning to be used by this information presenter + * @since 3.0 + */ + public void setDocumentPartitioning(String partitioning) { + Assert.isNotNull(partitioning); + fPartitioning= partitioning; + } + + /* + * @see dwtx.jface.text.information.IInformationPresenterExtension#getDocumentPartitioning() + * @since 3.0 + */ + public String getDocumentPartitioning() { + return fPartitioning; + } + + /** + * Registers a given information provider for a particular content type. + * If there is already a provider registered for this type, the new provider + * is registered instead of the old one. + * + * @param provider the information provider to register, or null to remove an existing one + * @param contentType the content type under which to register + */ + public void setInformationProvider(IInformationProvider provider, String contentType) { + + Assert.isNotNull(contentType); + + if (fProviders is null) + fProviders= new HashMap(); + + if (provider is null) + fProviders.remove(contentType); + else + fProviders.put(contentType, cast(Object)provider); + } + + /* + * @see IInformationPresenter#getInformationProvider(String) + */ + public IInformationProvider getInformationProvider(String contentType) { + if (fProviders is null) + return null; + + return cast(IInformationProvider) fProviders.get(contentType); + } + + /** + * Sets a offset to override the selection. Setting the value to -1 will disable + * overriding. + * + * @param offset the offset to override selection or -1 + */ + public void setOffset(int offset) { + fOffset= offset; + } + + /* + * @see AbstractInformationControlManager#computeInformation() + */ + protected void computeInformation() { + + int offset= fOffset < 0 ? fTextViewer.getSelectedRange().x : fOffset; + if (offset is -1) + return; + + fOffset= -1; + + IInformationProvider provider= null; + try { + String contentType= TextUtilities.getContentType(fTextViewer.getDocument(), getDocumentPartitioning(), offset, true); + provider= getInformationProvider(contentType); + } catch (BadLocationException x) { + } + if (provider is null) + return; + + IRegion subject= provider.getSubject(fTextViewer, offset); + if (subject is null) + return; + + Object info; + if ( cast(IInformationProviderExtension)provider ) { + IInformationProviderExtension extension= cast(IInformationProviderExtension) provider; + info= extension.getInformation2(fTextViewer, subject); + } else { + // backward compatibility code + info= stringcast(provider.getInformation(fTextViewer, subject)); + } + + if ( cast(IInformationProviderExtension2)provider ) + setCustomInformationControlCreator((cast(IInformationProviderExtension2) provider).getInformationPresenterControlCreator()); + else + setCustomInformationControlCreator(null); + + setInformation(info, computeArea(subject)); + } + + /** + * Determines the graphical area covered by the given text region. + * + * @param region the region whose graphical extend must be computed + * @return the graphical extend of the given region + */ + private Rectangle computeArea(IRegion region) { + + int start= 0; + int end= 0; + + IRegion widgetRegion= modelRange2WidgetRange(region); + if (widgetRegion !is null) { + start= widgetRegion.getOffset(); + end= widgetRegion.getOffset() + widgetRegion.getLength(); + } + + StyledText styledText= fTextViewer.getTextWidget(); + Rectangle bounds; + if (end > 0 && start < end) + bounds= styledText.getTextBounds(start, end - 1); + else { + Point loc= styledText.getLocationAtOffset(start); + bounds= new Rectangle(loc.x, loc.y, 0, styledText.getLineHeight(start)); + } + + return bounds; + } + + /** + * Translated the given range in the viewer's document into the corresponding + * range of the viewer's widget. + * + * @param region the range in the viewer's document + * @return the corresponding widget range + * @since 2.1 + */ + private IRegion modelRange2WidgetRange(IRegion region) { + if ( cast(ITextViewerExtension5)fTextViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) fTextViewer; + return extension.modelRange2WidgetRange(region); + } + + IRegion visibleRegion= fTextViewer.getVisibleRegion(); + int start= region.getOffset() - visibleRegion.getOffset(); + int end= start + region.getLength(); + if (end > visibleRegion.getLength()) + end= visibleRegion.getLength(); + + return new Region(start, end - start); + } + + /* + * @see IInformationPresenter#install(ITextViewer) + */ + public void install(ITextViewer textViewer) { + fTextViewer= textViewer; + install(fTextViewer.getTextWidget()); + } + + /* + * @see IInformationPresenter#uninstall() + */ + public void uninstall() { + dispose(); + } + + /* + * @see AbstractInformationControlManager#showInformationControl(Rectangle) + */ + protected void showInformationControl(Rectangle subjectArea) { + if ( cast(IWidgetTokenOwnerExtension)fTextViewer && cast(IWidgetTokenOwner)fTextViewer ) { + IWidgetTokenOwnerExtension extension= cast(IWidgetTokenOwnerExtension) fTextViewer; + if (extension.requestWidgetToken(this, WIDGET_PRIORITY)) + super.showInformationControl(subjectArea); + } else if ( cast(IWidgetTokenOwner)fTextViewer ) { + IWidgetTokenOwner owner= cast(IWidgetTokenOwner) fTextViewer; + if (owner.requestWidgetToken(this)) + super.showInformationControl(subjectArea); + + } else + super.showInformationControl(subjectArea); + } + + /* + * @see AbstractInformationControlManager#hideInformationControl() + */ + protected void hideInformationControl() { + try { + super.hideInformationControl(); + } finally { + if ( cast(IWidgetTokenOwner)fTextViewer ) { + IWidgetTokenOwner owner= cast(IWidgetTokenOwner) fTextViewer; + owner.releaseWidgetToken(this); + } + } + } + + /* + * @see AbstractInformationControlManager#handleInformationControlDisposed() + */ + protected void handleInformationControlDisposed() { + try { + super.handleInformationControlDisposed(); + } finally { + if ( cast(IWidgetTokenOwner)fTextViewer ) { + IWidgetTokenOwner owner= cast(IWidgetTokenOwner) fTextViewer; + owner.releaseWidgetToken(this); + } + } + } + + /* + * @see dwtx.jface.text.IWidgetTokenKeeper#requestWidgetToken(IWidgetTokenOwner) + */ + public bool requestWidgetToken(IWidgetTokenOwner owner) { + return false; + } + + /* + * @see dwtx.jface.text.IWidgetTokenKeeperExtension#requestWidgetToken(dwtx.jface.text.IWidgetTokenOwner, int) + * @since 3.0 + */ + public bool requestWidgetToken(IWidgetTokenOwner owner, int priority) { + return false; + } + + /* + * @see dwtx.jface.text.IWidgetTokenKeeperExtension#setFocus(dwtx.jface.text.IWidgetTokenOwner) + * @since 3.0 + */ + public bool setFocus(IWidgetTokenOwner owner) { + return false; + } +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/link/ILinkedModeListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/link/ILinkedModeListener.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.link.ILinkedModeListener; + +import dwtx.jface.text.link.LinkedModeModel; // packageimport +import dwtx.jface.text.link.LinkedPosition; // packageimport +import dwtx.jface.text.link.TabStopIterator; // packageimport +import dwtx.jface.text.link.LinkedModeUI; // packageimport +import dwtx.jface.text.link.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.link.LinkedPositionGroup; // packageimport +import dwtx.jface.text.link.LinkedModeManager; // packageimport +import dwtx.jface.text.link.LinkedPositionAnnotations; // packageimport +import dwtx.jface.text.link.ProposalPosition; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Protocol used by {@link LinkedModeModel}s to communicate state changes, such + * as leaving linked mode, suspending it due to a child mode coming up, and + * resuming after a child mode has left. + *

                  + * This interface may implemented by clients. + *

                  + * + * @since 3.0 + */ +public interface ILinkedModeListener { + + /** Flag to leave specifying no special action. */ + static const int NONE= 0; + /** + * Flag to leave specifying that all nested modes should + * exit. + */ + static const int EXIT_ALL= 1 << 0; + /** + * Flag to leave specifying that the caret should be moved to + * the exit position. + */ + static const int UPDATE_CARET= 1 << 1; + /** + * Flag to leave specifying that a UI of a parent mode should + * select the current position. + */ + static const int SELECT= 1 << 2; + /** + * Flag to leave specifying that document content outside of + * a linked position was modified. + */ + static const int EXTERNAL_MODIFICATION= 1 << 3; + + /** + * The leave event occurs when linked is left. + * + * @param model the model being left + * @param flags the reason and commands for leaving linked mode + */ + void left(LinkedModeModel model, int flags); + + /** + * The suspend event occurs when a nested linked mode is installed within + * model. + * + * @param model the model being suspended due to a nested model being + * installed + */ + void suspend(LinkedModeModel model); + + /** + * The resume event occurs when a nested linked mode exits. + * + * @param model the linked mode model being resumed due to a nested mode + * exiting + * @param flags the commands to execute when resuming after suspend + */ + void resume(LinkedModeModel model, int flags); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/link/InclusivePositionUpdater.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/link/InclusivePositionUpdater.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,125 @@ +/******************************************************************************* + * 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 + * 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.text.link.InclusivePositionUpdater; + +import dwtx.jface.text.link.LinkedModeModel; // packageimport +import dwtx.jface.text.link.LinkedPosition; // packageimport +import dwtx.jface.text.link.ILinkedModeListener; // packageimport +import dwtx.jface.text.link.TabStopIterator; // packageimport +import dwtx.jface.text.link.LinkedModeUI; // packageimport +import dwtx.jface.text.link.LinkedPositionGroup; // packageimport +import dwtx.jface.text.link.LinkedModeManager; // packageimport +import dwtx.jface.text.link.LinkedPositionAnnotations; // packageimport +import dwtx.jface.text.link.ProposalPosition; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.BadPositionCategoryException; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IPositionUpdater; +import dwtx.jface.text.Position; + + +/** + * Position updater that considers any change in + * [p.offset, p.offset + p.length] of a {@link Position} + * p as belonging to the position. + *

                  + * Internal class. Do not use. Public for testing purposes only. + *

                  + * + * @since 3.0 + * @noinstantiate This class is not intended to be instantiated by clients. + * @noextend This class is not intended to be subclassed by clients. + */ +public class InclusivePositionUpdater : IPositionUpdater { + + /** The position category. */ + private const String fCategory; + + /** + * Creates a new updater for the given category. + * + * @param category the new category. + */ + public this(String category) { + fCategory= category; + } + + /* + * @see dwtx.jface.text.IPositionUpdater#update(dwtx.jface.text.DocumentEvent) + */ + public void update(DocumentEvent event) { + + int eventOffset= event.getOffset(); + int eventOldLength= event.getLength(); + int eventNewLength= event.getText() is null ? 0 : event.getText().length(); + int deltaLength= eventNewLength - eventOldLength; + + try { + Position[] positions= event.getDocument().getPositions(fCategory); + + for (int i= 0; i !is positions.length; i++) { + + Position position= positions[i]; + + if (position.isDeleted()) + continue; + + int offset= position.getOffset(); + int length= position.getLength(); + int end= offset + length; + + if (offset > eventOffset + eventOldLength) + // position comes way + // after change - shift + position.setOffset(offset + deltaLength); + else if (end < eventOffset) { + // position comes way before change - + // leave alone + } else if (offset <= eventOffset && end >= eventOffset + eventOldLength) { + // event completely internal to the position - adjust length + position.setLength(length + deltaLength); + } else if (offset < eventOffset) { + // event extends over end of position - adjust length + int newEnd= eventOffset + eventNewLength; + position.setLength(newEnd - offset); + } else if (end > eventOffset + eventOldLength) { + // event extends from before position into it - adjust offset + // and length + // offset becomes end of event, length adjusted accordingly + // we want to recycle the overlapping part + position.setOffset(eventOffset); + int deleted= eventOffset + eventOldLength - offset; + position.setLength(length - deleted + eventNewLength); + } else { + // event consumes the position - delete it + position.delete_(); + } + } + } catch (BadPositionCategoryException e) { + // ignore and return + } + } + + /** + * Returns the position category. + * + * @return the position category + */ + public String getCategory() { + return fCategory; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/link/LinkedModeManager.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/link/LinkedModeManager.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,262 @@ +/******************************************************************************* + * 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 + * 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.text.link.LinkedModeManager; + +import dwtx.jface.text.link.LinkedModeModel; // packageimport +import dwtx.jface.text.link.LinkedPosition; // packageimport +import dwtx.jface.text.link.ILinkedModeListener; // packageimport +import dwtx.jface.text.link.TabStopIterator; // packageimport +import dwtx.jface.text.link.LinkedModeUI; // packageimport +import dwtx.jface.text.link.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.link.LinkedPositionGroup; // packageimport +import dwtx.jface.text.link.LinkedPositionAnnotations; // packageimport +import dwtx.jface.text.link.ProposalPosition; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + + + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.IDocument; + + +/** + * A linked mode manager ensures exclusive access of linked position infrastructures to documents. There + * is at most one LinkedModeManager installed on the same document. The getManager + * methods will return the existing instance if any of the specified documents already have an installed + * manager. + * + * @since 3.0 + */ +class LinkedModeManager { + + /** + * Our implementation of ILinkedModeListener. + */ + private class Listener : ILinkedModeListener { + + /* + * @see dwtx.jdt.internal.ui.text.link2.LinkedModeModel.ILinkedModeListener#left(dwtx.jdt.internal.ui.text.link2.LinkedModeModel, int) + */ + public void left(LinkedModeModel model, int flags) { + this.outer.left(model, flags); + } + + /* + * @see dwtx.jdt.internal.ui.text.link2.LinkedModeModel.ILinkedModeListener#suspend(dwtx.jdt.internal.ui.text.link2.LinkedModeModel) + */ + public void suspend(LinkedModeModel model) { + // not interested + } + + /* + * @see dwtx.jdt.internal.ui.text.link2.LinkedModeModel.ILinkedModeListener#resume(dwtx.jdt.internal.ui.text.link2.LinkedModeModel, int) + */ + public void resume(LinkedModeModel model, int flags) { + // not interested + } + + } + + /** Global map from documents to managers. */ + private static Map fgManagers_; + private static Map fgManagers(){ + if( fgManagers_ is null ){ + synchronized( LinkedModeManager.classinfo ){ + if( fgManagers_ is null ){ + fgManagers_= new HashMap(); + } + } + } + return fgManagers_; + } + /** + * Returns whether there exists a LinkedModeManager on document. + * + * @param document the document of interest + * @return true if there exists a LinkedModeManager on document, false otherwise + */ + public static bool hasManager(IDocument document) { + return fgManagers.get(cast(Object)document) !is null; + } + + /** + * Returns whether there exists a LinkedModeManager on any of the documents. + * + * @param documents the documents of interest + * @return true if there exists a LinkedModeManager on any of the documents, false otherwise + */ + public static bool hasManager(IDocument[] documents) { + for (int i= 0; i < documents.length; i++) { + if (hasManager(documents[i])) + return true; + } + return false; + } + + /** + * Returns the manager for the given documents. If force is + * true, any existing conflicting managers are canceled, otherwise, + * the method may return null if there are conflicts. + * + * @param documents the documents of interest + * @param force whether to kill any conflicting managers + * @return a manager able to cover the requested documents, or null if there is a conflict and force was set to false + */ + public static LinkedModeManager getLinkedManager(IDocument[] documents, bool force) { + if (documents is null || documents.length is 0) + return null; + + Set mgrs= new HashSet(); + LinkedModeManager mgr= null; + for (int i= 0; i < documents.length; i++) { + mgr= cast(LinkedModeManager) fgManagers.get(cast(Object)documents[i]); + if (mgr !is null) + mgrs.add(mgr); + } + if (mgrs.size() > 1) + if (force) { + for (Iterator it= mgrs.iterator(); it.hasNext(); ) { + LinkedModeManager m= cast(LinkedModeManager) it.next(); + m.closeAllEnvironments(); + } + } else { + return null; + } + + if (mgrs.size() is 0) + mgr= new LinkedModeManager(); + + for (int i= 0; i < documents.length; i++) + fgManagers.put(cast(Object)documents[i], mgr); + + return mgr; + } + + /** + * Cancels any linked mode manager for the specified document. + * + * @param document the document whose LinkedModeManager should be canceled + */ + public static void cancelManager(IDocument document) { + LinkedModeManager mgr= cast(LinkedModeManager) fgManagers.get(cast(Object)document); + if (mgr !is null) + mgr.closeAllEnvironments(); + } + + /** The hierarchy of environments managed by this manager. */ + private Stack fEnvironments; + private Listener fListener; + + this(){ + fEnvironments= new Stack(); + fListener= new Listener(); + } + + /** + * Notify the manager about a leaving model. + * + * @param model + * @param flags + */ + private void left(LinkedModeModel model, int flags) { + if (!fEnvironments.contains(model)) + return; + + while (!fEnvironments.isEmpty()) { + LinkedModeModel env= cast(LinkedModeModel) fEnvironments.pop(); + if (env is model) + break; + env.exit(ILinkedModeListener.NONE); + } + + if (fEnvironments.isEmpty()) { + removeManager(); + } + } + + private void closeAllEnvironments() { + while (!fEnvironments.isEmpty()) { + LinkedModeModel env= cast(LinkedModeModel) fEnvironments.pop(); + env.exit(ILinkedModeListener.NONE); + } + + removeManager(); + } + + private void removeManager() { + for (Iterator it= fgManagers.keySet().iterator(); it.hasNext();) { + IDocument doc= cast(IDocument) it.next(); + if (fgManagers.get(cast(Object)doc) is this) + it.remove(); + } + } + + /** + * Tries to nest the given LinkedModeModel onto the top of + * the stack of environments managed by the receiver. If force + * is true, any environments on the stack that create a conflict + * are killed. + * + * @param model the model to nest + * @param force whether to force the addition of the model + * @return true if nesting was successful, false otherwise (only possible if force is false + */ + public bool nestEnvironment(LinkedModeModel model, bool force) { + Assert.isNotNull(model); + + try { + while (true) { + if (fEnvironments.isEmpty()) { + model.addLinkingListener(fListener); + fEnvironments.push(model); + return true; + } + + LinkedModeModel top= cast(LinkedModeModel) fEnvironments.peek(); + if (model.canNestInto(top)) { + model.addLinkingListener(fListener); + fEnvironments.push(model); + return true; + } else if (!force) { + return false; + } else { // force + fEnvironments.pop(); + top.exit(ILinkedModeListener.NONE); + // continue; + } + } + } finally { + // if we remove any, make sure the new one got inserted + Assert.isTrue(fEnvironments.size() > 0); + } + } + + /** + * Returns the LinkedModeModel that is on top of the stack of + * environments managed by the receiver. + * + * @return the topmost LinkedModeModel + */ + public LinkedModeModel getTopEnvironment() { + if (fEnvironments.isEmpty()) + return null; + return cast(LinkedModeModel) fEnvironments.peek(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/link/LinkedModeModel.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/link/LinkedModeModel.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,791 @@ +/******************************************************************************* + * 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 + * 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.text.link.LinkedModeModel; + +import dwtx.jface.text.link.LinkedPosition; // packageimport +import dwtx.jface.text.link.ILinkedModeListener; // packageimport +import dwtx.jface.text.link.TabStopIterator; // packageimport +import dwtx.jface.text.link.LinkedModeUI; // packageimport +import dwtx.jface.text.link.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.link.LinkedPositionGroup; // packageimport +import dwtx.jface.text.link.LinkedModeManager; // packageimport +import dwtx.jface.text.link.LinkedPositionAnnotations; // packageimport +import dwtx.jface.text.link.ProposalPosition; // packageimport + + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.BadPositionCategoryException; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentExtension; +import dwtx.jface.text.IDocumentListener; +import dwtx.jface.text.IPositionUpdater; +import dwtx.jface.text.Position; +import dwtx.jface.text.IDocumentExtension; +import dwtx.text.edits.MalformedTreeException; +import dwtx.text.edits.TextEdit; + + +/** + * The model for linked mode, umbrellas several + * {@link LinkedPositionGroup}s. Once installed, the model + * propagates any changes to a position to all its siblings in the same position + * group. + *

                  + * Setting up a model consists of first adding + * LinkedPositionGroups to it, and then installing the + * model by either calling {@link #forceInstall()} or + * {@link #tryInstall()}. After installing the model, it becomes + * sealed and no more groups may be added. + *

                  + *

                  + * If a document change occurs that would modify more than one position + * group or that would invalidate the disjointness requirement of the positions, + * the model is torn down and all positions are deleted. The same happens + * upon calling {@link #exit(int)}. + *

                  + *

                  Nesting

                  + *

                  + * A LinkedModeModel may be nested into another model. This + * happens when installing a model the positions of which all fit into a + * single position in a parent model that has previously been installed on + * the same document(s). + *

                  + *

                  + * Clients may instantiate instances of this class. + *

                  + * + * @since 3.0 + * @noextend This class is not intended to be subclassed by clients. + */ +public class LinkedModeModel { + + /** + * Checks whether there is already a model installed on document. + * + * @param document the IDocument of interest + * @return true if there is an existing model, false + * otherwise + */ + public static bool hasInstalledModel(IDocument document) { + // if there is a manager, there also is a model + return LinkedModeManager.hasManager(document); + } + + /** + * Checks whether there is already a linked mode model installed on any of + * the documents. + * + * @param documents the IDocuments of interest + * @return true if there is an existing model, false + * otherwise + */ + public static bool hasInstalledModel(IDocument[] documents) { + // if there is a manager, there also is a model + return LinkedModeManager.hasManager(documents); + } + + /** + * Cancels any linked mode model on the specified document. If there is no + * model, nothing happens. + * + * @param document the document whose LinkedModeModel should + * be canceled + */ + public static void closeAllModels(IDocument document) { + LinkedModeManager.cancelManager(document); + } + + /** + * Returns the model currently active on document at + * offset, or null if there is none. + * + * @param document the document for which the caller asks for a + * model + * @param offset the offset into document, as there may be + * several models on a document + * @return the model currently active on document, or + * null + */ + public static LinkedModeModel getModel(IDocument document, int offset) { + if (!hasInstalledModel(document)) + return null; + + LinkedModeManager mgr= LinkedModeManager.getLinkedManager([document], false); + if (mgr !is null) + return mgr.getTopEnvironment(); + return null; + } + + /** + * Encapsulates the edition triggered by a change to a linking position. Can + * be applied to a document as a whole. + */ + private class Replace : IDocumentExtension.IReplace { + + /** The edition to apply on a document. */ + private TextEdit fEdit; + + /** + * Creates a new instance. + * + * @param edit the edition to apply to a document. + */ + public this(TextEdit edit) { + fEdit= edit; + } + + /* + * @see dwtx.jface.text.IDocumentExtension.IReplace#perform(dwtx.jface.text.IDocument, dwtx.jface.text.IDocumentListener) + */ + public void perform(IDocument document, IDocumentListener owner) { + document.removeDocumentListener(owner); + fIsChanging= true; + try { + fEdit.apply(document, TextEdit.UPDATE_REGIONS | TextEdit.CREATE_UNDO); + } catch (BadLocationException e) { + /* XXX: perform should really throw a BadLocationException + * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=52950 + */ + throw new RuntimeException(e); + } finally { + document.addDocumentListener(owner); + fIsChanging= false; + } + } + + } + + /** + * The document listener triggering the linked updating of positions + * managed by this model. + */ + private class DocumentListener : IDocumentListener { + + private bool fExit= false; + + /** + * Checks whether event occurs within any of the positions + * managed by this model. If not, the linked mode is left. + * + * @param event {@inheritDoc} + */ + public void documentAboutToBeChanged(DocumentEvent event) { + // don't react on changes executed by the parent model + if (fParentEnvironment !is null && fParentEnvironment.isChanging()) + return; + + for (Iterator it= fGroups.iterator(); it.hasNext(); ) { + LinkedPositionGroup group= cast(LinkedPositionGroup) it.next(); + if (!group.isLegalEvent(event)) { + fExit= true; + return; + } + } + } + + /** + * Propagates a change to a linked position to all its sibling positions. + * + * @param event {@inheritDoc} + */ + public void documentChanged(DocumentEvent event) { + if (fExit) { + this.outer.exit(ILinkedModeListener.EXTERNAL_MODIFICATION); + return; + } + fExit= false; + + // don't react on changes executed by the parent model + if (fParentEnvironment !is null && fParentEnvironment.isChanging()) + return; + + // collect all results + Map result= null; + for (Iterator it= fGroups.iterator(); it.hasNext();) { + LinkedPositionGroup group= cast(LinkedPositionGroup) it.next(); + + Map map= group.handleEvent(event); + if (result !is null && map !is null) { + // exit if more than one position was changed + this.outer.exit(ILinkedModeListener.EXTERNAL_MODIFICATION); + return; + } + if (map !is null) + result= map; + } + + if (result !is null) { + // edit all documents + for (Iterator it2= result.keySet().iterator(); it2.hasNext(); ) { + IDocument doc= cast(IDocument) it2.next(); + TextEdit edit= cast(TextEdit) result.get(cast(Object)doc); + Replace replace= new Replace(edit); + + // apply the edition, either as post notification replace + // on the calling document or directly on any other + // document + if (doc is event.getDocument()) { + if ( cast(IDocumentExtension)doc ) { + (cast(IDocumentExtension) doc).registerPostNotificationReplace(this, replace); + } else { + // ignore - there is no way we can log from JFace text... + } + } else { + replace.perform(doc, this); + } + } + } + } + + } + + /** The set of linked position groups. */ + private const List fGroups; + /** The set of documents spanned by this group. */ + private const Set fDocuments; + /** The position updater for linked positions. */ + private const IPositionUpdater fUpdater; + /** The document listener on the documents affected by this model. */ + private const DocumentListener fDocumentListener; + /** The parent model for a hierarchical set up, or null. */ + private LinkedModeModel fParentEnvironment; + /** + * The position in fParentEnvironment that includes all + * positions in this object, or null if there is no parent + * model. + */ + private LinkedPosition fParentPosition= null; + /** + * A model is sealed once it has children - no more positions can be + * added. + */ + private bool fIsSealed= false; + /** true when this model is changing documents. */ + private bool fIsChanging= false; + /** The linked listeners. */ + private const List fListeners; + /** Flag telling whether we have exited: */ + private bool fIsActive= true; + /** + * The sequence of document positions as we are going to iterate through + * them. + */ + private List fPositionSequence; + + /** + * Whether we are in the process of editing documents (set by Replace, + * read by DocumentListener. + * + * @return true if we are in the process of editing a + * document, false otherwise + */ + private bool isChanging() { + return fIsChanging || fParentEnvironment !is null && fParentEnvironment.isChanging(); + } + + /** + * Throws a BadLocationException if group + * conflicts with this model's groups. + * + * @param group the group being checked + * @throws BadLocationException if group conflicts with this + * model's groups + */ + private void enforceDisjoint(LinkedPositionGroup group) { + for (Iterator it= fGroups.iterator(); it.hasNext(); ) { + LinkedPositionGroup g= cast(LinkedPositionGroup) it.next(); + g.enforceDisjoint(group); + } + } + + /** + * Causes this model to exit. Called either if an illegal document change + * is detected, or by the UI. + * + * @param flags the exit flags as defined in {@link ILinkedModeListener} + */ + public void exit(int flags) { + if (!fIsActive) + return; + + fIsActive= false; + + for (Iterator it= fDocuments.iterator(); it.hasNext(); ) { + IDocument doc= cast(IDocument) it.next(); + try { + doc.removePositionCategory(getCategory()); + } catch (BadPositionCategoryException e) { + // won't happen + Assert.isTrue(false); + } + doc.removePositionUpdater(fUpdater); + doc.removeDocumentListener(fDocumentListener); + } + + fDocuments.clear(); + fGroups.clear(); + + List listeners= new ArrayList(fListeners); + fListeners.clear(); + for (Iterator it= listeners.iterator(); it.hasNext(); ) { + ILinkedModeListener listener= cast(ILinkedModeListener) it.next(); + listener.left(this, flags); + } + + + if (fParentEnvironment !is null) + fParentEnvironment.resume(flags); + } + + /** + * Causes this model to stop forwarding updates. The positions are not + * unregistered however, which will only happen when exit + * is called, or after the next document change. + * + * @param flags the exit flags as defined in {@link ILinkedModeListener} + * @since 3.1 + */ + public void stopForwarding(int flags) { + fDocumentListener.fExit= true; + } + + /** + * Puts document into the set of managed documents. This + * involves registering the document listener and adding our position + * category. + * + * @param document the new document + */ + private void manageDocument(IDocument document) { + if (!fDocuments.contains(cast(Object)document)) { + fDocuments.add(cast(Object)document); + document.addPositionCategory(getCategory()); + document.addPositionUpdater(fUpdater); + document.addDocumentListener(fDocumentListener); + } + + } + + /** + * Returns the position category used by this model. + * + * @return the position category used by this model + */ + private String getCategory() { + return toString(); + } + + /** + * Adds a position group to this LinkedModeModel. This + * method may not be called if the model has been installed. Also, if + * a UI has been set up for this model, it may not pick up groups + * added afterwards. + *

                  + * If the positions in group conflict with any other group in + * this model, a BadLocationException is thrown. Also, + * if this model is nested inside another one, all positions in all + * groups of the child model have to reside within a single position in the + * parent model, otherwise a BadLocationException is thrown. + *

                  + *

                  + * If group already exists, nothing happens. + *

                  + * + * @param group the group to be added to this model + * @throws BadLocationException if the group conflicts with the other groups + * in this model or violates the nesting requirements. + * @throws IllegalStateException if the method is called when the + * model is already sealed + */ + public void addGroup(LinkedPositionGroup group) { + if (group is null) + throw new IllegalArgumentException("group may not be null"); //$NON-NLS-1$ + if (fIsSealed) + throw new IllegalStateException("model is already installed"); //$NON-NLS-1$ + if (fGroups.contains(group)) + // nothing happens + return; + + enforceDisjoint(group); + group.seal(); + fGroups.add(group); + } + + /** + * Creates a new model. + * @since 3.1 + */ + public this() { + // DWT inst init + fGroups= new ArrayList(); + fDocuments= new HashSet(); + fUpdater= new InclusivePositionUpdater(getCategory()); + fDocumentListener= new DocumentListener(); + fListeners= new ArrayList(); + fPositionSequence= new ArrayList(); + + } + + /** + * Installs this model, which includes registering as document + * listener on all involved documents and storing global information about + * this model. Any conflicting model already present will be + * closed. + *

                  + * If an exception is thrown, the installation failed and + * the model is unusable. + *

                  + * + * @throws BadLocationException if some of the positions of this model + * were not valid positions on their respective documents + */ + public void forceInstall() { + if (!install(true)) + Assert.isTrue(false); + } + + /** + * Installs this model, which includes registering as document + * listener on all involved documents and storing global information about + * this model. If there is another model installed on the + * document(s) targeted by the receiver that conflicts with it, installation + * may fail. + *

                  + * The return value states whether installation was + * successful; if not, the model is not installed and will not work. + *

                  + * + * @return true if installation was successful, + * false otherwise + * @throws BadLocationException if some of the positions of this model + * were not valid positions on their respective documents + */ + public bool tryInstall() { + return install(false); + } + + /** + * Installs this model, which includes registering as document + * listener on all involved documents and storing global information about + * this model. The return value states whether installation was + * successful; if not, the model is not installed and will not work. + * The return value can only then become false if + * force was set to false as well. + * + * @param force if true, any other model that cannot + * coexist with this one is canceled; if false, + * install will fail when conflicts occur and return false + * @return true if installation was successful, + * false otherwise + * @throws BadLocationException if some of the positions of this model + * were not valid positions on their respective documents + */ + private bool install(bool force) { + if (fIsSealed) + throw new IllegalStateException("model is already installed"); //$NON-NLS-1$ + enforceNotEmpty(); + + IDocument[] documents= getDocuments(); + LinkedModeManager manager= LinkedModeManager.getLinkedManager(documents, force); + // if we force creation, we require a valid manager + Assert.isTrue(!(force && manager is null)); + if (manager is null) + return false; + + if (!manager.nestEnvironment(this, force)) + if (force) + Assert.isTrue(false); + else + return false; + + // we set up successfully. After this point, exit has to be called to + // remove registered listeners... + fIsSealed= true; + if (fParentEnvironment !is null) + fParentEnvironment.suspend(); + + // register positions + try { + for (Iterator it= fGroups.iterator(); it.hasNext(); ) { + LinkedPositionGroup group= cast(LinkedPositionGroup) it.next(); + group.register(this); + } + return true; + } catch (BadLocationException e){ + // if we fail to add, make sure to release all listeners again + exit(ILinkedModeListener.NONE); + throw e; + } + } + + /** + * Asserts that there is at least one linked position in this linked mode + * model, throws an IllegalStateException otherwise. + */ + private void enforceNotEmpty() { + bool hasPosition= false; + for (Iterator it= fGroups.iterator(); it.hasNext(); ) + if (!(cast(LinkedPositionGroup) it.next()).isEmpty()) { + hasPosition= true; + break; + } + if (!hasPosition) + throw new IllegalStateException("must specify at least one linked position"); //$NON-NLS-1$ + + } + + /** + * Collects all the documents that contained positions are set upon. + * @return the set of documents affected by this model + */ + private IDocument[] getDocuments() { + Set docs= new HashSet(); + for (Iterator it= fGroups.iterator(); it.hasNext(); ) { + LinkedPositionGroup group= cast(LinkedPositionGroup) it.next(); + docs.addAll(Arrays.asList(arraycast!(Object)(group.getDocuments()))); + } + return arraycast!(IDocument)( docs.toArray()); + } + + /** + * Returns whether the receiver can be nested into the given parent + * model. If yes, the parent model and its position that the receiver + * fits in are remembered. + * + * @param parent the parent model candidate + * @return true if the receiver can be nested into parent, false otherwise + */ + bool canNestInto(LinkedModeModel parent) { + for (Iterator it= fGroups.iterator(); it.hasNext(); ) { + LinkedPositionGroup group= cast(LinkedPositionGroup) it.next(); + if (!enforceNestability(group, parent)) { + fParentPosition= null; + return false; + } + } + + Assert.isNotNull(fParentPosition); + fParentEnvironment= parent; + return true; + } + + /** + * Called by nested models when a group is added to them. All + * positions in all groups of a nested model have to fit inside a + * single position in the parent model. + * + * @param group the group of the nested model to be adopted. + * @param model the model to check against + * @return false if it failed to enforce nestability + */ + private bool enforceNestability(LinkedPositionGroup group, LinkedModeModel model) { + Assert.isNotNull(model); + Assert.isNotNull(group); + + try { + for (Iterator it= model.fGroups.iterator(); it.hasNext(); ) { + LinkedPositionGroup pg= cast(LinkedPositionGroup) it.next(); + LinkedPosition pos; + pos= pg.adopt(group); + if (pos !is null && fParentPosition !is null && fParentPosition !is pos) + return false; // group does not fit into one parent position, which is illegal + else if (fParentPosition is null && pos !is null) + fParentPosition= pos; + } + } catch (BadLocationException e) { + return false; + } + + // group must fit into exactly one of the parent's positions + return fParentPosition !is null; + } + + /** + * Returns whether this model is nested. + * + *

                  + * This method is part of the private protocol between + * LinkedModeUI and LinkedModeModel. + *

                  + * + * @return true if this model is nested, + * false otherwise + */ + public bool isNested() { + return fParentEnvironment !is null; + } + + /** + * Returns the positions in this model that have a tab stop, in the + * order they were added. + * + *

                  + * This method is part of the private protocol between + * LinkedModeUI and LinkedModeModel. + *

                  + * + * @return the positions in this model that have a tab stop, in the + * order they were added + */ + public List getTabStopSequence() { + return fPositionSequence; + } + + /** + * Adds listener to the set of listeners that are informed + * upon state changes. + * + * @param listener the new listener + */ + public void addLinkingListener(ILinkedModeListener listener) { + Assert.isNotNull(cast(Object)listener); + if (!fListeners.contains(cast(Object)listener)) + fListeners.add(cast(Object)listener); + } + + /** + * Removes listener from the set of listeners that are + * informed upon state changes. + * + * @param listener the new listener + */ + public void removeLinkingListener(ILinkedModeListener listener) { + fListeners.remove(cast(Object)listener); + } + + /** + * Finds the position in this model that is closest after + * toFind. toFind needs not be a position in + * this model and serves merely as an offset. + * + *

                  + * This method part of the private protocol between + * LinkedModeUI and LinkedModeModel. + *

                  + * + * @param toFind the position to search from + * @return the closest position in the same document as toFind + * after the offset of toFind, or null + */ + public LinkedPosition findPosition(LinkedPosition toFind) { + LinkedPosition position= null; + for (Iterator it= fGroups.iterator(); it.hasNext(); ) { + LinkedPositionGroup group= cast(LinkedPositionGroup) it.next(); + position= group.getPosition(toFind); + if (position !is null) + break; + } + return position; + } + + /** + * Registers a LinkedPosition with this model. Called + * by PositionGroup. + * + * @param position the position to register + * @throws BadLocationException if the position cannot be added to its + * document + */ + void register(LinkedPosition position) { + Assert.isNotNull(position); + + IDocument document= position.getDocument(); + manageDocument(document); + try { + document.addPosition(getCategory(), position); + } catch (BadPositionCategoryException e) { + // won't happen as the category has been added by manageDocument() + Assert.isTrue(false); + } + int seqNr= position.getSequenceNumber(); + if (seqNr !is LinkedPositionGroup.NO_STOP) { + fPositionSequence.add(position); + } + } + + /** + * Suspends this model. + */ + private void suspend() { + List l= new ArrayList(fListeners); + for (Iterator it= l.iterator(); it.hasNext(); ) { + ILinkedModeListener listener= cast(ILinkedModeListener) it.next(); + listener.suspend(this); + } + } + + /** + * Resumes this model. flags can be NONE + * or SELECT. + * + * @param flags NONE or SELECT + */ + private void resume(int flags) { + List l= new ArrayList(fListeners); + for (Iterator it= l.iterator(); it.hasNext(); ) { + ILinkedModeListener listener= cast(ILinkedModeListener) it.next(); + listener.resume(this, flags); + } + } + + /** + * Returns whether an offset is contained by any position in this + * model. + * + * @param offset the offset to check + * @return true if offset is included by any + * position (see {@link LinkedPosition#includes(int)}) in this + * model, false otherwise + */ + public bool anyPositionContains(int offset) { + for (Iterator it= fGroups.iterator(); it.hasNext(); ) { + LinkedPositionGroup group= cast(LinkedPositionGroup) it.next(); + if (group.contains(offset)) + // take the first hit - exclusion is guaranteed by enforcing + // disjointness when adding positions + return true; + } + return false; + } + + /** + * Returns the linked position group that contains position, + * or null if position is not contained in any + * group within this model. Group containment is tested by calling + * group.contains(position) for every group in + * this model. + * + *

                  + * This method part of the private protocol between + * LinkedModeUI and LinkedModeModel. + *

                  + * + * @param position the position the group of which is requested + * @return the first group in this model for which + * group.contains(position) returns true, + * or null if no group contains position + */ + public LinkedPositionGroup getGroupForPosition(Position position) { + for (Iterator it= fGroups.iterator(); it.hasNext(); ) { + LinkedPositionGroup group= cast(LinkedPositionGroup) it.next(); + if (group.contains(position)) + return group; + } + return null; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/link/LinkedModeUI.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/link/LinkedModeUI.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,1353 @@ +/******************************************************************************* + * 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 + * 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.text.link.LinkedModeUI; + +import dwtx.jface.text.link.LinkedModeModel; // packageimport +import dwtx.jface.text.link.LinkedPosition; // packageimport +import dwtx.jface.text.link.ILinkedModeListener; // packageimport +import dwtx.jface.text.link.TabStopIterator; // packageimport +import dwtx.jface.text.link.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.link.LinkedPositionGroup; // packageimport +import dwtx.jface.text.link.LinkedModeManager; // packageimport +import dwtx.jface.text.link.LinkedPositionAnnotations; // packageimport +import dwtx.jface.text.link.ProposalPosition; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + + + + +import dwt.DWT; +import dwt.custom.StyledText; +import dwt.custom.VerifyKeyListener; +import dwt.events.ShellEvent; +import dwt.events.ShellListener; +import dwt.events.VerifyEvent; +import dwt.graphics.Point; +import dwt.widgets.Display; +import dwt.widgets.Shell; +import dwtx.core.runtime.Assert; +import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; +import dwtx.jface.internal.text.link.contentassist.IProposalListener; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.BadPartitioningException; +import dwtx.jface.text.BadPositionCategoryException; +import dwtx.jface.text.DefaultPositionUpdater; +import dwtx.jface.text.DocumentCommand; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IAutoEditStrategy; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentExtension3; +import dwtx.jface.text.IDocumentListener; +import dwtx.jface.text.IEditingSupport; +import dwtx.jface.text.IEditingSupportRegistry; +import dwtx.jface.text.IPositionUpdater; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.IRewriteTarget; +import dwtx.jface.text.ITextInputListener; +import dwtx.jface.text.ITextOperationTarget; +import dwtx.jface.text.ITextSelection; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.ITextViewerExtension; +import dwtx.jface.text.ITextViewerExtension2; +import dwtx.jface.text.ITextViewerExtension5; +import dwtx.jface.text.Position; +import dwtx.jface.text.Region; +import dwtx.jface.text.contentassist.ICompletionProposal; +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; +import dwtx.jface.text.source.IAnnotationModel; +import dwtx.jface.text.source.IAnnotationModelExtension; +import dwtx.jface.text.source.ISourceViewer; +import dwtx.jface.viewers.IPostSelectionProvider; +import dwtx.jface.viewers.ISelection; +import dwtx.jface.viewers.ISelectionChangedListener; +import dwtx.jface.viewers.SelectionChangedEvent; + +/** + * The UI for linked mode. Detects events that influence behavior of the linked mode + * UI and acts upon them. + *

                  + * LinkedModeUI relies on all added + * LinkedModeUITargets to provide implementations of + * ITextViewer that implement ITextViewerExtension, + * and the documents being edited to implement IDocumentExtension3. + *

                  + *

                  + * Clients may instantiate and extend this class. + *

                  + * + * @since 3.0 + */ +public class LinkedModeUI { + + /* cycle constants */ + /** + * Constant indicating that this UI should never cycle from the last + * position to the first and vice versa. + */ + public static Object CYCLE_NEVER_; + public static Object CYCLE_NEVER(){ + if( CYCLE_NEVER_ is null ){ + synchronized( LinkedModeUI.classinfo ){ + if( CYCLE_NEVER_ is null ){ + CYCLE_NEVER_ = new Object(); + } + } + } + return CYCLE_NEVER_; + } + /** + * Constant indicating that this UI should always cycle from the last + * position to the first and vice versa. + */ + public static Object CYCLE_ALWAYS_; + public static Object CYCLE_ALWAYS(){ + if( CYCLE_ALWAYS_ is null ){ + synchronized( LinkedModeUI.classinfo ){ + if( CYCLE_ALWAYS_ is null ){ + CYCLE_ALWAYS_ = new Object(); + } + } + } + return CYCLE_ALWAYS_; + } + /** + * Constant indicating that this UI should cycle from the last position to + * the first and vice versa if its model is not nested. + */ + public static Object CYCLE_WHEN_NO_PARENT_; + public static Object CYCLE_WHEN_NO_PARENT(){ + if( CYCLE_WHEN_NO_PARENT_ is null ){ + synchronized( LinkedModeUI.classinfo ){ + if( CYCLE_WHEN_NO_PARENT_ is null ){ + CYCLE_WHEN_NO_PARENT_ = new Object(); + } + } + } + return CYCLE_WHEN_NO_PARENT_; + } + + /** + * Listener that gets notified when the linked mode UI switches its focus position. + *

                  + * Clients may implement this interface. + *

                  + */ + public interface ILinkedModeUIFocusListener { + /** + * Called when the UI for the linked mode leaves a linked position. + * + * @param position the position being left + * @param target the target where position resides in + */ + void linkingFocusLost(LinkedPosition position, LinkedModeUITarget target); + /** + * Called when the UI for the linked mode gives focus to a linked position. + * + * @param position the position being entered + * @param target the target where position resides in + */ + void linkingFocusGained(LinkedPosition position, LinkedModeUITarget target); + } + + /** + * Null object implementation of focus listener. + */ + private static final class EmtpyFocusListener : ILinkedModeUIFocusListener { + + public void linkingFocusGained(LinkedPosition position, LinkedModeUITarget target) { + // ignore + } + + public void linkingFocusLost(LinkedPosition position, LinkedModeUITarget target) { + // ignore + } + } + + /** + * A link target consists of a viewer and gets notified if the linked mode UI on + * it is being shown. + *

                  + * Clients may extend this class. + *

                  + * @since 3.0 + */ + public static abstract class LinkedModeUITarget : ILinkedModeUIFocusListener { + /** + * Returns the viewer represented by this target, never null. + * + * @return the viewer associated with this target. + */ + public abstract ITextViewer getViewer(); + + /** + * The viewer's text widget is initialized when the UI first connects + * to the viewer and never changed thereafter. This is to keep the + * reference of the widget that we have registered our listeners with, + * as the viewer, when it gets disposed, does not remember it, resulting + * in a situation where we cannot uninstall the listeners and a memory leak. + */ + StyledText fWidget; + + /** The cached shell - same reason as fWidget. */ + Shell fShell; + + /** The registered listener, or null. */ + KeyListener fKeyListener; + + /** The cached custom annotation model. */ + LinkedPositionAnnotations fAnnotationModel; + } + + private static final class EmptyTarget : LinkedModeUITarget { + + private ITextViewer fTextViewer; + + /** + * @param viewer the viewer + */ + public this(ITextViewer viewer) { + Assert.isNotNull(cast(Object)viewer); + fTextViewer= viewer; + } + + /* + * @see dwtx.jdt.internal.ui.text.link2.LinkedModeUI.ILinkedUITarget#getViewer() + */ + public ITextViewer getViewer() { + return fTextViewer; + } + + /** + * {@inheritDoc} + */ + public void linkingFocusLost(LinkedPosition position, LinkedModeUITarget target) { + } + + /** + * {@inheritDoc} + */ + public void linkingFocusGained(LinkedPosition position, LinkedModeUITarget target) { + } + + } + + /** + * Listens for state changes in the model. + */ + private final class ExitListener : ILinkedModeListener { + public void left(LinkedModeModel model, int flags) { + leave(ILinkedModeListener.EXIT_ALL | flags); + } + + public void suspend(LinkedModeModel model) { + disconnect(); + redraw(); + } + + public void resume(LinkedModeModel model, int flags) { + if ((flags & ILinkedModeListener.EXIT_ALL) !is 0) { + leave(flags); + } else { + connect(); + if ((flags & ILinkedModeListener.SELECT) !is 0) + select(); + ensureAnnotationModelInstalled(); + redraw(); + } + } + } + + /** + * Exit flags returned if a custom exit policy wants to exit linked mode. + *

                  + * Clients may instantiate this class. + *

                  + */ + public static class ExitFlags { + /** The flags to return in the leave method. */ + public int flags; + /** The doit flag of the checked VerifyKeyEvent. */ + public bool doit; + /** + * Creates a new instance. + * + * @param flags the exit flags + * @param doit the doit flag for the verify event + */ + public this(int flags, bool doit) { + this.flags= flags; + this.doit= doit; + } + } + + /** + * An exit policy can be registered by a caller to get custom exit + * behavior. + *

                  + * Clients may implement this interface. + *

                  + */ + public interface IExitPolicy { + /** + * Checks whether the linked mode should be left after receiving the + * given VerifyEvent and selection. Note that the event + * carries widget coordinates as opposed to offset and + * length which are document coordinates. + * + * @param model the linked mode model + * @param event the verify event + * @param offset the offset of the current selection + * @param length the length of the current selection + * @return valid exit flags or null if no special action + * should be taken + */ + ExitFlags doExit(LinkedModeModel model, VerifyEvent event, int offset, int length); + } + + /** + * A NullObject implementation of IExitPolicy. + */ + private static class NullExitPolicy : IExitPolicy { + /* + * @see dwtx.jdt.internal.ui.text.link2.LinkedModeUI.IExitPolicy#doExit(dwt.events.VerifyEvent, int, int) + */ + public ExitFlags doExit(LinkedModeModel model, VerifyEvent event, int offset, int length) { + return null; + } + } + + /** + * Listens for shell events and acts upon them. + */ + private class Closer : ShellListener, ITextInputListener { + + public void shellActivated(ShellEvent e) { + } + + public void shellClosed(ShellEvent e) { + leave(ILinkedModeListener.EXIT_ALL); + } + + public void shellDeactivated(ShellEvent e) { +// TODO re-enable after debugging +// if (true) return; + + // from LinkedPositionUI: + + // don't deactivate on focus lost, since the proposal popups may take focus + // plus: it doesn't hurt if you can check with another window without losing linked mode + // since there is no intrusive popup sticking out. + + // need to check first what happens on reentering based on an open action + // Seems to be no problem + + // Better: + // Check with content assistant and only leave if its not the proposal shell that took the + // focus away. + + StyledText text; + ITextViewer viewer; + Display display; + + if (fCurrentTarget is null || (text= fCurrentTarget.fWidget) is null + || text.isDisposed() || (display= text.getDisplay()) is null + || display.isDisposed() + || (viewer= fCurrentTarget.getViewer()) is null) + { + leave(ILinkedModeListener.EXIT_ALL); + } + else + { + // Post in UI thread since the assistant popup will only get the focus after we lose it. + display.asyncExec(dgRunnable( (ITextViewer viewer_) { + if (fIsActive && cast(IEditingSupportRegistry)viewer_ ) { + IEditingSupport[] helpers= (cast(IEditingSupportRegistry) viewer_).getRegisteredSupports(); + for (int i= 0; i < helpers.length; i++) { + if (helpers[i].ownsFocusShell()) + return; + } + } + + // else + leave(ILinkedModeListener.EXIT_ALL); + + }, viewer )); + } + } + + public void shellDeiconified(ShellEvent e) { + } + + public void shellIconified(ShellEvent e) { + leave(ILinkedModeListener.EXIT_ALL); + } + + /* + * @see dwtx.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument) + */ + public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { + leave(ILinkedModeListener.EXIT_ALL); + } + + /* + * @see dwtx.jface.text.ITextInputListener#inputDocumentChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument) + */ + public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { + } + + } + + /** + * @since 3.1 + */ + private class DocumentListener : IDocumentListener { + /* + * @see dwtx.jface.text.IDocumentListener#documentAboutToBeChanged(dwtx.jface.text.DocumentEvent) + */ + public void documentAboutToBeChanged(DocumentEvent event) { + + // default behavior: any document change outside a linked position + // causes us to exit + int end= event.getOffset() + event.getLength(); + for (int offset= event.getOffset(); offset <= end; offset++) { + if (!fModel.anyPositionContains(offset)) { + ITextViewer viewer= fCurrentTarget.getViewer(); + if (fFramePosition !is null && cast(IEditingSupportRegistry)viewer ) { + IEditingSupport[] helpers= (cast(IEditingSupportRegistry) viewer).getRegisteredSupports(); + for (int i= 0; i < helpers.length; i++) { + if (helpers[i].isOriginator(null, new Region(fFramePosition.getOffset(), fFramePosition.getLength()))) + return; + } + } + + leave(ILinkedModeListener.EXTERNAL_MODIFICATION); + return; + } + } + } + + /* + * @see dwtx.jface.text.IDocumentListener#documentChanged(dwtx.jface.text.DocumentEvent) + */ + public void documentChanged(DocumentEvent event) { + } + } + + /** + * Listens for key events, checks the exit policy for custom exit + * strategies but defaults to handling Tab, Enter, and Escape. + */ + private class KeyListener : VerifyKeyListener { + + private bool fIsEnabled= true; + + public void verifyKey(VerifyEvent event) { + + if (!event.doit || !fIsEnabled) + return; + + Point selection= fCurrentTarget.getViewer().getSelectedRange(); + int offset= selection.x; + int length= selection.y; + + // if the custom exit policy returns anything, use that + ExitFlags exitFlags= fExitPolicy.doExit(fModel, event, offset, length); + if (exitFlags !is null) { + leave(exitFlags.flags); + event.doit= exitFlags.doit; + return; + } + + // standard behavior: + // (Shift+)Tab: jumps from position to position, depending on cycle mode + // Enter: accepts all entries and leaves all (possibly stacked) environments, the last sets the caret + // Esc: accepts all entries and leaves all (possibly stacked) environments, the caret stays + // ? what do we do to leave one level of a cycling model that is stacked? + // -> This is only the case if the level was set up with forced cycling cast(CYCLE_ALWAYS), in which case + // the caller is sure that one does not need by-level exiting. + switch (event.character) { + // [SHIFT-]TAB = hop between edit boxes + case 0x09: + if (!(fExitPosition !is null && fExitPosition.includes(offset)) && !fModel.anyPositionContains(offset)) { + // outside any edit box -> leave (all? TODO should only leave the affected, level and forward to the next upper) + leave(ILinkedModeListener.EXIT_ALL); + break; + } + + if (event.stateMask is DWT.SHIFT) + previous(); + else + next(); + + event.doit= false; + break; + + // ENTER + case 0x0A: + // Ctrl+Enter on WinXP + case 0x0D: +// if ((fExitPosition !is null && fExitPosition.includes(offset)) || !fModel.anyPositionContains(offset)) { + if (!fModel.anyPositionContains(offset)) { +// if ((fExitPosition is null || !fExitPosition.includes(offset)) && !fModel.anyPositionContains(offset)) { + // outside any edit box or on exit position -> leave (all? TODO should only leave the affected, level and forward to the next upper) + leave(ILinkedModeListener.EXIT_ALL); + break; + } + + // normal case: exit entire stack and put caret to final position + leave(ILinkedModeListener.EXIT_ALL | ILinkedModeListener.UPDATE_CARET); + event.doit= false; + break; + + // ESC + case 0x1B: + // exit entire stack and leave caret + leave(ILinkedModeListener.EXIT_ALL); + event.doit= false; + break; + + default: + if (event.character !is 0) { + if (!controlUndoBehavior(offset, length)) { + leave(ILinkedModeListener.EXIT_ALL); + break; + } + } + } + } + + private bool controlUndoBehavior(int offset, int length) { + LinkedPosition position= fModel.findPosition(new LinkedPosition(fCurrentTarget.getViewer().getDocument(), offset, length, LinkedPositionGroup.NO_STOP)); + if (position !is null) { + + // if the last position is not the same and there is an open change: close it. + if (!position.equals(fPreviousPosition)) + endCompoundChange(); + + beginCompoundChange(); + } + + fPreviousPosition= position; + return fPreviousPosition !is null; + } + + /** + * @param enabled the new enabled state + */ + public void setEnabled(bool enabled) { + fIsEnabled= enabled; + } + + } + + /** + * Installed as post selection listener on the watched viewer. Updates the + * linked position after cursor movement, even to positions not in the + * iteration list. + */ + private class MySelectionListener : ISelectionChangedListener { + + /* + * @see dwtx.jface.viewers.ISelectionChangedListener#selectionChanged(dwtx.jface.viewers.SelectionChangedEvent) + */ + public void selectionChanged(SelectionChangedEvent event) { + ISelection selection= event.getSelection(); + if ( cast(ITextSelection)selection ) { + ITextSelection textsel= cast(ITextSelection) selection; + if ( cast(ITextViewer)event.getSelectionProvider() ) { + IDocument doc= (cast(ITextViewer) event.getSelectionProvider()).getDocument(); + if (doc !is null) { + int offset= textsel.getOffset(); + int length= textsel.getLength(); + if (offset >= 0 && length >= 0) { + LinkedPosition find= new LinkedPosition(doc, offset, length, LinkedPositionGroup.NO_STOP); + LinkedPosition pos= fModel.findPosition(find); + if (pos is null && fExitPosition !is null && fExitPosition.includes(find)) + pos= fExitPosition; + + if (pos !is null) + switchPosition(pos, false, false); + } + } + } + } + } + + } + + private class ProposalListener : IProposalListener { + + /* + * @see dwtx.jface.internal.text.link.contentassist.IProposalListener#proposalChosen(dwtx.jface.text.contentassist.ICompletionProposal) + */ + public void proposalChosen(ICompletionProposal proposal) { + next(); + } + } + + /** The current viewer. */ + private LinkedModeUITarget fCurrentTarget; + /** + * The manager of the linked positions we provide a UI for. + * @since 3.1 + */ + private LinkedModeModel fModel; + /** The set of viewers we manage. */ + private LinkedModeUITarget[] fTargets; + /** The iterator over the tab stop positions. */ + private TabStopIterator fIterator; + + /* Our team of event listeners */ + /** The shell listener. */ + private Closer fCloser; + /** The linked mode listener. */ + private ILinkedModeListener fLinkedListener; + /** The selection listener. */ + private MySelectionListener fSelectionListener; + /** The content assist listener. */ + private ProposalListener fProposalListener; + /** + * The document listener. + * @since 3.1 + */ + private IDocumentListener fDocumentListener; + + /** The last caret position, used by fCaretListener. */ + private const Position fCaretPosition; + /** The exit policy to control custom exit behavior */ + private IExitPolicy fExitPolicy; + /** The current frame position shown in the UI, or null. */ + private LinkedPosition fFramePosition; + /** The last visited position, used for undo / redo. */ + private LinkedPosition fPreviousPosition; + /** The content assistant used to show proposals. */ + private ContentAssistant2 fAssistant; + /** The exit position. */ + private LinkedPosition fExitPosition; + /** State indicator to prevent multiple invocation of leave. */ + private bool fIsActive= false; + /** The position updater for the exit position. */ + private IPositionUpdater fPositionUpdater; + /** Whether to show context info. */ + private bool fDoContextInfo= false; + /** Whether we have begun a compound change, but not yet closed. */ + private bool fHasOpenCompoundChange= false; + /** The position listener. */ + private ILinkedModeUIFocusListener fPositionListener; + private IAutoEditStrategy fAutoEditVetoer; + private void fAutoEditVetoer_init(){ + fAutoEditVetoer = new class() IAutoEditStrategy { + /* + * @see dwtx.jface.text.IAutoEditStrategy#customizeDocumentCommand(dwtx.jface.text.IDocument, dwtx.jface.text.DocumentCommand) + */ + public void customizeDocumentCommand(IDocument document, DocumentCommand command) { + // invalidate the change to ensure that the change is performed on the document only. + if (fModel.anyPositionContains(command.offset)) { + command.doit= false; + command.caretOffset= command.offset + command.length; + } + + } + }; + } + + /** Whether this UI is in simple highlighting mode or not. */ + private bool fSimple; + + /** + * Tells whether colored labels support is enabled. + * @since 3.4 + */ + private bool fIsColoredLabelsSupportEnabled= false; + + private this(){ + fCloser= new Closer(); + fLinkedListener= new ExitListener(); + fSelectionListener= new MySelectionListener(); + fProposalListener= new ProposalListener(); + fDocumentListener= new DocumentListener(); + fCaretPosition= new Position(0, 0); + fExitPolicy= new NullExitPolicy(); + fPositionUpdater= new DefaultPositionUpdater(getCategory()); + fPositionListener= new EmtpyFocusListener(); + fAutoEditVetoer_init(); + } + + /** + * Creates a new UI on the given model and the set of viewers. The model + * must provide a tab stop sequence with a non-empty list of tab stops. + * + * @param model the linked mode model + * @param targets the non-empty list of targets upon which the linked mode + * UI should act + */ + public this(LinkedModeModel model, LinkedModeUITarget[] targets) { + this(); + constructor(model, targets); + } + + /** + * Convenience constructor for just one viewer. + * + * @param model the linked mode model + * @param viewer the viewer upon which the linked mode UI should act + */ + public this(LinkedModeModel model, ITextViewer viewer) { + this(); + constructor(model, [new EmptyTarget(viewer)]); + } + + /** + * Convenience constructor for multiple viewers. + * + * @param model the linked mode model + * @param viewers the non-empty list of viewers upon which the linked mode + * UI should act + */ + public this(LinkedModeModel model, ITextViewer[] viewers) { + this(); + LinkedModeUITarget[] array= new LinkedModeUITarget[viewers.length]; + for (int i= 0; i < array.length; i++) { + array[i]= new EmptyTarget(viewers[i]); + } + constructor(model, array); + } + + /** + * Convenience constructor for one target. + * + * @param model the linked mode model + * @param target the target upon which the linked mode UI should act + */ + public this(LinkedModeModel model, LinkedModeUITarget target) { + this(); + constructor(model, [target]); + } + + /** + * This does the actual constructor work. + * + * @param model the linked mode model + * @param targets the non-empty array of targets upon which the linked mode UI + * should act + */ + private void constructor(LinkedModeModel model, LinkedModeUITarget[] targets) { + Assert.isNotNull(model); + //Assert.isNotNull(targets); + Assert.isTrue(targets.length > 0); + Assert.isTrue(model.getTabStopSequence().size() > 0); + + fModel= model; + fTargets= targets; + fCurrentTarget= targets[0]; + fIterator= new TabStopIterator(fModel.getTabStopSequence()); + fIterator.setCycling(!fModel.isNested()); + fModel.addLinkingListener(fLinkedListener); + + fAssistant= new ContentAssistant2(); + fAssistant.addProposalListener(fProposalListener); + // TODO find a way to set up content assistant. +// fAssistant.setDocumentPartitioning(IJavaPartitions.JAVA_PARTITIONING); + fAssistant.enableColoredLabels(fIsColoredLabelsSupportEnabled); + fCaretPosition.delete_(); + } + + /** + * Starts this UI on the first position. + */ + public void enter() { + fIsActive= true; + connect(); + next(); + } + + /** + * Sets an IExitPolicy to customize the exit behavior of + * this linked mode UI. + * + * @param policy the exit policy to use. + */ + public void setExitPolicy(IExitPolicy policy) { + fExitPolicy= policy; + } + + /** + * Sets the exit position to move the caret to when linked mode mode is + * exited. + * + * @param target the target where the exit position is located + * @param offset the offset of the exit position + * @param length the length of the exit position (in case there should be a + * selection) + * @param sequence set to the tab stop position of the exit position, or + * LinkedPositionGroup.NO_STOP if there should be no + * tab stop. + * @throws BadLocationException if the position is not valid in the viewer's + * document + */ + public void setExitPosition(LinkedModeUITarget target, int offset, int length, int sequence) { + // remove any existing exit position + if (fExitPosition !is null) { + fExitPosition.getDocument().removePosition(fExitPosition); + fIterator.removePosition(fExitPosition); + fExitPosition= null; + } + + IDocument doc= target.getViewer().getDocument(); + if (doc is null) + return; + + fExitPosition= new LinkedPosition(doc, offset, length, sequence); + doc.addPosition(fExitPosition); // gets removed in leave() + if (sequence !is LinkedPositionGroup.NO_STOP) + fIterator.addPosition(fExitPosition); + + } + + /** + * Sets the exit position to move the caret to when linked mode is exited. + * + * @param viewer the viewer where the exit position is located + * @param offset the offset of the exit position + * @param length the length of the exit position (in case there should be a + * selection) + * @param sequence set to the tab stop position of the exit position, or + * LinkedPositionGroup.NO_STOP if there should be no tab stop. + * @throws BadLocationException if the position is not valid in the + * viewer's document + */ + public void setExitPosition(ITextViewer viewer, int offset, int length, int sequence) { + setExitPosition(new EmptyTarget(viewer), offset, length, sequence); + } + + /** + * Sets the cycling mode to either of CYCLING_ALWAYS, + * CYCLING_NEVER, or CYCLING_WHEN_NO_PARENT, + * which is the default. + * + * @param mode the new cycling mode. + */ + public void setCyclingMode(Object mode) { + if (mode !is CYCLE_ALWAYS && mode !is CYCLE_NEVER && mode !is CYCLE_WHEN_NO_PARENT) + throw new IllegalArgumentException(null); + + if (mode is CYCLE_ALWAYS || mode is CYCLE_WHEN_NO_PARENT && !fModel.isNested()) + fIterator.setCycling(true); + else + fIterator.setCycling(false); + } + + void next() { + if (fIterator.hasNext(fFramePosition)) { + switchPosition(fIterator.next(fFramePosition), true, true); + return; + } + leave(ILinkedModeListener.UPDATE_CARET); + } + + void previous() { + if (fIterator.hasPrevious(fFramePosition)) { + switchPosition(fIterator.previous(fFramePosition), true, true); + } else + // dont't update caret, but rather select the current frame + leave(ILinkedModeListener.SELECT); + } + + private void triggerContextInfo() { + ITextOperationTarget target= fCurrentTarget.getViewer().getTextOperationTarget(); + if (target !is null) { + if (target.canDoOperation(ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION)) + target.doOperation(ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION); + } + } + + /** Trigger content assist on choice positions */ + private void triggerContentAssist() { + if ( cast(ProposalPosition)fFramePosition ) { + ProposalPosition pp= cast(ProposalPosition) fFramePosition; + ICompletionProposal[] choices= pp.getChoices(); + if (choices !is null && choices.length > 0) { + fAssistant.setCompletions(choices); + fAssistant.showPossibleCompletions(); + return; + } + } + + fAssistant.setCompletions(new ICompletionProposal[0]); + fAssistant.hidePossibleCompletions(); + } + + private void switchPosition(LinkedPosition pos, bool select_, bool showProposals) { + Assert.isNotNull(pos); + if (pos.equals(fFramePosition)) + return; + + if (fFramePosition !is null && fCurrentTarget !is null) + fPositionListener.linkingFocusLost(fFramePosition, fCurrentTarget); + + // undo + endCompoundChange(); + + redraw(); // redraw current position being left - usually not needed + IDocument oldDoc= fFramePosition is null ? null : fFramePosition.getDocument(); + IDocument newDoc= pos.getDocument(); + + switchViewer(oldDoc, newDoc, pos); + fFramePosition= pos; + + if (select_) + select(); + if (fFramePosition is fExitPosition && !fIterator.isCycling()) + leave(ILinkedModeListener.NONE); + else { + redraw(); // redraw new position + ensureAnnotationModelInstalled(); + } + if (showProposals) + triggerContentAssist(); + if (fFramePosition !is fExitPosition && fDoContextInfo) + triggerContextInfo(); + + if (fFramePosition !is null && fCurrentTarget !is null) + fPositionListener.linkingFocusGained(fFramePosition, fCurrentTarget); + + } + + private void ensureAnnotationModelInstalled() { + LinkedPositionAnnotations lpa= fCurrentTarget.fAnnotationModel; + if (lpa !is null) { + ITextViewer viewer= fCurrentTarget.getViewer(); + if ( cast(ISourceViewer)viewer ) { + ISourceViewer sv= cast(ISourceViewer) viewer; + IAnnotationModel model= sv.getAnnotationModel(); + if ( cast(IAnnotationModelExtension)model ) { + IAnnotationModelExtension ext= cast(IAnnotationModelExtension) model; + IAnnotationModel ourModel= ext.getAnnotationModel(stringcast(getUniqueKey())); + if (ourModel is null) { + ext.addAnnotationModel(stringcast(getUniqueKey()), lpa); + } + } + } + } + } + + private void uninstallAnnotationModel(LinkedModeUITarget target) { + ITextViewer viewer= target.getViewer(); + if ( cast(ISourceViewer)viewer ) { + ISourceViewer sv= cast(ISourceViewer) viewer; + IAnnotationModel model= sv.getAnnotationModel(); + if ( cast(IAnnotationModelExtension)model ) { + IAnnotationModelExtension ext= cast(IAnnotationModelExtension) model; + ext.removeAnnotationModel(stringcast(getUniqueKey())); + } + } + } + + private void switchViewer(IDocument oldDoc, IDocument newDoc, LinkedPosition pos) { + if (oldDoc !is newDoc) { + + // redraw current document with new position before switching viewer + if (fCurrentTarget.fAnnotationModel !is null) + fCurrentTarget.fAnnotationModel.switchToPosition(fModel, pos); + + LinkedModeUITarget target= null; + for (int i= 0; i < fTargets.length; i++) { + if (fTargets[i].getViewer().getDocument() is newDoc) { + target= fTargets[i]; + break; + } + } + if (target !is fCurrentTarget) { + disconnect(); + fCurrentTarget= target; + target.linkingFocusLost(fFramePosition, target); + connect(); + ensureAnnotationModelInstalled(); + if (fCurrentTarget !is null) + fCurrentTarget.linkingFocusGained(pos, fCurrentTarget); + } + } + } + + private void select() { + ITextViewer viewer= fCurrentTarget.getViewer(); + if ( cast(ITextViewerExtension5)viewer ) { + ITextViewerExtension5 extension5= cast(ITextViewerExtension5) viewer; + extension5.exposeModelRange(new Region(fFramePosition.offset, fFramePosition.length)); + } else if (!viewer.overlapsWithVisibleRegion(fFramePosition.offset, fFramePosition.length)) { + viewer.resetVisibleRegion(); + } + viewer.revealRange(fFramePosition.offset, fFramePosition.length); + viewer.setSelectedRange(fFramePosition.offset, fFramePosition.length); + } + + private void redraw() { + if (fCurrentTarget.fAnnotationModel !is null) + fCurrentTarget.fAnnotationModel.switchToPosition(fModel, fFramePosition); + } + + private void connect() { + Assert.isNotNull(fCurrentTarget); + ITextViewer viewer= fCurrentTarget.getViewer(); + Assert.isNotNull(cast(Object)viewer); + fCurrentTarget.fWidget= viewer.getTextWidget(); + if (fCurrentTarget.fWidget is null) + leave(ILinkedModeListener.EXIT_ALL); + + if (fCurrentTarget.fKeyListener is null) { + fCurrentTarget.fKeyListener= new KeyListener(); + (cast(ITextViewerExtension) viewer).prependVerifyKeyListener(fCurrentTarget.fKeyListener); + } else + fCurrentTarget.fKeyListener.setEnabled(true); + + registerAutoEditVetoer(viewer); + + (cast(IPostSelectionProvider) viewer).addPostSelectionChangedListener(fSelectionListener); + + createAnnotationModel(); + + showSelection(); + + fCurrentTarget.fShell= fCurrentTarget.fWidget.getShell(); + if (fCurrentTarget.fShell is null) + leave(ILinkedModeListener.EXIT_ALL); + fCurrentTarget.fShell.addShellListener(fCloser); + + fAssistant.install(viewer); + + viewer.addTextInputListener(fCloser); + + viewer.getDocument().addDocumentListener(fDocumentListener); + } + + /** + * Reveals the selection on the current target's widget, if it is valid. + */ + private void showSelection() { + final StyledText widget= fCurrentTarget.fWidget; + if (widget is null || widget.isDisposed()) + return; + + // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=132263 + widget.getDisplay().asyncExec(new class() Runnable { + public void run() { + if (!widget.isDisposed()) + try { + widget.showSelection(); + } catch (IllegalArgumentException e) { + /* + * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=66914 + * if the StyledText is in setRedraw(false) mode, its + * selection may not be up2date and calling showSelection + * will throw an IAE. + * We don't have means to find out whether the selection is valid + * or whether the widget is redrawing or not therefore we try + * and ignore an IAE. + */ + } + } + }); + } + + /** + * Registers our auto edit vetoer with the viewer. + * + * @param viewer the viewer we want to veto ui-triggered changes within + * linked positions + */ + private void registerAutoEditVetoer(ITextViewer viewer) { + try { + String[] contentTypes= getContentTypes(viewer.getDocument()); + if ( cast(ITextViewerExtension2)viewer ) { + ITextViewerExtension2 vExtension= (cast(ITextViewerExtension2) viewer); + for (int i= 0; i < contentTypes.length; i++) { + vExtension.prependAutoEditStrategy(fAutoEditVetoer, contentTypes[i]); + } + } else { + Assert.isTrue(false); + } + + } catch (BadPartitioningException e) { + leave(ILinkedModeListener.EXIT_ALL); + } + } + + private void unregisterAutoEditVetoer(ITextViewer viewer) { + try { + String[] contentTypes= getContentTypes(viewer.getDocument()); + if ( cast(ITextViewerExtension2)viewer ) { + ITextViewerExtension2 vExtension= (cast(ITextViewerExtension2) viewer); + for (int i= 0; i < contentTypes.length; i++) { + vExtension.removeAutoEditStrategy(fAutoEditVetoer, contentTypes[i]); + } + } else { + Assert.isTrue(false); + } + } catch (BadPartitioningException e) { + leave(ILinkedModeListener.EXIT_ALL); + } + } + + /** + * Returns all possible content types of document. + * + * @param document the document + * @return all possible content types of document + * @throws BadPartitioningException + * @since 3.1 + */ + private String[] getContentTypes(IDocument document) { + if ( cast(IDocumentExtension3)document ) { + IDocumentExtension3 ext= cast(IDocumentExtension3) document; + String[] partitionings= ext.getPartitionings(); + Set contentTypes= new HashSet(20); + for (int i= 0; i < partitionings.length; i++) { + contentTypes.addAll(Arrays.asList(stringcast(ext.getLegalContentTypes(partitionings[i])))); + } + contentTypes.add(IDocument.DEFAULT_CONTENT_TYPE); + return stringcast( contentTypes.toArray()); + } + return document.getLegalContentTypes(); + } + + private void createAnnotationModel() { + if (fCurrentTarget.fAnnotationModel is null) { + LinkedPositionAnnotations lpa= new LinkedPositionAnnotations(); + if (fSimple) { + lpa.markExitTarget(true); + lpa.markFocus(false); + lpa.markSlaves(false); + lpa.markTargets(false); + } + lpa.setTargets(fIterator.getPositions()); + lpa.setExitTarget(fExitPosition); + lpa.connect(fCurrentTarget.getViewer().getDocument()); + fCurrentTarget.fAnnotationModel= lpa; + } + } + + private String getUniqueKey() { + return "linked.annotationmodelkey."~toString(); //$NON-NLS-1$ + } + + private void disconnect() { + Assert.isNotNull(fCurrentTarget); + ITextViewer viewer= fCurrentTarget.getViewer(); + Assert.isNotNull(cast(Object)viewer); + + viewer.getDocument().removeDocumentListener(fDocumentListener); + + fAssistant.uninstall(); + fAssistant.removeProposalListener(fProposalListener); + + fCurrentTarget.fWidget= null; + + Shell shell= fCurrentTarget.fShell; + fCurrentTarget.fShell= null; + + if (shell !is null && !shell.isDisposed()) + shell.removeShellListener(fCloser); + + // this one is asymmetric: we don't install the model in + // connect, but leave it to its callers to ensure they + // have the model installed if they need it + uninstallAnnotationModel(fCurrentTarget); + + unregisterAutoEditVetoer(viewer); + + // don't remove the verify key listener to let it keep its position + // in the listener queue + if (fCurrentTarget.fKeyListener !is null) + fCurrentTarget.fKeyListener.setEnabled(false); + + (cast(IPostSelectionProvider) viewer).removePostSelectionChangedListener(fSelectionListener); + + redraw(); + } + + void leave(int flags) { + if (!fIsActive) + return; + fIsActive= false; + + endCompoundChange(); + + Display display= null; + if (fCurrentTarget.fWidget !is null && !fCurrentTarget.fWidget.isDisposed()) + display= fCurrentTarget.fWidget.getDisplay(); + + if (fCurrentTarget.fAnnotationModel !is null) + fCurrentTarget.fAnnotationModel.removeAllAnnotations(); + disconnect(); + + for (int i= 0; i < fTargets.length; i++) { + LinkedModeUITarget target= fTargets[i]; + ITextViewer viewer= target.getViewer(); + if (target.fKeyListener !is null) { + (cast(ITextViewerExtension) viewer).removeVerifyKeyListener(target.fKeyListener); + target.fKeyListener= null; + } + + viewer.removeTextInputListener(fCloser); + } + + for (int i= 0; i < fTargets.length; i++) { + + if (fTargets[i].fAnnotationModel !is null) { + fTargets[i].fAnnotationModel.removeAllAnnotations(); + fTargets[i].fAnnotationModel.disconnect(fTargets[i].getViewer().getDocument()); + fTargets[i].fAnnotationModel= null; + } + + uninstallAnnotationModel(fTargets[i]); + } + + + if ((flags & ILinkedModeListener.UPDATE_CARET) !is 0 && fExitPosition !is null && fFramePosition !is fExitPosition && !fExitPosition.isDeleted()) + switchPosition(fExitPosition, true, false); + + final List docs= new ArrayList(); + for (int i= 0; i < fTargets.length; i++) { + IDocument doc= fTargets[i].getViewer().getDocument(); + if (doc !is null) + docs.add(cast(Object)doc); + } + + fModel.stopForwarding(flags); + + Runnable runnable= dgRunnable( (int flags_){ + if (fExitPosition !is null) + fExitPosition.getDocument().removePosition(fExitPosition); + + for (Iterator iter = docs.iterator(); iter.hasNext(); ) { + IDocument doc= cast(IDocument) iter.next(); + doc.removePositionUpdater(fPositionUpdater); + bool uninstallCat= false; + String[] cats= doc.getPositionCategories(); + for (int j= 0; j < cats.length; j++) { + if (getCategory().equals(cats[j])) { + uninstallCat= true; + break; + } + } + if (uninstallCat) + try { + doc.removePositionCategory(getCategory()); + } catch (BadPositionCategoryException e) { + // ignore + } + } + fModel.exit(flags_); + }, flags ); + + // remove positions (both exit positions AND linked positions in the + // model) asynchronously to make sure that the annotation painter + // gets correct document offsets. + if (display !is null) + display.asyncExec(runnable); + else + runnable.run(); + } + + private void endCompoundChange() { + if (fHasOpenCompoundChange) { + ITextViewerExtension extension= cast(ITextViewerExtension) fCurrentTarget.getViewer(); + IRewriteTarget target= extension.getRewriteTarget(); + target.endCompoundChange(); + fHasOpenCompoundChange= false; + } + } + + private void beginCompoundChange() { + if (!fHasOpenCompoundChange) { + ITextViewerExtension extension= cast(ITextViewerExtension) fCurrentTarget.getViewer(); + IRewriteTarget target= extension.getRewriteTarget(); + target.beginCompoundChange(); + fHasOpenCompoundChange= true; + } + } + + /** + * Returns the currently selected region or null. + * + * @return the currently selected region or null + */ + public IRegion getSelectedRegion() { + if (fFramePosition !is null) + return new Region(fFramePosition.getOffset(), fFramePosition.getLength()); + if (fExitPosition !is null) + return new Region(fExitPosition.getOffset(), fExitPosition.getLength()); + return null; + } + + private String getCategory() { + return toString(); + } + + /** + * Sets the context info property. If set to true, context + * info will be invoked on the current target's viewer whenever a position + * is switched. + * + * @param doContextInfo true if context information should be + * displayed + */ + public void setDoContextInfo(bool doContextInfo) { + fDoContextInfo= doContextInfo; + } + + /** + * Sets the focus callback which will get informed when the focus of the + * linked mode UI changes. + *

                  + * If there is a listener installed already, it will be replaced. + *

                  + * + * @param listener the new listener, never null. + */ + protected void setPositionListener(ILinkedModeUIFocusListener listener) { + Assert.isNotNull(cast(Object)listener); + fPositionListener= listener; + } + + /** + * Sets the "simple" mode of the receiver. A linked mode UI in simple mode + * merely draws the exit position, but not the target, focus, and slave + * positions. Default is false. This method must be called + * before it is entered. + * + * @param simple true if the UI should be in simple mode. + */ + public void setSimpleMode(bool simple) { + fSimple= simple; + } + + /** + * Enables the support for colored labels in the proposal popup. + *

                  Completion proposals can implement {@link ICompletionProposalExtension6} + * to provide colored proposal labels.

                  + * + * @param isEnabled if true the support for colored labels is enabled in the proposal popup + * @since 3.4 + */ + public void enableColoredLabels(bool isEnabled) { + fIsColoredLabelsSupportEnabled= isEnabled; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/link/LinkedPosition.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/link/LinkedPosition.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,194 @@ +/******************************************************************************* + * 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 + * 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.text.link.LinkedPosition; + +import dwtx.jface.text.link.LinkedModeModel; // packageimport +import dwtx.jface.text.link.ILinkedModeListener; // packageimport +import dwtx.jface.text.link.TabStopIterator; // packageimport +import dwtx.jface.text.link.LinkedModeUI; // packageimport +import dwtx.jface.text.link.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.link.LinkedPositionGroup; // packageimport +import dwtx.jface.text.link.LinkedModeManager; // packageimport +import dwtx.jface.text.link.LinkedPositionAnnotations; // packageimport +import dwtx.jface.text.link.ProposalPosition; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.Position; + +/** + * A Position on a document that knows which document it is + * registered with and has a sequence number for tab stops. + *

                  + * Clients may extend this class. + *

                  + * @since 3.0 + */ +public class LinkedPosition : Position { + alias Position.overlapsWith overlapsWith; + /** The document this position belongs to. */ + private IDocument fDocument; + private int fSequenceNumber; + + /** + * Creates a new instance. + * + * @param document the document + * @param offset the offset of the position + * @param length the length of the position + * @param sequence the iteration sequence rank + */ + public this(IDocument document, int offset, int length, int sequence) { + super(offset, length); + Assert.isNotNull(cast(Object)document); + fDocument= document; + fSequenceNumber= sequence; + } + + /** + * Creates a new instance. Equivalent to calling + * LinkedPosition(document, offset, length, LinkedPositionGroup.NO_STOP) + * + * @param document the document + * @param offset the offset of the position + * @param length the length of the position + */ + public this(IDocument document, int offset, int length) { + this(document, offset, length, LinkedPositionGroup.NO_STOP); + } + + /** + * @return Returns the document. + */ + public IDocument getDocument() { + return fDocument; + } + + /* + * @see dwtx.jface.text.Position#equals(java.lang.Object) + */ + public bool equals(Object other) { + if ( cast(LinkedPosition)other ) { + LinkedPosition p= cast(LinkedPosition) other; + return p.offset is offset && p.length is length && p.fDocument is fDocument; + } + return false; + } + + /** + * Returns whether this position overlaps with position. + * + * @param position the position to check. + * @return true if this position overlaps with + * position,false otherwise + */ + public bool overlapsWith(LinkedPosition position) { + return position.getDocument() is fDocument && overlapsWith(position.getOffset(), position.getLength()); + } + + /** + * Returns whether this position includes event. + * + * @param event the event to check. + * @return true if this position includes event, + * false otherwise + */ + public bool includes(DocumentEvent event) { + return includes(event.getDocument(), event.getOffset(), event.getLength()); + } + + /** + * Returns whether this position includes position. + * + * @param position the position to check. + * @return true if this position includes + * position,false otherwise + */ + public bool includes(LinkedPosition position) { + return includes(position.getDocument(), position.getOffset(), position.getLength()); + } + + /** + * Overrides {@link Position#includes(int)}so every offset is considered + * included that lies in between the first and last offset of this position, + * and offsets that are right at the end of the position. + * + * @param pOffset the offset to check + * @return true if pOffset is in + * [offset, offset + length] + */ + public bool includes(int pOffset) { + return this.offset <= pOffset && pOffset <= this.offset + this.length; + } + + /** + * Returns whether this position includes the range given by + * offset and length. A range is included by + * a LinkedPosition if {@link #includes(int) includes(offset)} + * returns true for every offset in the range, including the borders of the + * range. + * + * @param doc the document that the given range refers to, may be null + * @param off the offset of the range, referring to document + * @param len the length of the range + * @return true if doc is the same document as + * this position refers to, and if the entire range is included in + * this position + */ + protected bool includes(IDocument doc, int off, int len) { + return doc is fDocument && off >= offset && len + off <= offset + length; + + } + + /** + * Returns the content of this position on the referenced document. + * + * @return the content of the document at this position + * @throws BadLocationException if the position is not valid + */ + public String getContent() { + return fDocument.get(offset, length); + } + + /** + * Returns the sequence number of this position. + * + * @return the sequence number of this position + */ + public int getSequenceNumber() { + return fSequenceNumber; + } + + /** + * Sets the sequence number of this position. + * + * @param sequence the new sequence number + */ + public void setSequenceNumber(int sequence) { + fSequenceNumber= sequence; + } + + /* + * @see dwtx.jface.text.Position#hashCode() + */ + public override hash_t toHash() { + alias .toHash toHash; + return (cast(Object)fDocument).toHash() | super.toHash() | fSequenceNumber; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/link/LinkedPositionAnnotations.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/link/LinkedPositionAnnotations.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,331 @@ +/******************************************************************************* + * 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 + * 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.text.link.LinkedPositionAnnotations; + +import dwtx.jface.text.link.LinkedModeModel; // packageimport +import dwtx.jface.text.link.LinkedPosition; // packageimport +import dwtx.jface.text.link.ILinkedModeListener; // packageimport +import dwtx.jface.text.link.TabStopIterator; // packageimport +import dwtx.jface.text.link.LinkedModeUI; // packageimport +import dwtx.jface.text.link.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.link.LinkedPositionGroup; // packageimport +import dwtx.jface.text.link.LinkedModeManager; // packageimport +import dwtx.jface.text.link.ProposalPosition; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + + + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.Position; +import dwtx.jface.text.source.Annotation; +import dwtx.jface.text.source.AnnotationModel; + +/** + * Internal class. + * + * @since 3.0 + */ +final class LinkedPositionAnnotations : AnnotationModel { + + /* annotation types */ + private static const String TARGET_ANNOTATION_TYPE= "dwtx.ui.internal.workbench.texteditor.link.target"; //$NON-NLS-1$ + private static const String SLAVE_ANNOTATION_TYPE= "dwtx.ui.internal.workbench.texteditor.link.slave"; //$NON-NLS-1$ + private static const String FOCUS_ANNOTATION_TYPE= "dwtx.ui.internal.workbench.texteditor.link.master"; //$NON-NLS-1$ + private static const String EXIT_ANNOTATION_TYPE= "dwtx.ui.internal.workbench.texteditor.link.exit"; //$NON-NLS-1$ + + /* configuration */ + private bool fMarkTargets= true; + private bool fMarkSlaves= true; + private bool fMarkFocus= true; + private bool fMarkExitTarget= true; + + private Annotation fFocusAnnotation= null; + private Annotation fExitAnnotation= null; + private const Map fGroupAnnotations; + private const Map fTargetAnnotations; + private Position[] fTargets; + private LinkedPosition fExitPosition= null; + + public this(){ + fGroupAnnotations= new HashMap(); + fTargetAnnotations= new HashMap(); + } + + /** + * Sets the position that should be highlighted as the focus position, i.e. + * as the position whose changes are propagated to all its linked positions + * by the linked environment. + * + * @param position the new focus position, or null if no focus is set. + * @throws BadLocationException if position is invalid + */ + private void setFocusPosition(Position position) { + if (fMarkFocus && getPosition(fFocusAnnotation) !is position) { + removeAnnotation(fFocusAnnotation, false); + if (position !is null) { + fFocusAnnotation= new Annotation(FOCUS_ANNOTATION_TYPE, false, ""); //$NON-NLS-1$ + addAnnotation(fFocusAnnotation, position, false); + } else + fFocusAnnotation= null; + } + } + + /** + * Sets the position that should be highlighted as the exit position, i.e. + * as the position whose changes are propagated to all its linked positions + * by the linked environment. + * + * @param position the new exit position, or null if no focus is set. + * @throws BadLocationException in case position is invalid + */ + private void setExitPosition(Position position) { + if (fMarkExitTarget && getPosition(fExitAnnotation) !is position) { + removeAnnotation(fExitAnnotation, false); + if (position !is null) { + fExitAnnotation= new Annotation(EXIT_ANNOTATION_TYPE, false, ""); //$NON-NLS-1$ + addAnnotation(fExitAnnotation, position, false); + } else + fExitAnnotation= null; + } + } + + /** + * Sets the positions that should be highlighted as the slave positions, i.e. + * as the positions that are linked to the focus position. + * + * @param positions the new slave positions, or null if no slave positions are to be set + * @throws BadLocationException in case any of the given positions is invalid + */ + private void setGroupPositions(List positions) { + if (!fMarkSlaves) + return; + + // remove all positions which are already there + // Algorithm: toRemove contains all mappings at first, but all that are in + // positions get removed -> toRemove contains the difference set of previous - new + // toAdd are the new positions, which don't exist in previous = new - previous + List toRemove= new ArrayList(fGroupAnnotations.values()); + Map toAdd= new HashMap(); + if (positions !is null) { + for (Iterator iter= positions.iterator(); iter.hasNext();) { + Position p= cast(Position) iter.next(); + if (fGroupAnnotations.containsKey(p)) { + toRemove.remove(fGroupAnnotations.get(p)); + } else { + Annotation a= new Annotation(SLAVE_ANNOTATION_TYPE, false, ""); //$NON-NLS-1$ + toAdd.put(a, p); + fGroupAnnotations.put(p, a); + } + } + } + fGroupAnnotations.values().removeAll(toRemove); + + replaceAnnotations(arraycast!(Annotation)( toRemove.toArray()), toAdd, false); + } + + /** + * Sets the positions that should be highlighted as the target positions, i.e. + * as the positions that can be jumped to in a linked set up. + * + * @param positions the new target positions, or null if no target positions are to be set + * @throws BadLocationException in case any of the given positions is invalid + */ + private void setTargetPositions(List positions) { + if (!fMarkTargets) + return; + + // remove all positions which are already there + // Algorithm: toRemove contains all mappings at first, but all that are in + // positions get removed -> toRemove contains the difference set of previous - new + // toAdd are the new positions, which don't exist in previous = new - previous + List toRemove= new ArrayList(fTargetAnnotations.values()); + Map toAdd= new HashMap(); + if (positions !is null) { + for (Iterator iter= positions.iterator(); iter.hasNext();) { + Position p= cast(Position) iter.next(); + if (fTargetAnnotations.containsKey(p)) { + toRemove.remove(fTargetAnnotations.get(p)); + } else { + Annotation a= new Annotation(TARGET_ANNOTATION_TYPE, false, ""); //$NON-NLS-1$ + toAdd.put(a, p); + fTargetAnnotations.put(p, a); + } + } + } + fTargetAnnotations.values().removeAll(toRemove); + + replaceAnnotations(arraycast!(Annotation)( toRemove.toArray()), toAdd, false); + } + + /** + * Switches the focus position to position given the + * LinkedModeModel env. The slave positions for position + * is extracted from the environment and set accordingly, the target positions + * are updated as well. + * + * @param env + * @param position + */ + public void switchToPosition(LinkedModeModel env, LinkedPosition position) { + if (fDocument is null || + (position !is null && getPosition(fFocusAnnotation) is position) || + (position is null && fFocusAnnotation is null)) + return; + + LinkedPositionGroup linkedGroup= null; + if (position !is null) + linkedGroup= env.getGroupForPosition(position); + + List targets= new ArrayList(); + targets.addAll(Arrays.asList(fTargets)); + + List group; + if (linkedGroup !is null) + group= new ArrayList(Arrays.asList(linkedGroup.getPositions())); + else + group= new ArrayList(); + + if (position is null || !(cast(Object)fDocument).opEquals(cast(Object)position.getDocument())) + // position is not valid if not in this document + position= null; + + LinkedPosition exit= fExitPosition; + if (exit is null || !(cast(Object)fDocument).opEquals(cast(Object)exit.getDocument())) + // position is not valid if not in this document + exit= null; + + + if (exit !is null) { + group.remove(exit); + targets.remove(exit); + } + + group.removeAll(targets); + targets.remove(position); + group.remove(position); + prune(targets); + prune(group); + + try { + setFocusPosition(position); + setExitPosition(exit); + setGroupPositions(group); + setTargetPositions(targets); + } catch (BadLocationException e) { + // will never happen as we don't actually add/remove positions from the document + // see the addPosition / removePosition methods + Assert.isTrue(false); + } + fireModelChanged(); + + } + + /** + * Prune list of all LinkedPositions that + * do not belong to this model's IDocument. + * + * @param list the list of positions to prune + */ + private void prune(List list) { + for (Iterator iter= list.iterator(); iter.hasNext();) { + LinkedPosition pos= cast(LinkedPosition) iter.next(); + if (!(cast(Object)pos.getDocument()).opEquals(cast(Object)fDocument)) + iter.remove(); + } + } + + /** + * Sets the target positions + * @param positions + */ + public void setTargets(Position[] positions) { + fTargets= positions; + } + + /** + * Sets the exit position. + * + * @param position the new exit position, or null if no exit position should be set + */ + public void setExitTarget(LinkedPosition position) { + fExitPosition = position; + } + + /* + * @see dwtx.jface.text.source.AnnotationModel#addPosition(dwtx.jface.text.IDocument, dwtx.jface.text.Position) + */ + protected void addPosition(IDocument document, Position position) { + // don't to anything as our positions are managed by custom + // position updaters + } + + /* + * @see dwtx.jface.text.source.AnnotationModel#removePosition(dwtx.jface.text.IDocument, dwtx.jface.text.Position) + */ + protected void removePosition(IDocument document, Position pos) { + // don't to anything as our positions are managed by custom + // position updaters + } + + /* + * @see dwtx.jface.text.source.AnnotationModel#fireModelChanged() + */ + public void fireModelChanged() { + super.fireModelChanged(); + } + + /** + * Sets the drawing state for the exit target. Default is true. + * + * @param markExitTargets the new drawing state for exit targets + */ + public void markExitTarget(bool markExitTargets) { + fMarkExitTarget= markExitTargets; + } + + /** + * Sets the drawing state for the focus position. Default is true. + * + * @param markFocus the new drawing state for exit targets + */ + public void markFocus(bool markFocus) { + fMarkFocus= markFocus; + } + + /** + * Sets the drawing state for slave positions. Default is true. + * + * @param markSlaves the new drawing state for slaves + */ + public void markSlaves(bool markSlaves) { + fMarkSlaves= markSlaves; + } + + /** + * Sets the drawing state for targets. Default is true. + * + * @param markTargets the new drawing state for targets + */ + public void markTargets(bool markTargets) { + fMarkTargets= markTargets; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/link/LinkedPositionGroup.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/link/LinkedPositionGroup.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,429 @@ +/******************************************************************************* + * 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 + * 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.text.link.LinkedPositionGroup; + +import dwtx.jface.text.link.LinkedModeModel; // packageimport +import dwtx.jface.text.link.LinkedPosition; // packageimport +import dwtx.jface.text.link.ILinkedModeListener; // packageimport +import dwtx.jface.text.link.TabStopIterator; // packageimport +import dwtx.jface.text.link.LinkedModeUI; // packageimport +import dwtx.jface.text.link.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.link.LinkedModeManager; // packageimport +import dwtx.jface.text.link.LinkedPositionAnnotations; // packageimport +import dwtx.jface.text.link.ProposalPosition; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; +import tango.text.convert.Format; + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.Position; +import dwtx.jface.text.Region; +import dwtx.text.edits.MalformedTreeException; +import dwtx.text.edits.MultiTextEdit; +import dwtx.text.edits.ReplaceEdit; +import dwtx.text.edits.TextEdit; + +/** + * A group of positions in multiple documents that are simultaneously modified - + * if one gets edited, all other positions in a group are edited the same way. + * All linked positions in a group have the same content. + *

                  + * Normally, new positions are given a tab stop weight which can be used by + * clients, e.g. the UI. If no weight is given, a position will not be visited. + * If no weights are used at all, the first position in a document is taken as + * the only stop as to comply with the behavior of the old linked position + * infrastructure. + *

                  + *

                  + * Clients may instantiate this class. + *

                  + * + * @since 3.0 + * @noextend This class is not intended to be subclassed by clients. + */ +public class LinkedPositionGroup { + + /** Sequence constant declaring that a position should not be stopped by. */ + public static const int NO_STOP= -1; + + /* members */ + + /** The linked positions of this group. */ + private const List fPositions; + /** Whether we are sealed or not. */ + private bool fIsSealed= false; + /** + * true if there are custom iteration weights. For backward + * compatibility. + */ + private bool fHasCustomIteration= false; + + /* + * iteration variables, set to communicate state between isLegalEvent and + * handleEvent + */ + /** The position including the most recent DocumentEvent. */ + private LinkedPosition fLastPosition; + /** The region covered by fLastPosition before the document + * change. + */ + private IRegion fLastRegion; + + this(){ + fPositions= new LinkedList(); + } + + /** + * Adds a position to this group. The document region defined by the + * position must contain the same content (and thus have the same length) as + * any of the other positions already in this group. Additionally, all + * positions added must be disjoint; otherwise a + * BadLocationException is thrown. + *

                  + * Positions added using this method are owned by this group afterwards and + * may not be updated or modified thereafter. + *

                  + *

                  + * Once a group has been added to a LinkedModeModel, it + * becomes sealed and no positions may be added any more. + *

                  + * + * @param position the position to add + * @throws BadLocationException if the position is invalid or conflicts with + * other positions in the group + * @throws IllegalStateException if the group has already been added to a + * model + */ + public void addPosition(LinkedPosition position) { + /* + * Enforces constraints and sets the custom iteration flag. If the + * position is already in this group, nothing happens. + */ + Assert.isNotNull(position); + if (fIsSealed) + throw new IllegalStateException("cannot add positions after the group is added to an model"); //$NON-NLS-1$ + + if (!fPositions.contains(position)) { + enforceDisjoint(position); + enforceEqualContent(position); + fPositions.add(position); + fHasCustomIteration |= position.getSequenceNumber() !is LinkedPositionGroup.NO_STOP; + } else + return; // nothing happens + } + + /** + * Enforces the invariant that all positions must contain the same string. + * + * @param position the position to check + * @throws BadLocationException if the equal content check fails + */ + private void enforceEqualContent(LinkedPosition position) { + if (fPositions.size() > 0) { + LinkedPosition groupPosition= cast(LinkedPosition) fPositions.get(0); + String groupContent= groupPosition.getContent(); + String positionContent= position.getContent(); + if (!groupContent.equals(positionContent)) + throw new BadLocationException(Format( "First position: '{}' at {}, this position: '{}' at {}", + groupContent, groupPosition.getOffset(), //$NON-NLS-1$ //$NON-NLS-2$ + positionContent, position.getOffset())); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + /** + * Enforces the invariant that all positions must be disjoint. + * + * @param position the position to check + * @throws BadLocationException if the disjointness check fails + */ + private void enforceDisjoint(LinkedPosition position) { + for (Iterator it= fPositions.iterator(); it.hasNext(); ) { + LinkedPosition p= cast(LinkedPosition) it.next(); + if (p.overlapsWith(position)) + throw new BadLocationException(); + } + } + + /** + * Enforces the disjointness for another group + * + * @param group the group to check + * @throws BadLocationException if the disjointness check fails + */ + void enforceDisjoint(LinkedPositionGroup group) { + Assert.isNotNull(group); + for (Iterator it= group.fPositions.iterator(); it.hasNext(); ) { + LinkedPosition p= cast(LinkedPosition) it.next(); + enforceDisjoint(p); + } + } + + /** + * Checks whether event is a legal event for this group. An + * event is legal if it touches at most one position contained within this + * group. + * + * @param event the document event to check + * @return true if event is legal + */ + bool isLegalEvent(DocumentEvent event) { + fLastPosition= null; + fLastRegion= null; + + for (Iterator it= fPositions.iterator(); it.hasNext(); ) { + LinkedPosition pos= cast(LinkedPosition) it.next(); + if (overlapsOrTouches(pos, event)) { + if (fLastPosition !is null) { + fLastPosition= null; + fLastRegion= null; + return false; + } + + fLastPosition= pos; + fLastRegion= new Region(pos.getOffset(), pos.getLength()); + } + } + + return true; + } + + /** + * Checks whether the given event touches the given position. To touch means + * to overlap or come up to the borders of the position. + * + * @param position the position + * @param event the event + * @return true if position and + * event are not absolutely disjoint + * @since 3.1 + */ + private bool overlapsOrTouches(LinkedPosition position, DocumentEvent event) { + return (cast(Object)position.getDocument()).opEquals(cast(Object)event.getDocument()) && position.getOffset() <= event.getOffset() + event.getLength() && position.getOffset() + position.getLength() >= event.getOffset(); + } + + /** + * Creates an edition of a document change that will forward any + * modification in one position to all linked siblings. The return value is + * a map from IDocument to TextEdit. + * + * @param event the document event to check + * @return a map of edits, grouped by edited document, or null + * if there are no edits + */ + Map handleEvent(DocumentEvent event) { + + if (fLastPosition !is null) { + + Map map= new HashMap(); + + + int relativeOffset= event.getOffset() - fLastRegion.getOffset(); + if (relativeOffset < 0) { + relativeOffset= 0; + } + + int eventEnd= event.getOffset() + event.getLength(); + int lastEnd= fLastRegion.getOffset() + fLastRegion.getLength(); + int length; + if (eventEnd > lastEnd) + length= lastEnd - relativeOffset - fLastRegion.getOffset(); + else + length= eventEnd - relativeOffset - fLastRegion.getOffset(); + + String text= event.getText(); + if (text is null) + text= ""; //$NON-NLS-1$ + + for (Iterator it= fPositions.iterator(); it.hasNext(); ) { + LinkedPosition p= cast(LinkedPosition) it.next(); + if (p is fLastPosition || p.isDeleted()) + continue; // don't re-update the origin of the change + + List edits= cast(List) map.get(cast(Object)p.getDocument()); + if (edits is null) { + edits= new ArrayList(); + map.put(cast(Object)p.getDocument(), cast(Object)edits); + } + + edits.add(new ReplaceEdit(p.getOffset() + relativeOffset, length, text)); + } + + try { + for (Iterator it= map.keySet().iterator(); it.hasNext();) { + IDocument d= cast(IDocument) it.next(); + TextEdit edit= new MultiTextEdit(0, d.getLength()); + edit.addChildren(arraycast!(TextEdit)( (cast(List) map.get(cast(Object)d)).toArray())); + map.put(cast(Object)d, edit); + } + + return map; + } catch (MalformedTreeException x) { + // may happen during undo, as LinkedModeModel does not know + // that the changes technically originate from a parent environment + // if this happens, post notification changes are not accepted anyway and + // we can simply return null - any changes will be undone by the undo + // manager + return null; + } + + } + + return null; + } + + /** + * Sets the model of this group. Once a model has been set, no + * more positions can be added and the model cannot be changed. + */ + void seal() { + Assert.isTrue(!fIsSealed); + fIsSealed= true; + + if (fHasCustomIteration is false && fPositions.size() > 0) { + (cast(LinkedPosition) fPositions.get(0)).setSequenceNumber(0); + } + } + + IDocument[] getDocuments() { + IDocument[] docs= new IDocument[fPositions.size()]; + int i= 0; + for (Iterator it= fPositions.iterator(); it.hasNext(); i++) { + LinkedPosition pos= cast(LinkedPosition) it.next(); + docs[i]= pos.getDocument(); + } + return docs; + } + + void register(LinkedModeModel model) { + for (Iterator it= fPositions.iterator(); it.hasNext(); ) { + LinkedPosition pos= cast(LinkedPosition) it.next(); + model.register(pos); + } + } + + /** + * Returns the position in this group that encompasses all positions in + * group. + * + * @param group the group to be adopted + * @return a position in the receiver that contains all positions in group, + * or null if none can be found + * @throws BadLocationException if more than one position are affected by + * group + */ + LinkedPosition adopt(LinkedPositionGroup group) { + LinkedPosition found= null; + for (Iterator it= group.fPositions.iterator(); it.hasNext(); ) { + LinkedPosition pos= cast(LinkedPosition) it.next(); + LinkedPosition localFound= null; + for (Iterator it2= fPositions.iterator(); it2.hasNext(); ) { + LinkedPosition myPos= cast(LinkedPosition) it2.next(); + if (myPos.includes(pos)) { + if (found is null) + found= myPos; + else if (found !is myPos) + throw new BadLocationException(); + if (localFound is null) + localFound= myPos; + } + } + + if (localFound !is found) + throw new BadLocationException(); + } + return found; + } + + /** + * Finds the closest position to toFind. + * + * @param toFind the linked position for which to find the closest position + * @return the closest position to toFind. + */ + LinkedPosition getPosition(LinkedPosition toFind) { + for (Iterator it= fPositions.iterator(); it.hasNext(); ) { + LinkedPosition p= cast(LinkedPosition) it.next(); + if (p.includes(toFind)) + return p; + } + return null; + } + + /** + * Returns true if offset is contained in any + * position in this group. + * + * @param offset the offset to check + * @return true if offset is contained by this group + */ + bool contains(int offset) { + for (Iterator it= fPositions.iterator(); it.hasNext(); ) { + LinkedPosition pos= cast(LinkedPosition) it.next(); + if (pos.includes(offset)) { + return true; + } + } + return false; + } + + /** + * Returns whether this group contains any positions. + * + * @return true if this group is empty, false otherwise + * @since 3.1 + */ + public bool isEmpty() { + return fPositions.size() is 0; + } + + /** + * Returns whether this group contains any positions. + * + * @return true if this group is empty, false otherwise + * @deprecated As of 3.1, replaced by {@link #isEmpty()} + */ + public bool isEmtpy() { + return isEmpty(); + } + + /** + * Returns the positions contained in the receiver as an array. The + * positions are the actual positions and must not be modified; the array + * is a copy of internal structures. + * + * @return the positions of this group in no particular order + */ + public LinkedPosition[] getPositions() { + return arraycast!(LinkedPosition) (fPositions.toArray()); + } + + /** + * Returns true if the receiver contains position. + * + * @param position the position to check + * @return true if the receiver contains position + */ + bool contains(Position position) { + for (Iterator it= fPositions.iterator(); it.hasNext(); ) { + LinkedPosition p= cast(LinkedPosition) it.next(); + if (position.opEquals(p)) + return true; + } + return false; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/link/ProposalPosition.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/link/ProposalPosition.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.link.ProposalPosition; + +import dwtx.jface.text.link.LinkedModeModel; // packageimport +import dwtx.jface.text.link.LinkedPosition; // packageimport +import dwtx.jface.text.link.ILinkedModeListener; // packageimport +import dwtx.jface.text.link.TabStopIterator; // packageimport +import dwtx.jface.text.link.LinkedModeUI; // packageimport +import dwtx.jface.text.link.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.link.LinkedPositionGroup; // packageimport +import dwtx.jface.text.link.LinkedModeManager; // packageimport +import dwtx.jface.text.link.LinkedPositionAnnotations; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + +import dwtx.jface.text.IDocument; +import dwtx.jface.text.contentassist.ICompletionProposal; + +/** + * LinkedPosition with added completion proposals. + *

                  + * Clients may instantiate or extend this class. + *

                  + * + * @since 3.0 + */ +public class ProposalPosition : LinkedPosition { + + /** + * The proposals + */ + private ICompletionProposal[] fProposals; + + /** + * Creates a new instance. + * + * @param document the document + * @param offset the offset of the position + * @param length the length of the position + * @param sequence the iteration sequence rank + * @param proposals the proposals to be shown when entering this position + */ + public this(IDocument document, int offset, int length, int sequence, ICompletionProposal[] proposals) { + super(document, offset, length, sequence); + fProposals= copy(proposals); + } + + /** + * Creates a new instance, with no sequence number. + * + * @param document the document + * @param offset the offset of the position + * @param length the length of the position + * @param proposals the proposals to be shown when entering this position + */ + public this(IDocument document, int offset, int length, ICompletionProposal[] proposals) { + super(document, offset, length, LinkedPositionGroup.NO_STOP); + fProposals= copy(proposals); + } + + /* + * @since 3.1 + */ + private ICompletionProposal[] copy(ICompletionProposal[] proposals) { + if (proposals !is null) { + ICompletionProposal[] copy= new ICompletionProposal[proposals.length]; + SimpleType!(ICompletionProposal).arraycopy(proposals, 0, copy, 0, proposals.length); + return copy; + } + return null; + } + + /* + * @see java.lang.Object#equals(java.lang.Object) + */ + public override int opEquals(Object o) { + if ( cast(ProposalPosition)o ) { + if (super.opEquals(o)) { + return Arrays.equals(fProposals, (cast(ProposalPosition)o).fProposals); + } + } + return false; + } + + /** + * Returns the proposals attached to this position. The returned array is owned by + * this ProposalPosition and may not be modified by clients. + * + * @return an array of choices, including the initial one. Callers must not + * modify it. + */ + public ICompletionProposal[] getChoices() { + return fProposals; + } + + /* + * @see dwtx.jdt.internal.ui.text.link.LinkedPosition#hashCode() + */ + public override hash_t toHash() { + return super.toHash() | (fProposals is null ? 0 : (cast(hash_t)fProposals.ptr)/+.toHash()+/); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/link/TabStopIterator.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/link/TabStopIterator.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,234 @@ +/******************************************************************************* + * 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 + * 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.text.link.TabStopIterator; + +import dwtx.jface.text.link.LinkedModeModel; // packageimport +import dwtx.jface.text.link.LinkedPosition; // packageimport +import dwtx.jface.text.link.ILinkedModeListener; // packageimport +import dwtx.jface.text.link.LinkedModeUI; // packageimport +import dwtx.jface.text.link.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.link.LinkedPositionGroup; // packageimport +import dwtx.jface.text.link.LinkedModeManager; // packageimport +import dwtx.jface.text.link.LinkedPositionAnnotations; // packageimport +import dwtx.jface.text.link.ProposalPosition; // packageimport + + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; +import tango.core.Exception; + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.Position; + + + +/** + * Iterator that leaps over the double occurrence of an element when switching from forward + * to backward iteration that is shown by ListIterator. + *

                  + * Package private, only for use by LinkedModeUI. + *

                  + * @since 3.0 + */ +class TabStopIterator { + /** + * Comparator for LinkedPositions. If the sequence number of two positions is equal, the + * offset is used. + */ + private static class SequenceComparator : Comparator { + + /** + * {@inheritDoc} + * + *

                  o1 and o2 are required to be instances + * of LinkedPosition.

                  + */ + public int compare(Object o1, Object o2) { + LinkedPosition p1= cast(LinkedPosition)o1; + LinkedPosition p2= cast(LinkedPosition)o2; + int i= p1.getSequenceNumber() - p2.getSequenceNumber(); + if (i !is 0) + return i; + return p1.getOffset() - p2.getOffset(); + } + + } + + /** The comparator to sort the list of positions. */ + private static Comparator fComparator_; + private static Comparator fComparator(){ + if( fComparator_ is null ){ + synchronized( TabStopIterator.classinfo ){ + if( fComparator_ is null ){ + fComparator_ = new SequenceComparator(); + } + } + } + return fComparator_; + } + + /** The iteration sequence. */ + private const ArrayList fList; + /** The size of fList. */ + private int fSize; + /** Index of the current element, to the first one initially. */ + private int fIndex; + /** Cycling property. */ + private bool fIsCycling= false; + + this(List positionSequence) { + Assert.isNotNull(cast(Object)positionSequence); + fList= new ArrayList(positionSequence); + Collections.sort(fList, fComparator); + fSize= fList.size(); + fIndex= -1; + Assert.isTrue(fSize > 0); + } + + bool hasNext(LinkedPosition current) { + return getNextIndex(current) !is fSize; + } + + private int getNextIndex(LinkedPosition current) { + if (current !is null && fList.get(fIndex) !is current) + return findNext(current); + else if (fIsCycling && fIndex is fSize - 1) + return 0; + else + // default: increase + return fIndex + 1; + } + + /** + * Finds the closest position in the iteration set that follows after + * current and sets fIndex accordingly. If current + * is in the iteration set, the next in turn is chosen. + * + * @param current the current position + * @return true if there is a next position, false otherwise + */ + private int findNext(LinkedPosition current) { + Assert.isNotNull(current); + // if the position is in the iteration set, jump to the next one + int index= fList.indexOf(current); + if (index !is -1) { + if (fIsCycling && index is fSize - 1) + return 0; + return index + 1; + } + + // index is -1 + + // find the position that follows closest to the current position + LinkedPosition found= null; + for (Iterator it= fList.iterator(); it.hasNext(); ) { + LinkedPosition p= cast(LinkedPosition) it.next(); + if (p.offset > current.offset) + if (found is null || found.offset > p.offset) + found= p; + } + + if (found !is null) { + return fList.indexOf(found); + } else if (fIsCycling) { + return 0; + } else + return fSize; + } + + bool hasPrevious(LinkedPosition current) { + return getPreviousIndex(current) !is -1; + } + + private int getPreviousIndex(LinkedPosition current) { + if (current !is null && fList.get(fIndex) !is current) + return findPrevious(current); + else if (fIsCycling && fIndex is 0) + return fSize - 1; + else + return fIndex - 1; + } + + /** + * Finds the closest position in the iteration set that precedes + * current. If current + * is in the iteration set, the previous in turn is chosen. + * + * @param current the current position + * @return the index of the previous position + */ + private int findPrevious(LinkedPosition current) { + Assert.isNotNull(current); + // if the position is in the iteration set, jump to the next one + int index= fList.indexOf(current); + if (index !is -1) { + if (fIsCycling && index is 0) + return fSize - 1; + return index - 1; + } + + // index is -1 + + // find the position that follows closest to the current position + LinkedPosition found= null; + for (Iterator it= fList.iterator(); it.hasNext(); ) { + LinkedPosition p= cast(LinkedPosition) it.next(); + if (p.offset < current.offset) + if (found is null || found.offset < p.offset) + found= p; + } + if (found !is null) { + return fList.indexOf(found); + } else if (fIsCycling) { + return fSize - 1; + } else + return -1; + } + + LinkedPosition next(LinkedPosition current) { + if (!hasNext(current)) + throw new NoSuchElementException(null); + return cast(LinkedPosition) fList.get(fIndex= getNextIndex(current)); + } + + LinkedPosition previous(LinkedPosition current) { + if (!hasPrevious(current)) + throw new NoSuchElementException(null); + return cast(LinkedPosition) fList.get(fIndex= getPreviousIndex(current)); + } + + void setCycling(bool mode) { + fIsCycling= mode; + } + + void addPosition(Position position) { + fList.add(fSize++, position); + Collections.sort(fList, fComparator); + } + + void removePosition(Position position) { + if (fList.remove(position)) + fSize--; + } + + /** + * @return Returns the isCycling. + */ + bool isCycling() { + return fIsCycling; + } + + LinkedPosition[] getPositions() { + return arraycast!(LinkedPosition)( fList.toArray()); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/presentation/IPresentationDamager.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/presentation/IPresentationDamager.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.presentation.IPresentationDamager; + +import dwtx.jface.text.presentation.IPresentationReconciler; // packageimport +import dwtx.jface.text.presentation.PresentationReconciler; // packageimport +import dwtx.jface.text.presentation.IPresentationRepairer; // packageimport +import dwtx.jface.text.presentation.IPresentationReconcilerExtension; // packageimport + + +import dwt.dwthelper.utils; + + + +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITypedRegion; + + +/** + * A presentation damager is a strategy used by a presentation reconciler to + * determine the region of the document's presentation which must be rebuilt + * because of a document change. A presentation damager is assumed to be + * specific for a particular document content type. A presentation damager is + * expected to return a damage region which is a valid input for a presentation + * repairer. I.e. having access to the damage region only the repairer must be + * able to derive all the information needed to successfully repair this region. + *

                  + * This interface must either be implemented by clients or clients use the + * rule-based default implementation + * {@link dwtx.jface.text.rules.DefaultDamagerRepairer}. Implementers + * should be registered with a presentation reconciler in order get involved in + * the reconciling process.

                  + * + * @see IPresentationReconciler + * @see IDocument + * @see DocumentEvent + * @see IPresentationRepairer + */ +public interface IPresentationDamager { + + /** + * Tells the presentation damager on which document it will work. + * + * @param document the damager's working document + */ + void setDocument(IDocument document); + + /** + * Returns the damage in the document's presentation caused by the given document change. + * The damage is restricted to the specified partition for which the presentation damager is + * responsible. The damage may also depend on whether the document change also caused changes + * of the document's partitioning. + * + * @param partition the partition inside which the damage must be determined + * @param event the event describing the change whose damage must be determined + * @param documentPartitioningChanged indicates whether the given change changed the document's partitioning + * @return the computed damage + */ + IRegion getDamageRegion(ITypedRegion partition, DocumentEvent event, bool documentPartitioningChanged); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/presentation/IPresentationReconciler.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/presentation/IPresentationReconciler.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.presentation.IPresentationReconciler; + +import dwtx.jface.text.presentation.IPresentationDamager; // packageimport +import dwtx.jface.text.presentation.PresentationReconciler; // packageimport +import dwtx.jface.text.presentation.IPresentationRepairer; // packageimport +import dwtx.jface.text.presentation.IPresentationReconcilerExtension; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.jface.text.ITextViewer; + + +/** + * An IPresentationReconciler defines and maintains the + * representation of a text viewer's document in the presence of changes applied + * to the document. An IPresentationReconciler is a + * ITextViewer add-on. + *

                  + * The presentation reconciler keeps track of changes applied to the text + * viewer. It sends each change to presentation damagers which are registered + * for the content types of the regions in which the change occurred. The + * presentation reconciler passes the computed damage to presentation repairer + * which construct text presentations. When applied to the presentation + * reconciler's text viewer, those text presentations bring the document's + * presentation in sync with the document's content and thus repair the damage. + * A presentation damager is expected to return damage which is a valid input + * for a presentation repairer registered for the same content type as the + * damager. + *

                  + *

                  + * A presentation reconciler should always be configured with a pair of + * damager/repairer strategies. I.e. for each damager there should be a + * corresponding repairer. + *

                  + *

                  + * The interface may be implemented by clients. Clients may use + * PresentationReconciler as the standard implementation of this + * interface. + *

                  + *

                  + * In order to provided backward compatibility for clients of + * IPresentationReconciler, extension interfaces are used to + * provide a means of evolution. The following extension interface exists: + *

                    + *
                  • + * {@link dwtx.jface.text.presentation.IPresentationReconcilerExtension} + * since version 3.0 adding support for documents with multiple partitionings. + *
                  • + *
                  + *

                  + * + * @see dwtx.jface.text.presentation.IPresentationReconcilerExtension + * @see dwtx.jface.text.ITextViewer + * @see dwtx.jface.text.presentation.IPresentationDamager + * @see dwtx.jface.text.presentation.IPresentationRepairer + * @see dwtx.jface.text.TextPresentation + */ +public interface IPresentationReconciler { + + /** + * Installs this presentation reconciler on the given text viewer. After + * this method has been finished, the reconciler is operational. I.e., it + * works without requesting further client actions until + * uninstall is called. + *

                  + * The install and uninstall methods must be + * called in sequence; i.e. repeatedly calling install + * without calling uninstall may throw an exception. + *

                  + * + * @param viewer the viewer on which this presentation reconciler is + * installed + */ + void install(ITextViewer viewer); + + /** + * Removes the reconciler from the text viewer it has previously been + * installed on. + */ + void uninstall(); + + /** + * Returns the presentation damager registered with this presentation reconciler + * for the specified content type. + * + * @param contentType the content type for which to determine the damager + * @return the presentation damager registered for the given content type, or + * null if there is no damager + */ + IPresentationDamager getDamager(String contentType); + + /** + * Returns the presentation repairer registered with this presentation reconciler + * for the specified content type. + * + * @param contentType the content type for which to determine the repairer + * @return the presentation repairer registered for the given content type, or + * null if there is no repairer + */ + IPresentationRepairer getRepairer(String contentType); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/presentation/IPresentationReconcilerExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/presentation/IPresentationReconcilerExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.presentation.IPresentationReconcilerExtension; + +import dwtx.jface.text.presentation.IPresentationDamager; // packageimport +import dwtx.jface.text.presentation.IPresentationReconciler; // packageimport +import dwtx.jface.text.presentation.PresentationReconciler; // packageimport +import dwtx.jface.text.presentation.IPresentationRepairer; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Extension interface for {@link IPresentationReconciler}. Adds awareness of + * documents with multiple partitions. + * + * @since 3.0 + */ +public interface IPresentationReconcilerExtension { + + /** + * Returns the document partitioning this presentation reconciler is using. + * + * @return the document partitioning this presentation reconciler is using + */ + String getDocumentPartitioning(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/presentation/IPresentationRepairer.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/presentation/IPresentationRepairer.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.presentation.IPresentationRepairer; + +import dwtx.jface.text.presentation.IPresentationDamager; // packageimport +import dwtx.jface.text.presentation.IPresentationReconciler; // packageimport +import dwtx.jface.text.presentation.PresentationReconciler; // packageimport +import dwtx.jface.text.presentation.IPresentationReconcilerExtension; // packageimport + + +import dwt.dwthelper.utils; + + + +import dwtx.jface.text.IDocument; +import dwtx.jface.text.ITypedRegion; +import dwtx.jface.text.TextPresentation; + + +/** + * A presentation repairer is a strategy used by a presentation reconciler to + * rebuild a damaged region in a document's presentation. A presentation + * repairer is assumed to be specific for a particular document content type. + * The presentation repairer gets the region which it should repair and + * constructs a "repair description". The presentation repairer merges the steps + * contained within this description into the text presentation passed into + * createPresentation. + *

                  + * This interface may be implemented by clients. Alternatively, clients may use + * the rule-based default implementation + * {@link dwtx.jface.text.rules.DefaultDamagerRepairer}. Implementers + * should be registered with a presentation reconciler in order get involved in + * the reconciling process. + *

                  + * + * @see IPresentationReconciler + * @see IDocument + * @see dwt.custom.StyleRange + * @see TextPresentation + */ +public interface IPresentationRepairer { + + + /** + * Tells the presentation repairer on which document it will work. + * + * @param document the damager's working document + */ + void setDocument(IDocument document); + + /** + * Fills the given presentation with the style ranges which when applied to the + * presentation reconciler's text viewer repair the presentation damage described by + * the given region. + * + * @param presentation the text presentation to be filled by this repairer + * @param damage the damage to be repaired + */ + void createPresentation(TextPresentation presentation, ITypedRegion damage); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/presentation/PresentationReconciler.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/presentation/PresentationReconciler.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,603 @@ +/******************************************************************************* + * 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 + * 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.text.presentation.PresentationReconciler; + +import dwtx.jface.text.presentation.IPresentationDamager; // packageimport +import dwtx.jface.text.presentation.IPresentationReconciler; // packageimport +import dwtx.jface.text.presentation.IPresentationRepairer; // packageimport +import dwtx.jface.text.presentation.IPresentationReconcilerExtension; // packageimport + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + +import dwt.custom.StyleRange; +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.BadPositionCategoryException; +import dwtx.jface.text.DefaultPositionUpdater; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.DocumentPartitioningChangedEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentExtension3; +import dwtx.jface.text.IDocumentListener; +import dwtx.jface.text.IDocumentPartitioningListener; +import dwtx.jface.text.IDocumentPartitioningListenerExtension; +import dwtx.jface.text.IDocumentPartitioningListenerExtension2; +import dwtx.jface.text.IPositionUpdater; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextInputListener; +import dwtx.jface.text.ITextListener; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.ITextViewerExtension5; +import dwtx.jface.text.ITypedRegion; +import dwtx.jface.text.Region; +import dwtx.jface.text.TextEvent; +import dwtx.jface.text.TextPresentation; +import dwtx.jface.text.TextUtilities; +import dwtx.jface.text.TypedPosition; + + + +/** + * Standard implementation of IPresentationReconciler. This + * implementation assumes that the tasks performed by its presentation damagers + * and repairers are lightweight and of low cost. This presentation reconciler + * runs in the UI thread and always repairs the complete damage caused by a + * document change rather than just the portion overlapping with the viewer's + * viewport. + *

                  + * Usually, clients instantiate this class and configure it before using it. + *

                  + */ +public class PresentationReconciler : IPresentationReconciler, IPresentationReconcilerExtension { + + /** Prefix of the name of the position category for tracking damage regions. */ + protected const static String TRACKED_PARTITION= "__reconciler_tracked_partition"; //$NON-NLS-1$ + + + /** + * Internal listener class. + */ + class InternalListener : + ITextInputListener, IDocumentListener, ITextListener, + IDocumentPartitioningListener, IDocumentPartitioningListenerExtension, IDocumentPartitioningListenerExtension2 { + + /** Set to true if between a document about to be changed and a changed event. */ + private bool fDocumentChanging= false; + /** + * The cached redraw state of the text viewer. + * @since 3.0 + */ + private bool fCachedRedrawState= true; + + /* + * @see ITextInputListener#inputDocumentAboutToBeChanged(IDocument, IDocument) + */ + public void inputDocumentAboutToBeChanged(IDocument oldDocument, IDocument newDocument) { + if (oldDocument !is null) { + try { + + fViewer.removeTextListener(this); + oldDocument.removeDocumentListener(this); + oldDocument.removeDocumentPartitioningListener(this); + + oldDocument.removePositionUpdater(fPositionUpdater); + oldDocument.removePositionCategory(fPositionCategory); + + } catch (BadPositionCategoryException x) { + // should not happened for former input documents; + } + } + } + + /* + * @see ITextInputListener#inputDocumenChanged(IDocument, IDocument) + */ + public void inputDocumentChanged(IDocument oldDocument, IDocument newDocument) { + + fDocumentChanging= false; + fCachedRedrawState= true; + + if (newDocument !is null) { + + newDocument.addPositionCategory(fPositionCategory); + newDocument.addPositionUpdater(fPositionUpdater); + + newDocument.addDocumentPartitioningListener(this); + newDocument.addDocumentListener(this); + fViewer.addTextListener(this); + + setDocumentToDamagers(newDocument); + setDocumentToRepairers(newDocument); + processDamage(new Region(0, newDocument.getLength()), newDocument); + } + } + + /* + * @see IDocumentPartitioningListener#documentPartitioningChanged(IDocument) + */ + public void documentPartitioningChanged(IDocument document) { + if (!fDocumentChanging && fCachedRedrawState) + processDamage(new Region(0, document.getLength()), document); + else + fDocumentPartitioningChanged= true; + } + + /* + * @see IDocumentPartitioningListenerExtension#documentPartitioningChanged(IDocument, IRegion) + * @since 2.0 + */ + public void documentPartitioningChanged(IDocument document, IRegion changedRegion) { + if (!fDocumentChanging && fCachedRedrawState) { + processDamage(new Region(changedRegion.getOffset(), changedRegion.getLength()), document); + } else { + fDocumentPartitioningChanged= true; + fChangedDocumentPartitions= changedRegion; + } + } + + /* + * @see dwtx.jface.text.IDocumentPartitioningListenerExtension2#documentPartitioningChanged(dwtx.jface.text.DocumentPartitioningChangedEvent) + * @since 3.0 + */ + public void documentPartitioningChanged(DocumentPartitioningChangedEvent event) { + IRegion changedRegion= event.getChangedRegion(getDocumentPartitioning()); + if (changedRegion !is null) + documentPartitioningChanged(event.getDocument(), changedRegion); + } + + /* + * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent) + */ + public void documentAboutToBeChanged(DocumentEvent e) { + + fDocumentChanging= true; + if (fCachedRedrawState) { + try { + int offset= e.getOffset() + e.getLength(); + ITypedRegion region= getPartition(e.getDocument(), offset); + fRememberedPosition= new TypedPosition(region); + e.getDocument().addPosition(fPositionCategory, fRememberedPosition); + } catch (BadLocationException x) { + // can not happen + } catch (BadPositionCategoryException x) { + // should not happen on input elements + } + } + } + + /* + * @see IDocumentListener#documentChanged(DocumentEvent) + */ + public void documentChanged(DocumentEvent e) { + if (fCachedRedrawState) { + try { + e.getDocument().removePosition(fPositionCategory, fRememberedPosition); + } catch (BadPositionCategoryException x) { + // can not happen on input documents + } + } + fDocumentChanging= false; + } + + /* + * @see ITextListener#textChanged(TextEvent) + */ + public void textChanged(TextEvent e) { + + fCachedRedrawState= e.getViewerRedrawState(); + if (!fCachedRedrawState) + return; + + IRegion damage= null; + IDocument document= null; + + if (e.getDocumentEvent() is null) { + document= fViewer.getDocument(); + if (document !is null) { + if (e.getOffset() is 0 && e.getLength() is 0 && e.getText() is null) { + // redraw state change, damage the whole document + damage= new Region(0, document.getLength()); + } else { + IRegion region= widgetRegion2ModelRegion(e); + try { + String text= document.get(region.getOffset(), region.getLength()); + DocumentEvent de= new DocumentEvent(document, region.getOffset(), region.getLength(), text); + damage= getDamage(de, false); + } catch (BadLocationException x) { + } + } + } + } else { + DocumentEvent de= e.getDocumentEvent(); + document= de.getDocument(); + damage= getDamage(de, true); + } + + if (damage !is null && document !is null) + processDamage(damage, document); + + fDocumentPartitioningChanged= false; + fChangedDocumentPartitions= null; + } + + /** + * Translates the given text event into the corresponding range of the viewer's document. + * + * @param e the text event + * @return the widget region corresponding the region of the given event + * @since 2.1 + */ + protected IRegion widgetRegion2ModelRegion(TextEvent e) { + + String text= e.getText(); + int length= text is null ? 0 : text.length(); + + if ( cast(ITextViewerExtension5)fViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) fViewer; + return extension.widgetRange2ModelRange(new Region(e.getOffset(), length)); + } + + IRegion visible= fViewer.getVisibleRegion(); + IRegion region= new Region(e.getOffset() + visible.getOffset(), length); + return region; + } + } + + /** The map of presentation damagers. */ + private Map fDamagers; + /** The map of presentation repairers. */ + private Map fRepairers; + /** The target viewer. */ + private ITextViewer fViewer; + /** The internal listener. */ + private InternalListener fInternalListener; + /** The name of the position category to track damage regions. */ + private String fPositionCategory; + /** The position updated for the damage regions' position category. */ + private IPositionUpdater fPositionUpdater; + /** The positions representing the damage regions. */ + private TypedPosition fRememberedPosition; + /** Flag indicating the receipt of a partitioning changed notification. */ + private bool fDocumentPartitioningChanged= false; + /** The range covering the changed partitioning. */ + private IRegion fChangedDocumentPartitions= null; + /** + * The partitioning used by this presentation reconciler. + * @since 3.0 + */ + private String fPartitioning; + + /** + * Creates a new presentation reconciler. There are no damagers or repairers + * registered with this reconciler by default. The default partitioning + * IDocumentExtension3.DEFAULT_PARTITIONING is used. + */ + public this() { + fInternalListener= new InternalListener(); +// super(); + fPartitioning= IDocumentExtension3.DEFAULT_PARTITIONING; + fPositionCategory= TRACKED_PARTITION ~ Integer.toString(toHash()); + fPositionUpdater= new DefaultPositionUpdater(fPositionCategory); + } + + /** + * Sets the document partitioning for this presentation reconciler. + * + * @param partitioning the document partitioning for this presentation reconciler. + * @since 3.0 + */ + public void setDocumentPartitioning(String partitioning) { + Assert.isNotNull(partitioning); + fPartitioning= partitioning; + } + + /* + * @see dwtx.jface.text.presentation.IPresentationReconcilerExtension#geDocumenttPartitioning() + * @since 3.0 + */ + public String getDocumentPartitioning() { + return fPartitioning; + } + + /** + * Registers the given presentation damager for a particular content type. + * If there is already a damager registered for this type, the old damager + * is removed first. + * + * @param damager the presentation damager to register, or null to remove an existing one + * @param contentType the content type under which to register + */ + public void setDamager(IPresentationDamager damager, String contentType) { + + Assert.isNotNull(contentType); + + if (fDamagers is null) + fDamagers= new HashMap(); + + if (damager is null) + fDamagers.remove(contentType); + else + fDamagers.put(stringcast(contentType), cast(Object)damager); + } + + /** + * Registers the given presentation repairer for a particular content type. + * If there is already a repairer registered for this type, the old repairer + * is removed first. + * + * @param repairer the presentation repairer to register, or null to remove an existing one + * @param contentType the content type under which to register + */ + public void setRepairer(IPresentationRepairer repairer, String contentType) { + + Assert.isNotNull(contentType); + + if (fRepairers is null) + fRepairers= new HashMap(); + + if (repairer is null) + fRepairers.remove(contentType); + else + fRepairers.put(stringcast(contentType), cast(Object)repairer); + } + + /* + * @see IPresentationReconciler#install(ITextViewer) + */ + public void install(ITextViewer viewer) { + Assert.isNotNull(cast(Object)viewer); + + fViewer= viewer; + fViewer.addTextInputListener(fInternalListener); + + IDocument document= viewer.getDocument(); + if (document !is null) + fInternalListener.inputDocumentChanged(null, document); + } + + /* + * @see IPresentationReconciler#uninstall() + */ + public void uninstall() { + fViewer.removeTextInputListener(fInternalListener); + + // Ensure we uninstall all listeners + fInternalListener.inputDocumentAboutToBeChanged(fViewer.getDocument(), null); + } + + /* + * @see IPresentationReconciler#getDamager(String) + */ + public IPresentationDamager getDamager(String contentType) { + + if (fDamagers is null) + return null; + + return cast(IPresentationDamager) fDamagers.get(contentType); + } + + /* + * @see IPresentationReconciler#getRepairer(String) + */ + public IPresentationRepairer getRepairer(String contentType) { + + if (fRepairers is null) + return null; + + return cast(IPresentationRepairer) fRepairers.get(contentType); + } + + /** + * Informs all registered damagers about the document on which they will work. + * + * @param document the document on which to work + */ + protected void setDocumentToDamagers(IDocument document) { + if (fDamagers !is null) { + Iterator e= fDamagers.values().iterator(); + while (e.hasNext()) { + IPresentationDamager damager= cast(IPresentationDamager) e.next(); + damager.setDocument(document); + } + } + } + + /** + * Informs all registered repairers about the document on which they will work. + * + * @param document the document on which to work + */ + protected void setDocumentToRepairers(IDocument document) { + if (fRepairers !is null) { + Iterator e= fRepairers.values().iterator(); + while (e.hasNext()) { + IPresentationRepairer repairer= cast(IPresentationRepairer) e.next(); + repairer.setDocument(document); + } + } + } + + /** + * Constructs a "repair description" for the given damage and returns this + * description as a text presentation. For this, it queries the partitioning + * of the damage region and asks the appropriate presentation repairer for + * each partition to construct the "repair description" for this partition. + * + * @param damage the damage to be repaired + * @param document the document whose presentation must be repaired + * @return the presentation repair description as text presentation or + * null if the partitioning could not be computed + */ + protected TextPresentation createPresentation(IRegion damage, IDocument document) { + try { + if (fRepairers is null || fRepairers.isEmpty()) { + TextPresentation presentation= new TextPresentation(damage, 100); + presentation.setDefaultStyleRange(new StyleRange(damage.getOffset(), damage.getLength(), null, null)); + return presentation; + } + + TextPresentation presentation= new TextPresentation(damage, 1000); + + ITypedRegion[] partitioning= TextUtilities.computePartitioning(document, getDocumentPartitioning(), damage.getOffset(), damage.getLength(), false); + for (int i= 0; i < partitioning.length; i++) { + ITypedRegion r= partitioning[i]; + IPresentationRepairer repairer= getRepairer(r.getType()); + if (repairer !is null) + repairer.createPresentation(presentation, r); + } + + return presentation; + + } catch (BadLocationException x) { + return null; + } + } + + + /** + * Checks for the first and the last affected partition affected by a + * document event and calls their damagers. Invalidates everything from the + * start of the damage for the first partition until the end of the damage + * for the last partition. + * + * @param e the event describing the document change + * @param optimize true if partition changes should be + * considered for optimization + * @return the damaged caused by the change or null if + * computing the partitioning failed + * @since 3.0 + */ + private IRegion getDamage(DocumentEvent e, bool optimize) { + int length= e.getText() is null ? 0 : e.getText().length(); + + if (fDamagers is null || fDamagers.isEmpty()) { + length= Math.max(e.getLength(), length); + length= Math.min(e.getDocument().getLength() - e.getOffset(), length); + return new Region(e.getOffset(), length); + } + + bool isDeletion= length is 0; + IRegion damage= null; + try { + int offset= e.getOffset(); + if (isDeletion) + offset= Math.max(0, offset - 1); + ITypedRegion partition= getPartition(e.getDocument(), offset); + IPresentationDamager damager= getDamager(partition.getType()); + if (damager is null) + return null; + + IRegion r= damager.getDamageRegion(partition, e, fDocumentPartitioningChanged); + + if (!fDocumentPartitioningChanged && optimize && !isDeletion) { + damage= r; + } else { + + int damageEnd= getDamageEndOffset(e); + + int parititionDamageEnd= -1; + if (fChangedDocumentPartitions !is null) + parititionDamageEnd= fChangedDocumentPartitions.getOffset() + fChangedDocumentPartitions.getLength(); + + int end= Math.max(damageEnd, parititionDamageEnd); + + damage= end is -1 ? r : new Region(r.getOffset(), end - r.getOffset()); + } + + } catch (BadLocationException x) { + } + + return damage; + } + + /** + * Returns the end offset of the damage. If a partition has been split by + * the given document event also the second half of the original + * partition must be considered. This is achieved by using the remembered + * partition range. + * + * @param e the event describing the change + * @return the damage end offset (excluding) + * @exception BadLocationException if method accesses invalid offset + */ + private int getDamageEndOffset(DocumentEvent e) { + + IDocument d= e.getDocument(); + + int length= 0; + if (e.getText() !is null) { + length= e.getText().length; + if (length > 0) + -- length; + } + + ITypedRegion partition= getPartition(d, e.getOffset() + length); + int endOffset= partition.getOffset() + partition.getLength(); + if (endOffset is e.getOffset()) + return -1; + + int end= fRememberedPosition is null ? -1 : fRememberedPosition.getOffset() + fRememberedPosition.getLength(); + if (endOffset < end && end < d.getLength()) + partition= getPartition(d, end); + + IPresentationDamager damager= getDamager(partition.getType()); + if (damager is null) + return -1; + + IRegion r= damager.getDamageRegion(partition, e, fDocumentPartitioningChanged); + + return r.getOffset() + r.getLength(); + } + + /** + * Processes the given damage. + * @param damage the damage to be repaired + * @param document the document whose presentation must be repaired + */ + private void processDamage(IRegion damage, IDocument document) { + if (damage !is null && damage.getLength() > 0) { + TextPresentation p= createPresentation(damage, document); + if (p !is null) + applyTextRegionCollection(p); + } + } + + /** + * Applies the given text presentation to the text viewer the presentation + * reconciler is installed on. + * + * @param presentation the text presentation to be applied to the text viewer + */ + private void applyTextRegionCollection(TextPresentation presentation) { + fViewer.changeTextPresentation(presentation, false); + } + + /** + * Returns the partition for the given offset in the given document. + * + * @param document the document + * @param offset the offset + * @return the partition + * @throws BadLocationException if offset is invalid in the given document + * @since 3.0 + */ + private ITypedRegion getPartition(IDocument document, int offset) { + return TextUtilities.getPartition(document, getDocumentPartitioning(), offset, false); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/projection/ChildDocument.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/projection/ChildDocument.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,116 @@ +/******************************************************************************* + * 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 + * 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.text.projection.ChildDocument; + +import dwtx.jface.text.projection.ProjectionMapping; // packageimport +import dwtx.jface.text.projection.ChildDocumentManager; // packageimport +import dwtx.jface.text.projection.SegmentUpdater; // packageimport +import dwtx.jface.text.projection.Segment; // packageimport +import dwtx.jface.text.projection.ProjectionDocument; // packageimport +import dwtx.jface.text.projection.FragmentUpdater; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport +import dwtx.jface.text.projection.IMinimalMapping; // packageimport +import dwtx.jface.text.projection.Fragment; // packageimport +import dwtx.jface.text.projection.ProjectionTextStore; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.Position; + +/** + * Implementation of a child document based on + * {@link dwtx.jface.text.projection.ProjectionDocument}. This class + * exists for compatibility reasons. + *

                  + * Internal class. This class is not intended to be used by clients.

                  + * + * @since 3.0 + * @noinstantiate This class is not intended to be instantiated by clients. + * @noextend This class is not intended to be subclassed by clients. + */ +public class ChildDocument : ProjectionDocument { + + /** + * Position reflecting a visible region. The exclusive end offset of the position + * is considered being overlapping with the visible region. + */ + static private class VisibleRegion : Position { + + /** + * Creates a new visible region. + * + * @param regionOffset the offset of the region + * @param regionLength the length of the region + */ + public this(int regionOffset, int regionLength) { + super(regionOffset, regionLength); + } + + /** + * If regionOffset is the end of the visible region and the regionLength is 0, + * the regionOffset is considered overlapping with the visible region. + * + * @see dwtx.jface.text.Position#overlapsWith(int, int) + */ + public bool overlapsWith(int regionOffset, int regionLength) { + bool appending= (regionOffset is offset + length) && regionLength is 0; + return appending || super.overlapsWith(regionOffset, regionLength); + } + } + + /** + * Creates a new child document. + * + * @param masterDocument @inheritDoc + */ + public this(IDocument masterDocument) { + super(masterDocument); + } + + /** + * Returns the parent document of this child document. + * + * @return the parent document of this child document + * @see ProjectionDocument#getMasterDocument() + */ + public IDocument getParentDocument() { + return getMasterDocument(); + } + + /** + * Sets the parent document range covered by this child document to the + * given range. + * + * @param offset the offset of the range + * @param length the length of the range + * @throws BadLocationException if the given range is not valid + */ + public void setParentDocumentRange(int offset, int length) { + replaceMasterDocumentRanges(offset, length); + } + + /** + * Returns the parent document range of this child document. + * + * @return the parent document range of this child document + */ + public Position getParentDocumentRange() { + IRegion coverage= getDocumentInformationMapping().getCoverage(); + return new VisibleRegion(coverage.getOffset(), coverage.getLength()); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/projection/ChildDocumentManager.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/projection/ChildDocumentManager.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,53 @@ +/******************************************************************************* + * 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 + * 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.text.projection.ChildDocumentManager; + +import dwtx.jface.text.projection.ProjectionMapping; // packageimport +import dwtx.jface.text.projection.SegmentUpdater; // packageimport +import dwtx.jface.text.projection.Segment; // packageimport +import dwtx.jface.text.projection.ProjectionDocument; // packageimport +import dwtx.jface.text.projection.FragmentUpdater; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport +import dwtx.jface.text.projection.ChildDocument; // packageimport +import dwtx.jface.text.projection.IMinimalMapping; // packageimport +import dwtx.jface.text.projection.Fragment; // packageimport +import dwtx.jface.text.projection.ProjectionTextStore; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.IDocument; + + +/** + * Implementation of a child document manager based on + * {@link dwtx.jface.text.projection.ProjectionDocumentManager}. This + * class exists for compatibility reasons. + *

                  + * Internal class. This class is not intended to be used by clients outside + * the Platform Text framework.

                  + * + * @since 3.0 + * @noinstantiate This class is not intended to be instantiated by clients. + * @noextend This class is not intended to be subclassed by clients. + */ +public class ChildDocumentManager : ProjectionDocumentManager { + + /* + * @see dwtx.jface.text.projection.ProjectionDocumentManager#createProjectionDocument(dwtx.jface.text.IDocument) + */ + protected ProjectionDocument createProjectionDocument(IDocument master) { + return new ChildDocument(master); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/projection/Fragment.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/projection/Fragment.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,59 @@ +/******************************************************************************* + * 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 + * 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.text.projection.Fragment; + +import dwtx.jface.text.projection.ProjectionMapping; // packageimport +import dwtx.jface.text.projection.ChildDocumentManager; // packageimport +import dwtx.jface.text.projection.SegmentUpdater; // packageimport +import dwtx.jface.text.projection.Segment; // packageimport +import dwtx.jface.text.projection.ProjectionDocument; // packageimport +import dwtx.jface.text.projection.FragmentUpdater; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport +import dwtx.jface.text.projection.ChildDocument; // packageimport +import dwtx.jface.text.projection.IMinimalMapping; // packageimport +import dwtx.jface.text.projection.ProjectionTextStore; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.Position; + + +/** + * Internal class. Do not use. Only public for testing purposes. + *

                  + * A fragment is a range of the master document that has an image, the so called + * segment, in a projection document.

                  + * + * @since 3.0 + * @noinstantiate This class is not intended to be instantiated by clients. + * @noextend This class is not intended to be subclassed by clients. + */ +public class Fragment : Position { + + /** + * The corresponding segment of this fragment. + */ + public Segment segment; + + /** + * Creates a new fragment covering the given range. + * + * @param offset the offset of the fragment + * @param length the length of the fragment + */ + public this(int offset, int length) { + super(offset, length); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/projection/FragmentUpdater.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/projection/FragmentUpdater.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.projection.FragmentUpdater; + +import dwtx.jface.text.projection.ProjectionMapping; // packageimport +import dwtx.jface.text.projection.ChildDocumentManager; // packageimport +import dwtx.jface.text.projection.SegmentUpdater; // packageimport +import dwtx.jface.text.projection.Segment; // packageimport +import dwtx.jface.text.projection.ProjectionDocument; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport +import dwtx.jface.text.projection.ChildDocument; // packageimport +import dwtx.jface.text.projection.IMinimalMapping; // packageimport +import dwtx.jface.text.projection.Fragment; // packageimport +import dwtx.jface.text.projection.ProjectionTextStore; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.BadPositionCategoryException; +import dwtx.jface.text.DefaultPositionUpdater; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.Position; + + +/** + * The position updater used to adapt the fragments of a master document. If an + * insertion happens at a fragment's offset, the fragment is extended rather + * than shifted. Also, the last fragment is extended if an insert operation + * happens at the end of the fragment. + * + * @since 3.0 + */ +class FragmentUpdater : DefaultPositionUpdater { + + /** Indicates whether the position being updated represents the last fragment. */ + private bool fIsLast= false; + + /** + * Creates the fragment updater for the given category. + * + * @param fragmentCategory the position category used for managing the fragments of a document + */ + /+protected+/ this(String fragmentCategory) { + super(fragmentCategory); + } + + /* + * @see dwtx.jface.text.IPositionUpdater#update(dwtx.jface.text.DocumentEvent) + */ + public void update(DocumentEvent event) { + + try { + + Position[] category= event.getDocument().getPositions(getCategory()); + + fOffset= event.getOffset(); + fLength= event.getLength(); + fReplaceLength= (event.getText() is null ? 0 : event.getText().length()); + fDocument= event.getDocument(); + + for (int i= 0; i < category.length; i++) { + + fPosition= category[i]; + fIsLast= (i is category.length -1); + + fOriginalPosition.offset= fPosition.offset; + fOriginalPosition.length= fPosition.length; + + if (notDeleted()) + adaptToReplace(); + } + + } catch (BadPositionCategoryException x) { + // do nothing + } + } + + /* + * @see dwtx.jface.text.DefaultPositionUpdater#adaptToInsert() + */ + protected void adaptToInsert() { + int myStart= fPosition.offset; + int myEnd= Math.max(myStart, fPosition.offset + fPosition.length - (fIsLast || isAffectingReplace() ? 0 : 1)); + + if (myEnd < fOffset) + return; + + if (fLength <= 0) { + + if (myStart <= fOffset) + fPosition.length += fReplaceLength; + else + fPosition.offset += fReplaceLength; + + } else { + + if (myStart <= fOffset && fOriginalPosition.offset <= fOffset) + fPosition.length += fReplaceLength; + else + fPosition.offset += fReplaceLength; + } + } + + /** + * Returns whether this updater considers any position affected by the given document event. A + * position is affected if event {@link Position#overlapsWith(int, int) overlaps} + * with it but not if the position is only shifted. + * + * @param event the event + * @return true if there is any affected position, false otherwise + */ + public bool affectsPositions(DocumentEvent event) { + IDocument document= event.getDocument(); + try { + + int index= document.computeIndexInCategory(getCategory(), event.getOffset()); + Position[] fragments= document.getPositions(getCategory()); + + if (0 < index) { + Position fragment= fragments[index - 1]; + if (fragment.overlapsWith(event.getOffset(), event.getLength())) + return true; + if (index is fragments.length && fragment.offset + fragment.length is event.getOffset()) + return true; + } + + if (index < fragments.length) { + Position fragment= fragments[index]; + return fragment.overlapsWith(event.getOffset(), event.getLength()); + } + + } catch (BadLocationException x) { + } catch (BadPositionCategoryException x) { + } + + return false; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/projection/IMinimalMapping.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/projection/IMinimalMapping.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.projection.IMinimalMapping; + +import dwtx.jface.text.projection.ProjectionMapping; // packageimport +import dwtx.jface.text.projection.ChildDocumentManager; // packageimport +import dwtx.jface.text.projection.SegmentUpdater; // packageimport +import dwtx.jface.text.projection.Segment; // packageimport +import dwtx.jface.text.projection.ProjectionDocument; // packageimport +import dwtx.jface.text.projection.FragmentUpdater; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport +import dwtx.jface.text.projection.ChildDocument; // packageimport +import dwtx.jface.text.projection.Fragment; // packageimport +import dwtx.jface.text.projection.ProjectionTextStore; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IRegion; + + +/** + * Internal interface for defining the exact subset of + * {@link dwtx.jface.text.projection.ProjectionMapping} that the + * {@link dwtx.jface.text.projection.ProjectionTextStore} is allowed to + * access. + * + * @since 3.0 + */ +interface IMinimalMapping { + + /* + * @see dwtx.jface.text.IDocumentInformationMapping#getCoverage() + */ + IRegion getCoverage(); + + /* + * @see dwtx.jface.text.IDocumentInformationMapping#toOriginRegion(IRegion) + */ + IRegion toOriginRegion(IRegion region) ; + + /* + * @see dwtx.jface.text.IDocumentInformationMapping#toOriginOffset(int) + */ + int toOriginOffset(int offset) ; + + /* + * @see dwtx.jface.text.IDocumentInformationMappingExtension#toExactOriginRegions(IRegion) + */ + IRegion[] toExactOriginRegions(IRegion region) ; + + /* + * @see dwtx.jface.text.IDocumentInformationMappingExtension#getImageLength() + */ + int getImageLength(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/projection/ProjectionDocument.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/projection/ProjectionDocument.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,919 @@ +/******************************************************************************* + * 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 + * 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.text.projection.ProjectionDocument; + +import dwtx.jface.text.projection.ProjectionMapping; // packageimport +import dwtx.jface.text.projection.ChildDocumentManager; // packageimport +import dwtx.jface.text.projection.SegmentUpdater; // packageimport +import dwtx.jface.text.projection.Segment; // packageimport +import dwtx.jface.text.projection.FragmentUpdater; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport +import dwtx.jface.text.projection.ChildDocument; // packageimport +import dwtx.jface.text.projection.IMinimalMapping; // packageimport +import dwtx.jface.text.projection.Fragment; // packageimport +import dwtx.jface.text.projection.ProjectionTextStore; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + +import dwtx.jface.text.AbstractDocument; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.BadPositionCategoryException; +import dwtx.jface.text.DefaultLineTracker; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentExtension; +import dwtx.jface.text.IDocumentInformationMapping; +import dwtx.jface.text.IDocumentListener; +import dwtx.jface.text.ILineTracker; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextStore; +import dwtx.jface.text.Position; +import dwtx.jface.text.Region; +import dwtx.jface.text.TextUtilities; + + +/** + * A ProjectionDocument represents a projection of its master + * document. The contents of a projection document is a sequence of fragments of + * the master document, i.e. the projection document can be thought as being + * constructed from the master document by not copying the whole master document + * but omitting several ranges of the master document. + *

                  + * The projection document indirectly utilizes its master document as + * ITextStore by means of a ProjectionTextStore. + *

                  + * The content of a projection document can be changed in two ways. Either by a + * text replace applied to the master document or the projection document. Or by + * changing the projection between the master document and the projection + * document. For the latter the two methods addMasterDocumentRange + * and removeMasterDocumentRange are provided. For any + * manipulation, the projection document sends out a + * {@link dwtx.jface.text.projection.ProjectionDocumentEvent} describing + * the change. + *

                  + * Clients are not supposed to directly instantiate this class. In order to + * obtain a projection document, a + * {@link dwtx.jface.text.projection.ProjectionDocumentManager}should be + * used. This class is not intended to be subclassed outside of its origin + * package.

                  + * + * @since 3.0 + * @noinstantiate This class is not intended to be instantiated by clients. + * @noextend This class is not intended to be subclassed by clients. + */ +public class ProjectionDocument : AbstractDocument { + + + /** + * Prefix of the name of the position category used to keep track of the master + * document's fragments that correspond to the segments of the projection + * document. + */ + private const static String FRAGMENTS_CATEGORY_PREFIX= "__fragmentsCategory"; //$NON-NLS-1$ + + /** + * Name of the position category used to keep track of the project + * document's segments that correspond to the fragments of the master + * document. + */ + private const static String SEGMENTS_CATEGORY= "__segmentsCategory"; //$NON-NLS-1$ + + + /** The master document */ + private IDocument fMasterDocument; + /** The master document as document extension */ + private IDocumentExtension fMasterDocumentExtension; + /** The fragments' position category */ + private String fFragmentsCategory; + /** The segment's position category */ + private String fSegmentsCategory; + /** The document event issued by the master document */ + private DocumentEvent fMasterEvent; + /** The document event to be issued by the projection document */ + private ProjectionDocumentEvent fSlaveEvent; + /** The original document event generated by a direct manipulation of this projection document */ + private DocumentEvent fOriginalEvent; + /** Indicates whether the projection document initiated a master document update or not */ + private bool fIsUpdating= false; + /** Indicated whether the projection document is in auto expand mode nor not */ + private bool fIsAutoExpanding= false; + /** The position updater for the segments */ + private SegmentUpdater fSegmentUpdater; + /** The position updater for the fragments */ + private FragmentUpdater fFragmentsUpdater; + /** The projection mapping */ + private ProjectionMapping fMapping; + + /** + * Creates a projection document for the given master document. + * + * @param masterDocument the master document + */ + public this(IDocument masterDocument) { + super(); + + fMasterDocument= masterDocument; + if ( cast(IDocumentExtension)fMasterDocument ) + fMasterDocumentExtension= cast(IDocumentExtension) fMasterDocument; + + fSegmentsCategory= SEGMENTS_CATEGORY; + fFragmentsCategory= FRAGMENTS_CATEGORY_PREFIX ~ Integer.toString(toHash()); + fMasterDocument.addPositionCategory(fFragmentsCategory); + fFragmentsUpdater= new FragmentUpdater(fFragmentsCategory); + fMasterDocument.addPositionUpdater(fFragmentsUpdater); + + fMapping= new ProjectionMapping(masterDocument, fFragmentsCategory, this, fSegmentsCategory); + + ITextStore s= new ProjectionTextStore(masterDocument, fMapping); + ILineTracker tracker= new DefaultLineTracker(); + + setTextStore(s); + setLineTracker(tracker); + + completeInitialization(); + + initializeProjection(); + tracker.set(s.get(0, s.getLength())); + } + + /** + * Disposes this projection document. + */ + public void dispose() { + fMasterDocument.removePositionUpdater(fFragmentsUpdater); + try { + fMasterDocument.removePositionCategory(fFragmentsCategory); + } catch (BadPositionCategoryException x) { + // allow multiple dispose calls + } + } + + private void internalError() { + throw new IllegalStateException(); + } + + /** + * Returns the fragments of the master documents. + * + * @return the fragment of the master document + */ + protected final Position[] getFragments() { + try { + return fMasterDocument.getPositions(fFragmentsCategory); + } catch (BadPositionCategoryException e) { + internalError(); + } + // unreachable + return null; + } + + /** + * Returns the segments of this projection document. + * + * @return the segments of this projection document + */ + protected final Position[] getSegments() { + try { + return getPositions(fSegmentsCategory); + } catch (BadPositionCategoryException e) { + internalError(); + } + // unreachable + return null; + } + + /** + * Returns the projection mapping used by this document. + * + * @return the projection mapping used by this document + * @deprecated As of 3.4, replaced by {@link #getDocumentInformationMapping()} + */ + public ProjectionMapping getProjectionMapping(){ + return fMapping; + } + + /** + * Returns the projection mapping used by this document. + * + * @return the projection mapping used by this document + * @since 3.4 + */ + public IDocumentInformationMapping getDocumentInformationMapping() { + return fMapping; + } + + /** + * Returns the master document of this projection document. + * + * @return the master document of this projection document + */ + public IDocument getMasterDocument() { + return fMasterDocument; + } + + /* + * @see dwtx.jface.text.IDocumentExtension4#getDefaultLineDelimiter() + * @since 3.1 + */ + public String getDefaultLineDelimiter() { + return TextUtilities.getDefaultLineDelimiter(fMasterDocument); + } + + /** + * Initializes the projection document from the master document based on + * the master's fragments. + */ + private void initializeProjection() { + + try { + + addPositionCategory(fSegmentsCategory); + fSegmentUpdater= new SegmentUpdater(fSegmentsCategory); + addPositionUpdater(fSegmentUpdater); + + int offset= 0; + Position[] fragments= getFragments(); + for (int i= 0; i < fragments.length; i++) { + Fragment fragment= cast(Fragment) fragments[i]; + Segment segment= new Segment(offset, fragment.getLength()); + segment.fragment= fragment; + addPosition(fSegmentsCategory, segment); + offset += fragment.length; + } + + } catch (BadPositionCategoryException x) { + internalError(); + } catch (BadLocationException x) { + internalError(); + } + } + + /** + * Creates a segment for the given fragment at the given position inside the list of segments. + * + * @param fragment the corresponding fragment + * @param index the index in the list of segments + * @return the created segment + * @throws BadLocationException in case the fragment is invalid + * @throws BadPositionCategoryException in case the segment category is invalid + */ + private Segment createSegmentFor(Fragment fragment, int index) { + + int offset= 0; + if (index > 0) { + Position[] segments= getSegments(); + Segment segment= cast(Segment) segments[index - 1]; + offset= segment.getOffset() + segment.getLength(); + } + + Segment segment= new Segment(offset, 0); + segment.fragment= fragment; + fragment.segment= segment; + addPosition(fSegmentsCategory, segment); + return segment; + } + + /** + * Adds the given range of the master document to this projection document. + * + * @param offsetInMaster offset of the master document range + * @param lengthInMaster length of the master document range + * @param masterDocumentEvent the master document event that causes this + * projection change or null if none + * @throws BadLocationException if the given range is invalid in the master + * document + */ + private void internalAddMasterDocumentRange(int offsetInMaster, int lengthInMaster, DocumentEvent masterDocumentEvent) { + if (lengthInMaster is 0) + return; + + try { + + Position[] fragments= getFragments(); + int index= fMasterDocument.computeIndexInCategory(fFragmentsCategory, offsetInMaster); + + Fragment left= null; + Fragment right= null; + + if (index < fragments.length) { + Fragment fragment= cast(Fragment) fragments[index]; + if (offsetInMaster is fragment.offset) + if (fragment.length is 0) // the fragment does not overlap - it is a zero-length fragment at the same offset + left= fragment; + else + throw new IllegalArgumentException("overlaps with existing fragment"); //$NON-NLS-1$ + if (offsetInMaster + lengthInMaster is fragment.offset) + right= fragment; + } + + if (0 < index && index <= fragments.length) { + Fragment fragment= cast(Fragment) fragments[index - 1]; + if (fragment.includes(offsetInMaster)) + throw new IllegalArgumentException("overlaps with existing fragment"); //$NON-NLS-1$ + if (fragment.getOffset() + fragment.getLength() is offsetInMaster) + left= fragment; + } + + int offsetInSlave= 0; + if (index > 0) { + Fragment fragment= cast(Fragment) fragments[index - 1]; + Segment segment= fragment.segment; + offsetInSlave= segment.getOffset() + segment.getLength(); + } + + ProjectionDocumentEvent event= new ProjectionDocumentEvent(this, offsetInSlave, 0, fMasterDocument.get(offsetInMaster, lengthInMaster), offsetInMaster, lengthInMaster, masterDocumentEvent); + super.fireDocumentAboutToBeChanged(event); + + // check for neighboring fragment + if (left !is null && right !is null) { + + int endOffset= right.getOffset() + right.getLength(); + left.setLength(endOffset - left.getOffset()); + left.segment.setLength(left.segment.getLength() + right.segment.getLength()); + + removePosition(fSegmentsCategory, right.segment); + fMasterDocument.removePosition(fFragmentsCategory, right); + + } else if (left !is null) { + int endOffset= offsetInMaster +lengthInMaster; + left.setLength(endOffset - left.getOffset()); + left.segment.markForStretch(); + + } else if (right !is null) { + right.setOffset(right.getOffset() - lengthInMaster); + right.setLength(right.getLength() + lengthInMaster); + right.segment.markForStretch(); + + } else { + // create a new segment + Fragment fragment= new Fragment(offsetInMaster, lengthInMaster); + fMasterDocument.addPosition(fFragmentsCategory, fragment); + Segment segment= createSegmentFor(fragment, index); + segment.markForStretch(); + } + + getTracker().replace(event.getOffset(), event.getLength(), event.getText()); + super.fireDocumentChanged(event); + + } catch (BadPositionCategoryException x) { + internalError(); + } + } + + /** + * Finds the fragment of the master document that represents the given range. + * + * @param offsetInMaster the offset of the range in the master document + * @param lengthInMaster the length of the range in the master document + * @return the fragment representing the given master document range + */ + private Fragment findFragment(int offsetInMaster, int lengthInMaster) { + Position[] fragments= getFragments(); + for (int i= 0; i < fragments.length; i++) { + Fragment f= cast(Fragment) fragments[i]; + if (f.getOffset() <= offsetInMaster && offsetInMaster + lengthInMaster <= f.getOffset() + f.getLength()) + return f; + } + return null; + } + + /** + * Removes the given range of the master document from this projection + * document. + * + * @param offsetInMaster the offset of the range in the master document + * @param lengthInMaster the length of the range in the master document + * + * @throws BadLocationException if the given range is not valid in the + * master document + * @throws IllegalArgumentException if the given range is not projected in + * this projection document or is not completely comprised by + * an existing fragment + */ + private void internalRemoveMasterDocumentRange(int offsetInMaster, int lengthInMaster) { + try { + + IRegion imageRegion= fMapping.toExactImageRegion(new Region(offsetInMaster, lengthInMaster)); + if (imageRegion is null) + throw new IllegalArgumentException(null); + + Fragment fragment= findFragment(offsetInMaster, lengthInMaster); + if (fragment is null) + throw new IllegalArgumentException(null); + + ProjectionDocumentEvent event= new ProjectionDocumentEvent(this, imageRegion.getOffset(), imageRegion.getLength(), "", offsetInMaster, lengthInMaster); //$NON-NLS-1$ + super.fireDocumentAboutToBeChanged(event); + + if (fragment.getOffset() is offsetInMaster) { + fragment.setOffset(offsetInMaster + lengthInMaster); + fragment.setLength(fragment.getLength() - lengthInMaster); + } else if (fragment.getOffset() + fragment.getLength() is offsetInMaster + lengthInMaster) { + fragment.setLength(fragment.getLength() - lengthInMaster); + } else { + // split fragment into three fragments, let position updater remove it + + // add fragment for the region to be removed + Fragment newFragment= new Fragment(offsetInMaster, lengthInMaster); + Segment segment= new Segment(imageRegion.getOffset(), imageRegion.getLength()); + newFragment.segment= segment; + segment.fragment= newFragment; + fMasterDocument.addPosition(fFragmentsCategory, newFragment); + addPosition(fSegmentsCategory, segment); + + // add fragment for the remainder right of the deleted range in the original fragment + int offset= offsetInMaster + lengthInMaster; + newFragment= new Fragment(offset, fragment.getOffset() + fragment.getLength() - offset); + offset= imageRegion.getOffset() + imageRegion.getLength(); + segment= new Segment(offset, fragment.segment.getOffset() + fragment.segment.getLength() - offset); + newFragment.segment= segment; + segment.fragment= newFragment; + fMasterDocument.addPosition(fFragmentsCategory, newFragment); + addPosition(fSegmentsCategory, segment); + + // adjust length of initial fragment (the left one) + fragment.setLength(offsetInMaster - fragment.getOffset()); + fragment.segment.setLength(imageRegion.getOffset() - fragment.segment.getOffset()); + } + + getTracker().replace(event.getOffset(), event.getLength(), event.getText()); + super.fireDocumentChanged(event); + + } catch (BadPositionCategoryException x) { + internalError(); + } + } + + /** + * Returns the sequence of all master document regions which are contained + * in the given master document range and which are not yet part of this + * projection document. + * + * @param offsetInMaster the range offset in the master document + * @param lengthInMaster the range length in the master document + * @return the sequence of regions which are not yet part of the projection + * document + * @throws BadLocationException in case the given range is invalid in the + * master document + */ + public final IRegion[] computeUnprojectedMasterRegions(int offsetInMaster, int lengthInMaster) { + + IRegion[] fragments= null; + IRegion imageRegion= fMapping.toImageRegion(new Region(offsetInMaster, lengthInMaster)); + if (imageRegion !is null) + fragments= fMapping.toExactOriginRegions(imageRegion); + + if (fragments is null || fragments.length is 0) + return [ new Region(offsetInMaster, lengthInMaster) ]; + + List gaps= new ArrayList(); + + IRegion region= fragments[0]; + if (offsetInMaster < region.getOffset()) + gaps.add(new Region(offsetInMaster, region.getOffset() - offsetInMaster)); + + for (int i= 0; i < fragments.length - 1; i++) { + IRegion left= fragments[i]; + IRegion right= fragments[i + 1]; + int leftEnd= left.getOffset() + left.getLength(); + if (leftEnd < right.getOffset()) + gaps.add(new Region(leftEnd, right.getOffset() - leftEnd)); + } + + region= fragments[fragments.length - 1]; + int leftEnd= region.getOffset() + region.getLength(); + int rightEnd= offsetInMaster + lengthInMaster; + if (leftEnd < rightEnd) + gaps.add(new Region(leftEnd, rightEnd - leftEnd)); + + return arraycast!(IRegion)(gaps.toArray()); + } + + /** + * Returns the first master document region which is contained in the given + * master document range and which is not yet part of this projection + * document. + * + * @param offsetInMaster the range offset in the master document + * @param lengthInMaster the range length in the master document + * @return the first region that is not yet part of the projection document + * @throws BadLocationException in case the given range is invalid in the + * master document + * @since 3.1 + */ + private IRegion computeFirstUnprojectedMasterRegion(int offsetInMaster, int lengthInMaster) { + + IRegion[] fragments= null; + IRegion imageRegion= fMapping.toImageRegion(new Region(offsetInMaster, lengthInMaster)); + if (imageRegion !is null) + fragments= fMapping.toExactOriginRegions(imageRegion); + + if (fragments is null || fragments.length is 0) + return new Region(offsetInMaster, lengthInMaster); + + IRegion region= fragments[0]; + if (offsetInMaster < region.getOffset()) + return new Region(offsetInMaster, region.getOffset() - offsetInMaster); + + for (int i= 0; i < fragments.length - 1; i++) { + IRegion left= fragments[i]; + IRegion right= fragments[i + 1]; + int leftEnd= left.getOffset() + left.getLength(); + if (leftEnd < right.getOffset()) + return new Region(leftEnd, right.getOffset() - leftEnd); + } + + region= fragments[fragments.length - 1]; + int leftEnd= region.getOffset() + region.getLength(); + int rightEnd= offsetInMaster + lengthInMaster; + if (leftEnd < rightEnd) + return new Region(leftEnd, rightEnd - leftEnd); + + return null; + } + + /** + * Ensures that the given range of the master document is part of this + * projection document. + * + * @param offsetInMaster the offset of the master document range + * @param lengthInMaster the length of the master document range + * @throws BadLocationException in case the master event is not valid + */ + public void addMasterDocumentRange(int offsetInMaster, int lengthInMaster) { + addMasterDocumentRange(offsetInMaster, lengthInMaster, null); + } + + /** + * Ensures that the given range of the master document is part of this + * projection document. + * + * @param offsetInMaster the offset of the master document range + * @param lengthInMaster the length of the master document range + * @param masterDocumentEvent the master document event which causes this + * projection change, or null if none + * @throws BadLocationException in case the master event is not valid + */ + private void addMasterDocumentRange(int offsetInMaster, int lengthInMaster, DocumentEvent masterDocumentEvent) { + /* + * Calling internalAddMasterDocumentRange may cause other master ranges + * to become unfolded, resulting in re-entrant calls to this method. In + * order to not add a region twice, we have to compute the next region + * to add in every iteration. + * + * To place an upper bound on the number of iterations, we use the number + * of fragments * 2 as the limit. + */ + int limit= Math.max(getFragments().length * 2, 20); + while (true) { + if (limit-- < 0) + throw new IllegalArgumentException("safety loop termination"); //$NON-NLS-1$ + + IRegion gap= computeFirstUnprojectedMasterRegion(offsetInMaster, lengthInMaster); + if (gap is null) + return; + + internalAddMasterDocumentRange(gap.getOffset(), gap.getLength(), masterDocumentEvent); + } + } + + /** + * Ensures that the given range of the master document is not part of this + * projection document. + * + * @param offsetInMaster the offset of the master document range + * @param lengthInMaster the length of the master document range + * @throws BadLocationException in case the master event is not valid + */ + public void removeMasterDocumentRange(int offsetInMaster, int lengthInMaster) { + IRegion[] fragments= computeProjectedMasterRegions(offsetInMaster, lengthInMaster); + if (fragments is null || fragments.length is 0) + return; + + for (int i= 0; i < fragments.length; i++) { + IRegion fragment= fragments[i]; + internalRemoveMasterDocumentRange(fragment.getOffset(), fragment.getLength()); + } + } + + /** + * Returns the sequence of all master document regions with are contained in the given master document + * range and which are part of this projection document. May return null if no such + * regions exist. + * + * @param offsetInMaster the range offset in the master document + * @param lengthInMaster the range length in the master document + * @return the sequence of regions which are part of the projection document or null + * @throws BadLocationException in case the given range is invalid in the master document + */ + public final IRegion[] computeProjectedMasterRegions(int offsetInMaster, int lengthInMaster) { + IRegion imageRegion= fMapping.toImageRegion(new Region(offsetInMaster, lengthInMaster)); + return imageRegion !is null ? fMapping.toExactOriginRegions(imageRegion) : null; + } + + /** + * Returns whether this projection is being updated. + * + * @return true if the document is updating + */ + protected bool isUpdating() { + return fIsUpdating; + } + + /* + * @see dwtx.jface.text.IDocument#replace(int, int, java.lang.String) + */ + public void replace(int offset, int length, String text) { + try { + fIsUpdating= true; + if (fMasterDocumentExtension !is null) + fMasterDocumentExtension.stopPostNotificationProcessing(); + + super.replace(offset, length, text); + + } finally { + fIsUpdating= false; + if (fMasterDocumentExtension !is null) + fMasterDocumentExtension.resumePostNotificationProcessing(); + } + } + + /* + * @see dwtx.jface.text.IDocument#set(java.lang.String) + */ + public void set(String text) { + try { + fIsUpdating= true; + if (fMasterDocumentExtension !is null) + fMasterDocumentExtension.stopPostNotificationProcessing(); + + super.set(text); + + } finally { + fIsUpdating= false; + if (fMasterDocumentExtension !is null) + fMasterDocumentExtension.resumePostNotificationProcessing(); + } + } + + /** + * Transforms a document event of the master document into a projection + * document based document event. + * + * @param masterEvent the master document event + * @return the slave document event + * @throws BadLocationException in case the master event is not valid + */ + private ProjectionDocumentEvent normalize(DocumentEvent masterEvent) { + if (!isUpdating()) { + IRegion imageRegion= fMapping.toExactImageRegion(new Region(masterEvent.getOffset(), masterEvent.getLength())); + if (imageRegion !is null) + return new ProjectionDocumentEvent(this, imageRegion.getOffset(), imageRegion.getLength(), masterEvent.getText(), masterEvent); + return null; + } + + ProjectionDocumentEvent event= new ProjectionDocumentEvent(this, fOriginalEvent.getOffset(), fOriginalEvent.getLength(), fOriginalEvent.getText(), masterEvent); + fOriginalEvent= null; + return event; + } + + /** + * Ensures that when the master event affects this projection document, that the whole region described by the + * event is part of this projection document. + * + * @param masterEvent the master document event + * @return true if masterEvent affects this projection document + * @throws BadLocationException in case the master event is not valid + */ + protected final bool adaptProjectionToMasterChange(DocumentEvent masterEvent) { + if (!isUpdating() && fFragmentsUpdater.affectsPositions(masterEvent) || fIsAutoExpanding && masterEvent.getLength() > 0) { + + addMasterDocumentRange(masterEvent.getOffset(), masterEvent.getLength(), masterEvent); + return true; + + } else if (fMapping.getImageLength() is 0 && masterEvent.getLength() is 0) { + + Position[] fragments= getFragments(); + if (fragments.length is 0) { + // there is no segment in this projection document, thus one must be created + // need to bypass the usual infrastructure as the new segment/fragment would be of length 0 and thus the segmentation be not well formed + try { + Fragment fragment= new Fragment(0, 0); + fMasterDocument.addPosition(fFragmentsCategory, fragment); + createSegmentFor(fragment, 0); + } catch (BadPositionCategoryException x) { + internalError(); + } + } + } + + return isUpdating(); + } + + /** + * When called, this projection document is informed about a forthcoming + * change of its master document. This projection document checks whether + * the master document change affects it and if so informs all document + * listeners. + * + * @param masterEvent the master document event + */ + public void masterDocumentAboutToBeChanged(DocumentEvent masterEvent) { + try { + + bool assertNotNull= adaptProjectionToMasterChange(masterEvent); + fSlaveEvent= normalize(masterEvent); + if (assertNotNull && fSlaveEvent is null) + internalError(); + + fMasterEvent= masterEvent; + if (fSlaveEvent !is null) + delayedFireDocumentAboutToBeChanged(); + + } catch (BadLocationException e) { + internalError(); + } + } + + /** + * When called, this projection document is informed about a change of its + * master document. If this projection document is affected it informs all + * of its document listeners. + * + * @param masterEvent the master document event + */ + public void masterDocumentChanged(DocumentEvent masterEvent) { + if ( !isUpdating() && masterEvent is fMasterEvent) { + if (fSlaveEvent !is null) { + try { + getTracker().replace(fSlaveEvent.getOffset(), fSlaveEvent.getLength(), fSlaveEvent.getText()); + fireDocumentChanged(fSlaveEvent); + } catch (BadLocationException e) { + internalError(); + } + } else if (ensureWellFormedSegmentation(masterEvent.getOffset())) + fMapping.projectionChanged(); + } + } + + /* + * @see dwtx.jface.text.AbstractDocument#fireDocumentAboutToBeChanged(dwtx.jface.text.DocumentEvent) + */ + protected void fireDocumentAboutToBeChanged(DocumentEvent event) { + fOriginalEvent= event; + // delay it until there is a notification from the master document + // at this point, it is expensive to construct the master document information + } + + /** + * Fires the slave document event as about-to-be-changed event to all registered listeners. + */ + private void delayedFireDocumentAboutToBeChanged() { + super.fireDocumentAboutToBeChanged(fSlaveEvent); + } + + /** + * Ignores the given event and sends the semantically equal slave document event instead. + * + * @param event the event to be ignored + */ + protected void fireDocumentChanged(DocumentEvent event) { + super.fireDocumentChanged(fSlaveEvent); + } + + /* + * @see dwtx.jface.text.AbstractDocument#updateDocumentStructures(dwtx.jface.text.DocumentEvent) + */ + protected void updateDocumentStructures(DocumentEvent event) { + super.updateDocumentStructures(event); + ensureWellFormedSegmentation(computeAnchor(event)); + fMapping.projectionChanged(); + } + + private int computeAnchor(DocumentEvent event) { + if ( cast(ProjectionDocumentEvent)event ) { + ProjectionDocumentEvent slave= cast(ProjectionDocumentEvent) event; + Object changeType= slave.getChangeType(); + if (ProjectionDocumentEvent.CONTENT_CHANGE is changeType) { + DocumentEvent master= slave.getMasterEvent(); + if (master !is null) + return master.getOffset(); + } else if (ProjectionDocumentEvent.PROJECTION_CHANGE is changeType) { + return slave.getMasterOffset(); + } + } + return -1; + } + + private bool ensureWellFormedSegmentation(int anchorOffset) { + bool changed= false; + Position[] segments= getSegments(); + for (int i= 0; i < segments.length; i++) { + Segment segment= cast(Segment) segments[i]; + if (segment.isDeleted() || segment.getLength() is 0) { + try { + removePosition(fSegmentsCategory, segment); + fMasterDocument.removePosition(fFragmentsCategory, segment.fragment); + changed= true; + } catch (BadPositionCategoryException e) { + internalError(); + } + } else if (i < segments.length - 1) { + Segment next= cast(Segment) segments[i + 1]; + if (next.isDeleted() || next.getLength() is 0) + continue; + Fragment fragment= segment.fragment; + if (fragment.getOffset() + fragment.getLength() is next.fragment.getOffset()) { + // join fragments and their corresponding segments + segment.setLength(segment.getLength() + next.getLength()); + fragment.setLength(fragment.getLength() + next.fragment.getLength()); + next.delete_(); + } + } + } + + if (changed && anchorOffset !is -1) { + Position[] changedSegments= getSegments(); + if (changedSegments is null || changedSegments.length is 0) { + Fragment fragment= new Fragment(anchorOffset, 0); + try { + fMasterDocument.addPosition(fFragmentsCategory, fragment); + createSegmentFor(fragment, 0); + } catch (BadLocationException e) { + internalError(); + } catch (BadPositionCategoryException e) { + internalError(); + } + } + } + + return changed; + } + + /* + * @see IDocumentExtension#registerPostNotificationReplace(IDocumentListener, IDocumentExtension.IReplace) + */ + public void registerPostNotificationReplace(IDocumentListener owner, IDocumentExtension.IReplace replace) { + if (!isUpdating()) + throw new UnsupportedOperationException(); + super.registerPostNotificationReplace(owner, replace); + } + + /** + * Sets the auto expand mode for this document. + * + * @param autoExpandMode true if auto-expanding + */ + public void setAutoExpandMode(bool autoExpandMode) { + fIsAutoExpanding= autoExpandMode; + } + + /** + * Replaces all master document ranges with the given master document range. + * + * @param offsetInMaster the offset in the master document + * @param lengthInMaster the length in the master document + * @throws BadLocationException if the given range of the master document is not valid + */ + public void replaceMasterDocumentRanges(int offsetInMaster, int lengthInMaster) { + try { + + ProjectionDocumentEvent event= new ProjectionDocumentEvent(this, 0, fMapping.getImageLength(), fMasterDocument.get(offsetInMaster, lengthInMaster), offsetInMaster, lengthInMaster); + super.fireDocumentAboutToBeChanged(event); + + Position[] fragments= getFragments(); + for (int i= 0; i < fragments.length; i++) { + Fragment fragment= cast(Fragment) fragments[i]; + fMasterDocument.removePosition(fFragmentsCategory, fragment); + removePosition(fSegmentsCategory, fragment.segment); + } + + Fragment fragment= new Fragment(offsetInMaster, lengthInMaster); + Segment segment= new Segment(0, 0); + segment.fragment= fragment; + fragment.segment= segment; + fMasterDocument.addPosition(fFragmentsCategory, fragment); + addPosition(fSegmentsCategory, segment); + + getTracker().set(fMasterDocument.get(offsetInMaster, lengthInMaster)); + super.fireDocumentChanged(event); + + } catch (BadPositionCategoryException x) { + internalError(); + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/projection/ProjectionDocumentEvent.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/projection/ProjectionDocumentEvent.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,175 @@ +/******************************************************************************* + * 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 + * 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.text.projection.ProjectionDocumentEvent; + +import dwtx.jface.text.projection.ProjectionMapping; // packageimport +import dwtx.jface.text.projection.ChildDocumentManager; // packageimport +import dwtx.jface.text.projection.SegmentUpdater; // packageimport +import dwtx.jface.text.projection.Segment; // packageimport +import dwtx.jface.text.projection.ProjectionDocument; // packageimport +import dwtx.jface.text.projection.FragmentUpdater; // packageimport +import dwtx.jface.text.projection.ChildDocument; // packageimport +import dwtx.jface.text.projection.IMinimalMapping; // packageimport +import dwtx.jface.text.projection.Fragment; // packageimport +import dwtx.jface.text.projection.ProjectionTextStore; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.SlaveDocumentEvent; + + +/** + * This event is sent out by an + * {@link dwtx.jface.text.projection.ProjectionDocument}when it is + * manipulated. The manipulation is either a content manipulation or a change of + * the projection between the master and the slave. Clients can determine the + * type of change by asking the projection document event for its change type + * (see {@link #getChangeType()}) and comparing it with the predefined types + * {@link #PROJECTION_CHANGE}and {@link #CONTENT_CHANGE}. + *

                  + * Clients are not supposed to create instances of this class. Instances are + * created by {@link dwtx.jface.text.projection.ProjectionDocument} + * instances. This class is not intended to be subclassed.

                  + * + * @since 3.0 + * @noinstantiate This class is not intended to be instantiated by clients. + * @noextend This class is not intended to be subclassed by clients. + */ +public class ProjectionDocumentEvent : SlaveDocumentEvent { + + /** The change type indicating a projection change */ + private static Object PROJECTION_CHANGE_; + public static Object PROJECTION_CHANGE(){ + if( PROJECTION_CHANGE_ is null ) { + synchronized( ProjectionDocumentEvent.classinfo ) { + if( PROJECTION_CHANGE_ is null ) { + PROJECTION_CHANGE_ = new Object(); + } + } + } + return PROJECTION_CHANGE_; + } + /** The change type indicating a content change */ + private static Object CONTENT_CHANGE_; + public static Object CONTENT_CHANGE(){ + if( CONTENT_CHANGE_ is null ) { + synchronized( ProjectionDocumentEvent.classinfo ) { + if( CONTENT_CHANGE_ is null ) { + CONTENT_CHANGE_ = new Object(); + } + } + } + return CONTENT_CHANGE_; + } + + /** The change type */ + private Object fChangeType; + /** The offset of the change in the master document */ + private int fMasterOffset= -1; + /** The length of the change in the master document */ + private int fMasterLength= -1; + + /** + * Creates a new content change event caused by the given master document + * change. Instances created using this constructor return -1 + * when calling getMasterOffset or + * getMasterLength. This information can be obtained by + * accessing the master event. + * + * @param doc the changed projection document + * @param offset the offset in the projection document + * @param length the length in the projection document + * @param text the replacement text + * @param masterEvent the original master event + */ + public this(IDocument doc, int offset, int length, String text, DocumentEvent masterEvent) { + super(doc, offset, length, text, masterEvent); + fChangeType= CONTENT_CHANGE; + } + + /** + * Creates a new projection change event for the given properties. Instances + * created with this constructor return the given master document offset and + * length but do not have an associated master document event. + * + * @param doc the projection document + * @param offset the offset in the projection document + * @param length the length in the projection document + * @param text the replacement text + * @param masterOffset the offset in the master document + * @param masterLength the length in the master document + */ + public this(IDocument doc, int offset, int length, String text, int masterOffset, int masterLength) { + super(doc, offset, length, text, null); + fChangeType= PROJECTION_CHANGE; + fMasterOffset= masterOffset; + fMasterLength= masterLength; + } + + /** + * Creates a new projection document event for the given properties. The + * projection change is caused by a manipulation of the master document. In + * order to accommodate the master document change, the projection document + * had to change the projection. Instances created with this constructor + * return the given master document offset and length and also have an + * associated master document event. + * + * @param doc the projection document + * @param offset the offset in the projection document + * @param length the length in the projection document + * @param text the replacement text + * @param masterOffset the offset in the master document + * @param masterLength the length in the master document + * @param masterEvent the master document event + */ + public this(IDocument doc, int offset, int length, String text, int masterOffset, int masterLength, DocumentEvent masterEvent) { + super(doc, offset, length, text, masterEvent); + fChangeType= PROJECTION_CHANGE; + fMasterOffset= masterOffset; + fMasterLength= masterLength; + } + + /** + * Returns the change type of this event. This is either {@link #PROJECTION_CHANGE} or + * {@link #CONTENT_CHANGE}. + * + * @return the change type of this event + */ + public Object getChangeType() { + return fChangeType; + } + + /** + * Returns the offset of the master document range that has been added or removed in case this + * event describes a projection change, otherwise it returns -1. + * + * @return the master document offset of the projection change or -1 + */ + public int getMasterOffset() { + return fMasterOffset; + } + + /** + * Returns the length of the master document range that has been added or removed in case this event + * describes a projection changed, otherwise -1. + * + * @return the master document length of the projection change or -1 + */ + public int getMasterLength() { + return fMasterLength; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/projection/ProjectionDocumentManager.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/projection/ProjectionDocumentManager.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,242 @@ +/******************************************************************************* + * 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 + * 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.text.projection.ProjectionDocumentManager; + +import dwtx.jface.text.projection.ProjectionMapping; // packageimport +import dwtx.jface.text.projection.ChildDocumentManager; // packageimport +import dwtx.jface.text.projection.SegmentUpdater; // packageimport +import dwtx.jface.text.projection.Segment; // packageimport +import dwtx.jface.text.projection.ProjectionDocument; // packageimport +import dwtx.jface.text.projection.FragmentUpdater; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport +import dwtx.jface.text.projection.ChildDocument; // packageimport +import dwtx.jface.text.projection.IMinimalMapping; // packageimport +import dwtx.jface.text.projection.Fragment; // packageimport +import dwtx.jface.text.projection.ProjectionTextStore; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + + + +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentInformationMapping; +import dwtx.jface.text.IDocumentListener; +import dwtx.jface.text.ISlaveDocumentManager; +import dwtx.jface.text.ISlaveDocumentManagerExtension; + + +/** + * A ProjectionDocumentManager is one particular implementation + * of {@link dwtx.jface.text.ISlaveDocumentManager}. This manager + * creates so called projection documents (see + * {@link dwtx.jface.text.projection.ProjectionDocument}as slave + * documents for given master documents. + *

                  + * A projection document represents a particular projection of the master + * document and is accordingly adapted to changes of the master document. Vice + * versa, the master document is accordingly adapted to changes of its slave + * documents. The manager does not maintain any particular management structure + * but utilizes mechanisms given by {@link dwtx.jface.text.IDocument} + * such as position categories and position updaters. + *

                  + * Clients can instantiate this class. This class is not intended to be + * subclassed.

                  + * + * @since 3.0 + * @noextend This class is not intended to be subclassed by clients. + */ +public class ProjectionDocumentManager : IDocumentListener, ISlaveDocumentManager, ISlaveDocumentManagerExtension { + + /** Registry for master documents and their projection documents. */ + private Map fProjectionRegistry; + + this(){ + fProjectionRegistry= new HashMap(); + } + + /** + * Registers the given projection document for the given master document. + * + * @param master the master document + * @param projection the projection document + */ + private void add(IDocument master, ProjectionDocument projection) { + List list= cast(List) fProjectionRegistry.get(cast(Object)master); + if (list is null) { + list= new ArrayList(1); + fProjectionRegistry.put(cast(Object)master, cast(Object)list); + } + list.add(projection); + } + + /** + * Unregisters the given projection document from its master. + * + * @param master the master document + * @param projection the projection document + */ + private void remove(IDocument master, ProjectionDocument projection) { + List list= cast(List) fProjectionRegistry.get(cast(Object)master); + if (list !is null) { + list.remove(projection); + if (list.size() is 0) + fProjectionRegistry.remove(cast(Object)master); + } + } + + /** + * Returns whether the given document is a master document. + * + * @param master the document + * @return true if the given document is a master document known to this manager + */ + private bool hasProjection(IDocument master) { + return ( null !is cast(List)fProjectionRegistry.get(cast(Object)master) ); + } + + /** + * Returns an iterator enumerating all projection documents registered for the given document or + * null if the document is not a known master document. + * + * @param master the document + * @return an iterator for all registered projection documents or null + */ + private Iterator getProjectionsIterator(IDocument master) { + List list= cast(List) fProjectionRegistry.get(cast(Object)master); + if (list !is null) + return list.iterator(); + return null; + } + + /** + * Informs all projection documents of the master document that issued the given document event. + * + * @param about indicates whether the change is about to happen or happened already + * @param masterEvent the document event which will be processed to inform the projection documents + */ + protected void fireDocumentEvent(bool about, DocumentEvent masterEvent) { + IDocument master= masterEvent.getDocument(); + Iterator e= getProjectionsIterator(master); + if (e is null) + return; + + while (e.hasNext()) { + ProjectionDocument document= cast(ProjectionDocument) e.next(); + if (about) + document.masterDocumentAboutToBeChanged(masterEvent); + else + document.masterDocumentChanged(masterEvent); + } + } + + /* + * @see dwtx.jface.text.IDocumentListener#documentChanged(dwtx.jface.text.DocumentEvent) + */ + public void documentChanged(DocumentEvent event) { + fireDocumentEvent(false, event); + } + + /* + * @see dwtx.jface.text.IDocumentListener#documentAboutToBeChanged(dwtx.jface.text.DocumentEvent) + */ + public void documentAboutToBeChanged(DocumentEvent event) { + fireDocumentEvent(true, event); + } + + /* + * @see dwtx.jface.text.ISlaveDocumentManager#createMasterSlaveMapping(dwtx.jface.text.IDocument) + */ + public IDocumentInformationMapping createMasterSlaveMapping(IDocument slave) { + if ( cast(ProjectionDocument)slave ) { + ProjectionDocument projectionDocument= cast(ProjectionDocument) slave; + return projectionDocument.getDocumentInformationMapping(); + } + return null; + } + + /* + * @see dwtx.jface.text.ISlaveDocumentManager#createSlaveDocument(dwtx.jface.text.IDocument) + */ + public IDocument createSlaveDocument(IDocument master) { + if (!hasProjection(master)) + master.addDocumentListener(this); + ProjectionDocument slave= createProjectionDocument(master); + add(master, slave); + return slave; + } + + /** + * Factory method for projection documents. + * + * @param master the master document + * @return the newly created projection document + */ + protected ProjectionDocument createProjectionDocument(IDocument master) { + return new ProjectionDocument(master); + } + + /* + * @see dwtx.jface.text.ISlaveDocumentManager#freeSlaveDocument(dwtx.jface.text.IDocument) + */ + public void freeSlaveDocument(IDocument slave) { + if ( cast(ProjectionDocument)slave ) { + ProjectionDocument projectionDocument= cast(ProjectionDocument) slave; + IDocument master= projectionDocument.getMasterDocument(); + remove(master, projectionDocument); + projectionDocument.dispose(); + if (!hasProjection(master)) + master.removeDocumentListener(this); + } + } + + /* + * @see dwtx.jface.text.ISlaveDocumentManager#getMasterDocument(dwtx.jface.text.IDocument) + */ + public IDocument getMasterDocument(IDocument slave) { + if ( cast(ProjectionDocument)slave ) + return (cast(ProjectionDocument) slave).getMasterDocument(); + return null; + } + + /* + * @see dwtx.jface.text.ISlaveDocumentManager#isSlaveDocument(dwtx.jface.text.IDocument) + */ + public bool isSlaveDocument(IDocument document) { + return ( null !is cast(ProjectionDocument)document ); + } + + /* + * @see dwtx.jface.text.ISlaveDocumentManager#setAutoExpandMode(dwtx.jface.text.IDocument, bool) + */ + public void setAutoExpandMode(IDocument slave, bool autoExpanding) { + if ( cast(ProjectionDocument)slave ) + (cast(ProjectionDocument) slave).setAutoExpandMode(autoExpanding); + } + + /* + * @see dwtx.jface.text.ISlaveDocumentManagerExtension#getSlaveDocuments(dwtx.jface.text.IDocument) + */ + public IDocument[] getSlaveDocuments(IDocument master) { + List list= cast(List) fProjectionRegistry.get(cast(Object)master); + if (list !is null) { + return arraycast!(IDocument)(list.toArray()); + } + return null; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/projection/ProjectionMapping.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/projection/ProjectionMapping.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,723 @@ +/******************************************************************************* + * 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 + * 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.text.projection.ProjectionMapping; + +import dwtx.jface.text.projection.ChildDocumentManager; // packageimport +import dwtx.jface.text.projection.SegmentUpdater; // packageimport +import dwtx.jface.text.projection.Segment; // packageimport +import dwtx.jface.text.projection.ProjectionDocument; // packageimport +import dwtx.jface.text.projection.FragmentUpdater; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport +import dwtx.jface.text.projection.ChildDocument; // packageimport +import dwtx.jface.text.projection.IMinimalMapping; // packageimport +import dwtx.jface.text.projection.Fragment; // packageimport +import dwtx.jface.text.projection.ProjectionTextStore; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.BadPositionCategoryException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentInformationMapping; +import dwtx.jface.text.IDocumentInformationMappingExtension; +import dwtx.jface.text.IDocumentInformationMappingExtension2; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.Position; +import dwtx.jface.text.Region; + + +/** + * Internal class. Do not use. Only public for testing purposes. + *

                  + * Implementation of {@link dwtx.jface.text.IDocumentInformationMapping} + * for the projection mapping between a master and a slave document. + * + * @since 3.0 + * @noinstantiate This class is not intended to be instantiated by clients. + * @noextend This class is not intended to be subclassed by clients. + */ +public class ProjectionMapping : IDocumentInformationMapping , IDocumentInformationMappingExtension, IDocumentInformationMappingExtension2, IMinimalMapping { + + private static const int LEFT= -1; + private static const int NONE= 0; + private static const int RIGHT= +1; + + /** The master document */ + private IDocument fMasterDocument; + /** The position category used to manage the projection fragments inside the master document */ + private String fFragmentsCategory; + /** The projection document */ + private IDocument fSlaveDocument; + /** The position category to manage the projection segments inside the slave document. */ + private String fSegmentsCategory; + /** Cached segments */ + private Position[] fCachedSegments; + /** Cached fragments */ + private Position[] fCachedFragments; + + /** + * Creates a new mapping between the given parent document and the given projection document. + * + * @param masterDocument the master document + * @param fragmentsCategory the position category of the parent document used to manage the projected regions + * @param slaveDocument the slave document + * @param segmentsCategory the position category of the projection document used to manage the fragments + */ + public this(IDocument masterDocument, String fragmentsCategory, IDocument slaveDocument, String segmentsCategory) { + fMasterDocument= masterDocument; + fFragmentsCategory= fragmentsCategory; + fSlaveDocument= slaveDocument; + fSegmentsCategory= segmentsCategory; + } + + /** + * Notifies this projection mapping that there was a projection change. + */ + public void projectionChanged() { + fCachedSegments= null; + fCachedFragments= null; + } + + private Position[] getSegments() { + if (fCachedSegments is null) { + try { + fCachedSegments= fSlaveDocument.getPositions(fSegmentsCategory); + } catch (BadPositionCategoryException e) { + return new Position[0]; + } + } + return fCachedSegments; + } + + private Position[] getFragments() { + if (fCachedFragments is null) { + try { + fCachedFragments= fMasterDocument.getPositions(fFragmentsCategory); + } catch (BadPositionCategoryException e) { + return new Position[0]; + } + } + return fCachedFragments; + } + + private int findSegmentIndex(int offset) { + Position[] segments= getSegments(); + if (segments.length is 0) { + if (offset > 0) + throw new BadLocationException(); + return -1; + } + + try { + int index= fSlaveDocument.computeIndexInCategory(fSegmentsCategory, offset); + if (index is segments.length && offset > exclusiveEnd(segments[index-1])) + throw new BadLocationException(); + + if (index < segments.length && offset is segments[index].offset) + return index; + + if (index > 0) + index--; + + return index; + + } catch (BadPositionCategoryException e) { + throw new IllegalStateException(); + } + } + + private Segment findSegment(int offset) { + + checkImageOffset(offset); + + int index= findSegmentIndex(offset); + if (index is -1) { + + Segment s= new Segment(0, 0); + Fragment f= new Fragment(0, 0); + s.fragment= f; + f.segment= s; + return s; + } + + Position[] segments= getSegments(); + return cast(Segment) segments[index]; + } + + /** + * Computes the fragment index given an origin offset. Returns the index of + * the fragment that contains offset, or -1 + * if no fragment contains offset. + *

                  + * If extensionDirection is set to RIGHT or + * LEFT, the next fragment in that direction is returned if + * there is no fragment containing offset. Note that if + * offset occurs before any fragment and + * extensionDirection is LEFT, + * -1 is also returned. The same applies for an offset after + * the last fragment and extensionDirection set to + * RIGHT. + *

                  + * + * @param offset an origin offset + * @param extensionDirection the direction in which to extend the search, or + * NONE + * @return the index of the fragment containing offset, or + * -1 + * @throws BadLocationException if the index is not valid on the master + * document + */ + private int findFragmentIndex(int offset, int extensionDirection) { + try { + + Position[] fragments= getFragments(); + if (fragments.length is 0) + return -1; + + int index= fMasterDocument.computeIndexInCategory(fFragmentsCategory, offset); + + if (index < fragments.length && offset is fragments[index].offset) + return index; + + if (0 < index && index <= fragments.length && fragments[index - 1].includes(offset)) + return index - 1; + + switch (extensionDirection) { + case LEFT: + return index - 1; + case RIGHT: + if (index < fragments.length) + return index; + } + + return -1; + + } catch (BadPositionCategoryException e) { + throw new IllegalStateException(); + } + } + + private Fragment findFragment(int offset) { + checkOriginOffset(offset); + + int index= findFragmentIndex(offset, NONE); + Position[] fragments= getFragments(); + if (index is -1) { + if (fragments.length > 0) { + Fragment last= cast(Fragment) fragments[fragments.length - 1]; + if (exclusiveEnd(last) is offset) + return last; + } + return null; + } + return cast(Fragment) fragments[index]; + } + + /** + * Returns the image region for originRegion. + * + * @param originRegion the region to get the image for + * @param exact if true, the begin and end offsets of + * originRegion must be projected, otherwise + * null is returned. If false, the + * begin and end range that is not visible is simply clipped. + * @param takeClosestImage if false, null is + * returned if originRegion is completely invisible. + * If true, the zero-length region is returned that + * "covers" the hidden origin region + * @return the image region of originRegion + * @throws BadLocationException if the region is not a valid origin region + */ + private IRegion toImageRegion(IRegion originRegion, bool exact, bool takeClosestImage) { + if (originRegion.getLength() is 0 && !takeClosestImage) { + int imageOffset= toImageOffset(originRegion.getOffset()); + return imageOffset is -1 ? null : new Region(imageOffset, 0); + } + + Fragment[] fragments= findFragments(originRegion, exact, takeClosestImage); + if (fragments is null) { + if (takeClosestImage) { + // originRegion may before the first or after the last fragment + Position[] allFragments= getFragments(); + if (allFragments.length > 0) { + // before the first + if (exclusiveEnd(originRegion) <= allFragments[0].getOffset()) + return new Region(0, 0); + // after last + Position last= allFragments[allFragments.length - 1]; + if (originRegion.getOffset() >= exclusiveEnd(last)) + return new Region(exclusiveEnd((cast(Fragment) last).segment), 0); + } + return new Region(0, 0); + } + return null; + } + + int imageOffset, exclusiveImageEndOffset; + + // translate start offset + int relative= originRegion.getOffset() - fragments[0].getOffset(); + if (relative < 0) { + Assert.isTrue(!exact); + relative= 0; + } + imageOffset= fragments[0].segment.getOffset() + relative; + + // translate end offset + relative= exclusiveEnd(originRegion) - fragments[1].getOffset(); + if (relative > fragments[1].getLength()) { + Assert.isTrue(!exact); + relative= fragments[1].getLength(); + } + exclusiveImageEndOffset= fragments[1].segment.getOffset() + relative; + + return new Region(imageOffset, exclusiveImageEndOffset - imageOffset); + } + + /** + * Returns the two fragments containing the begin and end offsets of + * originRegion. + * + * @param originRegion the region to get the fragments for + * @param exact if true, only the fragments that contain the + * begin and end offsets are returned; if false, the + * first fragment after the begin offset and the last fragment before + * the end offset are returned if the offsets are not projected + * @param takeClosestImage if true, the method will return + * fragments also if originRegion completely lies in + * an unprojected region. + * @return the two fragments containing the begin and end offset of + * originRegion, or null if these do + * not exist + * @throws BadLocationException if the region is not a valid origin region + */ + private Fragment[] findFragments(IRegion originRegion, bool exact, bool takeClosestImage) { + Position[] fragments= getFragments(); + if (fragments.length is 0) + return null; + + checkOriginRegion(originRegion); + + int startFragmentIdx= findFragmentIndex(originRegion.getOffset(), exact ? NONE : RIGHT); + if (startFragmentIdx is -1) + return null; + + int endFragmentIdx= findFragmentIndex(inclusiveEnd(originRegion), exact ? NONE : LEFT); + if (!takeClosestImage && startFragmentIdx > endFragmentIdx || endFragmentIdx is -1) + return null; + + Fragment[] result= [cast(Fragment) fragments[startFragmentIdx], cast(Fragment) fragments[endFragmentIdx]]; + return result; + } + + private IRegion createOriginStartRegion(Segment image, int offsetShift) { + return new Region(image.fragment.getOffset() + offsetShift, image.fragment.getLength() - offsetShift); + } + + private IRegion createOriginRegion(Segment image) { + return new Region(image.fragment.getOffset(), image.fragment.getLength()); + } + + private IRegion createOriginEndRegion(Segment image, int lengthReduction) { + return new Region(image.fragment.getOffset(), image.fragment.getLength() - lengthReduction); + } + + private IRegion createImageStartRegion(Fragment origin, int offsetShift) { + int shift= offsetShift > 0 ? offsetShift : 0; + return new Region(origin.segment.getOffset() + shift, origin.segment.getLength() - shift); + } + + private IRegion createImageRegion(Fragment origin) { + return new Region(origin.segment.getOffset(), origin.segment.getLength()); + } + + private IRegion createImageEndRegion(Fragment origin, int lengthReduction) { + int reduction= lengthReduction > 0 ? lengthReduction : 0; + return new Region(origin.segment.getOffset(), origin.segment.getLength() - reduction); + } + + private IRegion createOriginStartRegion(Fragment origin, int offsetShift) { + int shift= offsetShift > 0 ? offsetShift : 0; + return new Region(origin.getOffset() + shift, origin.getLength() - shift); + } + + private IRegion createOriginRegion(Fragment origin) { + return new Region(origin.getOffset(), origin.getLength()); + } + + private IRegion createOriginEndRegion(Fragment origin, int lengthReduction) { + int reduction= lengthReduction > 0 ? lengthReduction : 0; + return new Region(origin.getOffset(), origin.getLength() - reduction); + } + + private IRegion getIntersectingRegion(IRegion left, IRegion right) { + int offset= Math.max(left.getOffset(), right.getOffset()); + int exclusiveEndOffset= Math.min(exclusiveEnd(left), exclusiveEnd(right)); + if (exclusiveEndOffset < offset) + return null; + return new Region(offset, exclusiveEndOffset - offset); + } + + /* + * @see dwtx.jface.text.IDocumentInformationMapping#getCoverage() + */ + public IRegion getCoverage() { + Position[] fragments= getFragments(); + if (fragments !is null && fragments.length > 0) { + Position first=fragments[0]; + Position last= fragments[fragments.length -1]; + return new Region(first.offset, exclusiveEnd(last) - first.offset); + } + return new Region(0, 0); + } + + /* + * @see dwtx.jface.text.IDocumentInformationMapping#toOriginOffset(int) + */ + public int toOriginOffset(int imageOffset) { + Segment segment= findSegment(imageOffset); + int relative= imageOffset - segment.offset; + return segment.fragment.offset + relative; + } + + /* + * @see dwtx.jface.text.IDocumentInformationMapping#toOriginRegion(dwtx.jface.text.IRegion) + */ + public IRegion toOriginRegion(IRegion imageRegion) { + int imageOffset= imageRegion.getOffset(); + int imageLength= imageRegion.getLength(); + + if (imageLength is 0) { + if (imageOffset is 0) { + Position[] fragments= getFragments(); + if (fragments.length is 0 || (fragments.length is 1 && fragments[0].getOffset() is 0 && fragments[0].getLength() is 0)) + return new Region(0, fMasterDocument.getLength()); + } + return new Region(toOriginOffset(imageOffset), 0); + } + + int originOffset= toOriginOffset(imageOffset); + int inclusiveImageEndOffset= imageOffset + imageLength -1; + int inclusiveOriginEndOffset= toOriginOffset(inclusiveImageEndOffset); + + return new Region(originOffset, (inclusiveOriginEndOffset + 1) - originOffset); + } + + /* + * @see dwtx.jface.text.IDocumentInformationMapping#toOriginLines(int) + */ + public IRegion toOriginLines(int imageLine) { + IRegion imageRegion= fSlaveDocument.getLineInformation(imageLine); + IRegion originRegion= toOriginRegion(imageRegion); + + int originStartLine= fMasterDocument.getLineOfOffset(originRegion.getOffset()); + if (originRegion.getLength() is 0) + return new Region(originStartLine, 1); + + int originEndLine= fMasterDocument.getLineOfOffset(inclusiveEnd(originRegion)); + return new Region(originStartLine, (originEndLine + 1) - originStartLine); + } + + /* + * @see dwtx.jface.text.IDocumentInformationMapping#toOriginLine(int) + */ + public int toOriginLine(int imageLine) { + IRegion lines= toOriginLines(imageLine); + return (lines.getLength() > 1 ? -1 : lines.getOffset()); + } + + /* + * @see dwtx.jface.text.IDocumentInformationMapping#toImageOffset(int) + */ + public int toImageOffset(int originOffset) { + Fragment fragment= findFragment(originOffset); + if (fragment !is null) { + int relative= originOffset - fragment.offset; + return fragment.segment.offset + relative; + } + return -1; + } + + /* + * @see dwtx.jface.text.IDocumentInformationMappingExtension#toExactImageRegion(dwtx.jface.text.IRegion) + */ + public IRegion toExactImageRegion(IRegion originRegion) { + return toImageRegion(originRegion, true, false); + } + + /* + * @see dwtx.jface.text.IDocumentInformationMapping#toImageRegion(dwtx.jface.text.IRegion) + */ + public IRegion toImageRegion(IRegion originRegion) { + return toImageRegion(originRegion, false, false); + } + + /* + * @see dwtx.jface.text.IDocumentInformationMappingExtension2#toClosestImageRegion(dwtx.jface.text.IRegion) + * @since 3.1 + */ + public IRegion toClosestImageRegion(IRegion originRegion) { + return toImageRegion(originRegion, false, true); + } + + /* + * @see dwtx.jface.text.IDocumentInformationMapping#toImageLine(int) + */ + public int toImageLine(int originLine) { + IRegion originRegion= fMasterDocument.getLineInformation(originLine); + IRegion imageRegion= toImageRegion(originRegion); + if (imageRegion is null) { + int imageOffset= toImageOffset(originRegion.getOffset()); + if (imageOffset > -1) + imageRegion= new Region(imageOffset, 0); + else + return -1; + } + + int startLine= fSlaveDocument.getLineOfOffset(imageRegion.getOffset()); + if (imageRegion.getLength() is 0) + return startLine; + + int endLine= fSlaveDocument.getLineOfOffset(imageRegion.getOffset() + imageRegion.getLength()); + if (endLine !is startLine) + throw new IllegalStateException(); + + return startLine; + } + + /* + * @see dwtx.jface.text.IDocumentInformationMapping#toClosestImageLine(int) + */ + public int toClosestImageLine(int originLine) { + try { + + int imageLine= toImageLine(originLine); + if (imageLine > -1) + return imageLine; + + Position[] fragments= getFragments(); + if (fragments.length is 0) + return -1; + + IRegion originLineRegion= fMasterDocument.getLineInformation(originLine); + int index= fMasterDocument.computeIndexInCategory(fFragmentsCategory, originLineRegion.getOffset()); + + if (0 < index && index < fragments.length) { + Fragment left= cast(Fragment) fragments[index - 1]; + int leftDistance= originLineRegion.getOffset() - (exclusiveEnd(left)); + Fragment right= cast(Fragment) fragments[index]; + int rightDistance= right.getOffset() - (exclusiveEnd(originLineRegion)); + + if (leftDistance <= rightDistance) + originLine= fMasterDocument.getLineOfOffset(left.getOffset() + Math.max(left.getLength() - 1, 0)); + else + originLine= fMasterDocument.getLineOfOffset(right.getOffset()); + + } else if (index is 0) { + Fragment right= cast(Fragment) fragments[index]; + originLine= fMasterDocument.getLineOfOffset(right.getOffset()); + } else if (index is fragments.length) { + Fragment left= cast(Fragment) fragments[index - 1]; + originLine= fMasterDocument.getLineOfOffset(exclusiveEnd(left)); + } + + return toImageLine(originLine); + + } catch (BadPositionCategoryException x) { + } + + return -1; + } + + /* + * @see dwtx.jface.text.IDocumentInformationMappingExtension#toExactOriginRegions(dwtx.jface.text.IRegion) + */ + public IRegion[] toExactOriginRegions(IRegion imageRegion) { + + if (imageRegion.getLength() is 0) + return [ new Region(toOriginOffset(imageRegion.getOffset()), 0) ]; + + int endOffset= exclusiveEnd(imageRegion); + Position[] segments= getSegments(); + int firstIndex= findSegmentIndex(imageRegion.getOffset()); + int lastIndex= findSegmentIndex(endOffset - 1); + + int resultLength= lastIndex - firstIndex + 1; + IRegion[] result= new IRegion[resultLength]; + + // first + result[0]= createOriginStartRegion(cast(Segment) segments[firstIndex], imageRegion.getOffset() - segments[firstIndex].getOffset()); + // middles + for (int i= 1; i < resultLength - 1; i++) + result[i]= createOriginRegion(cast(Segment) segments[firstIndex + i]); + // last + Segment last= cast(Segment) segments[lastIndex]; + int segmentEndOffset= exclusiveEnd(last); + IRegion lastRegion= createOriginEndRegion(last, segmentEndOffset - endOffset); + if (resultLength > 1) { + // first !is last + result[resultLength - 1]= lastRegion; + } else { + // merge first and last + IRegion intersection= getIntersectingRegion(result[0], lastRegion); + if (intersection is null) + result= new IRegion[0]; + else + result[0]= intersection; + } + + return result; + } + + /* + * @see dwtx.jface.text.IDocumentInformationMappingExtension#getImageLength() + */ + public int getImageLength() { + Position[] segments= getSegments(); + int length= 0; + for (int i= 0; i < segments.length; i++) + length += segments[i].length; + return length; + } + + /* + * @see dwtx.jface.text.IDocumentInformationMappingExtension#toExactImageRegions(dwtx.jface.text.IRegion) + */ + public IRegion[] toExactImageRegions(IRegion originRegion) { + + int offset= originRegion.getOffset(); + if (originRegion.getLength() is 0) { + int imageOffset= toImageOffset(offset); + return imageOffset > -1 ? [ cast(IRegion) new Region(imageOffset, 0) ] : null; + } + + int endOffset= exclusiveEnd(originRegion); + Position[] fragments= getFragments(); + int firstIndex= findFragmentIndex(offset, RIGHT); + int lastIndex= findFragmentIndex(endOffset - 1, LEFT); + + if (firstIndex is -1 || firstIndex > lastIndex) + return null; + + int resultLength= lastIndex - firstIndex + 1; + IRegion[] result= new IRegion[resultLength]; + + // first + result[0]= createImageStartRegion(cast(Fragment) fragments[firstIndex], offset - fragments[firstIndex].getOffset()); + // middles + for (int i= 1; i < resultLength - 1; i++) + result[i]= createImageRegion(cast(Fragment) fragments[firstIndex + i]); + // last + Fragment last= cast(Fragment) fragments[lastIndex]; + int fragmentEndOffset= exclusiveEnd(last); + IRegion lastRegion= createImageEndRegion(last, fragmentEndOffset - endOffset); + if (resultLength > 1) { + // first !is last + result[resultLength - 1]= lastRegion; + } else { + // merge first and last + IRegion intersection= getIntersectingRegion(result[0], lastRegion); + if (intersection is null) + return null; + result[0]= intersection; + } + + return result; + } + + /* + * @see dwtx.jface.text.IDocumentInformationMappingExtension#getExactCoverage(dwtx.jface.text.IRegion) + */ + public IRegion[] getExactCoverage(IRegion originRegion) { + + int originOffset= originRegion.getOffset(); + int originLength= originRegion.getLength(); + + if (originLength is 0) { + int imageOffset= toImageOffset(originOffset); + return imageOffset > -1 ? [ cast(IRegion)new Region(originOffset, 0) ] : null; + } + + int endOffset= originOffset + originLength; + Position[] fragments= getFragments(); + int firstIndex= findFragmentIndex(originOffset, RIGHT); + int lastIndex= findFragmentIndex(endOffset - 1, LEFT); + + if (firstIndex is -1 || firstIndex > lastIndex) + return null; + + int resultLength= lastIndex - firstIndex + 1; + IRegion[] result= new IRegion[resultLength]; + + // first + result[0]= createOriginStartRegion(cast(Fragment) fragments[firstIndex], originOffset - fragments[firstIndex].getOffset()); + // middles + for (int i= 1; i < resultLength - 1; i++) + result[i]= createOriginRegion(cast(Fragment) fragments[firstIndex + i]); + // last + Fragment last= cast(Fragment) fragments[lastIndex]; + int fragmentEndOffset= exclusiveEnd(last); + IRegion lastRegion= createOriginEndRegion(last, fragmentEndOffset - endOffset); + if (resultLength > 1) { + // first !is last + result[resultLength - 1]= lastRegion; + } else { + // merge first and last + IRegion intersection= getIntersectingRegion(result[0], lastRegion); + if (intersection is null) + return null; + result[0]= intersection; + } + + return result; + } + + private final void checkOriginRegion(IRegion originRegion) { + int offset= originRegion.getOffset(); + int endOffset= inclusiveEnd(originRegion); + int max= fMasterDocument.getLength(); + if (offset < 0 || offset > max || endOffset < 0 || endOffset > max) + throw new BadLocationException(); + } + + private final void checkOriginOffset(int originOffset) { + if (originOffset < 0 || originOffset > fMasterDocument.getLength()) + throw new BadLocationException(); + } + + private final void checkImageOffset(int imageOffset) { + if (imageOffset < 0 || imageOffset > getImageLength()) + throw new BadLocationException(); + } + + private final int exclusiveEnd(Position position) { + return position.offset + position.length; + } + + private final int exclusiveEnd(IRegion region) { + return region.getOffset() + region.getLength(); + } + + private final int inclusiveEnd(IRegion region) { + int length= region.getLength(); + if (length is 0) + return region.getOffset(); + return region.getOffset() + length - 1; + } + + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/projection/ProjectionTextStore.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/projection/ProjectionTextStore.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.projection.ProjectionTextStore; + +import dwtx.jface.text.projection.ProjectionMapping; // packageimport +import dwtx.jface.text.projection.ChildDocumentManager; // packageimport +import dwtx.jface.text.projection.SegmentUpdater; // packageimport +import dwtx.jface.text.projection.Segment; // packageimport +import dwtx.jface.text.projection.ProjectionDocument; // packageimport +import dwtx.jface.text.projection.FragmentUpdater; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport +import dwtx.jface.text.projection.ChildDocument; // packageimport +import dwtx.jface.text.projection.IMinimalMapping; // packageimport +import dwtx.jface.text.projection.Fragment; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextStore; +import dwtx.jface.text.Region; + + +/** + * A text store representing the projection defined by the given document + * information mapping. + * + * @since 3.0 + */ +class ProjectionTextStore : ITextStore { + + /** + * Implementation of {@link IRegion} that can be reused + * by setting the offset and the length. + */ + private static class ReusableRegion : IRegion { + + private int fOffset; + private int fLength; + + /* + * @see dwtx.jface.text.IRegion#getLength() + */ + public int getLength() { + return fLength; + } + + /* + * @see dwtx.jface.text.IRegion#getOffset() + */ + public int getOffset() { + return fOffset; + } + + /** + * Updates this region. + * + * @param offset the new offset + * @param length the new length + */ + public void update(int offset, int length) { + fOffset= offset; + fLength= length; + } + } + + /** The master document */ + private IDocument fMasterDocument; + /** The document information mapping */ + private IMinimalMapping fMapping; + /** Internal region used for querying the mapping. */ + private ReusableRegion fReusableRegion; + + + /** + * Creates a new projection text store for the given master document and + * the given document information mapping. + * + * @param masterDocument the master document + * @param mapping the document information mapping + */ + public this(IDocument masterDocument, IMinimalMapping mapping) { + fReusableRegion= new ReusableRegion(); + fMasterDocument= masterDocument; + fMapping= mapping; + } + + private void internalError() { + throw new IllegalStateException(); + } + + /* + * @see dwtx.jface.text.ITextStore#set(java.lang.String) + */ + public void set(String contents) { + + IRegion masterRegion= fMapping.getCoverage(); + if (masterRegion is null) + internalError(); + + try { + fMasterDocument.replace(masterRegion.getOffset(), masterRegion.getLength(), contents); + } catch (BadLocationException e) { + internalError(); + } + } + + /* + * @see dwtx.jface.text.ITextStore#replace(int, int, java.lang.String) + */ + public void replace(int offset, int length, String text) { + fReusableRegion.update(offset, length); + try { + IRegion masterRegion= fMapping.toOriginRegion(fReusableRegion); + fMasterDocument.replace(masterRegion.getOffset(), masterRegion.getLength(), text); + } catch (BadLocationException e) { + internalError(); + } + } + + /* + * @see dwtx.jface.text.ITextStore#getLength() + */ + public int getLength() { + return fMapping.getImageLength(); + } + + /* + * @see dwtx.jface.text.ITextStore#get(int) + */ + public char get(int offset) { + try { + int originOffset= fMapping.toOriginOffset(offset); + return fMasterDocument.getChar(originOffset); + } catch (BadLocationException e) { + internalError(); + } + + // unreachable + return cast(wchar) 0; + } + + /* + * @see ITextStore#get(int, int) + */ + public String get(int offset, int length) { + try { + IRegion[] fragments= fMapping.toExactOriginRegions(new Region(offset, length)); + StringBuffer buffer= new StringBuffer(); + for (int i= 0; i < fragments.length; i++) { + IRegion fragment= fragments[i]; + buffer.append(fMasterDocument.get(fragment.getOffset(), fragment.getLength())); + } + return buffer.toString(); + } catch (BadLocationException e) { + internalError(); + } + + // unreachable + return null; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/projection/Segment.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/projection/Segment.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,107 @@ +/******************************************************************************* + * 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 + * 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.text.projection.Segment; + +import dwtx.jface.text.projection.ProjectionMapping; // packageimport +import dwtx.jface.text.projection.ChildDocumentManager; // packageimport +import dwtx.jface.text.projection.SegmentUpdater; // packageimport +import dwtx.jface.text.projection.ProjectionDocument; // packageimport +import dwtx.jface.text.projection.FragmentUpdater; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport +import dwtx.jface.text.projection.ChildDocument; // packageimport +import dwtx.jface.text.projection.IMinimalMapping; // packageimport +import dwtx.jface.text.projection.Fragment; // packageimport +import dwtx.jface.text.projection.ProjectionTextStore; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.Position; + + +/** + * Internal class. Do not use. Only public for testing purposes. + *

                  + * A segment is the image of a master document fragment in a projection + * document. + * + * @since 3.0 + * @noinstantiate This class is not intended to be instantiated by clients. + * @noextend This class is not intended to be subclassed by clients. + */ +public class Segment : Position { + + /** The corresponding fragment for this segment. */ + public Fragment fragment; + /** A flag indicating that the segment updater should stretch this segment when a change happens at its boundaries. */ + public bool isMarkedForStretch_; + /** A flag indicating that the segment updater should shift this segment when a change happens at its boundaries. */ + public bool isMarkedForShift_; + + /** + * Creates a new segment covering the given range. + * + * @param offset the offset of the segment + * @param length the length of the segment + */ + public this(int offset, int length) { + super(offset, length); + } + + /** + * Sets the stretching flag. + */ + public void markForStretch() { + isMarkedForStretch_= true; + } + + /** + * Returns true if the stretching flag is set, false otherwise. + * @return true if the stretching flag is set, false otherwise + */ + public bool isMarkedForStretch() { + return isMarkedForStretch_; + } + public bool isMarkedForStretch(bool v) { + isMarkedForStretch_ = v; + return isMarkedForStretch(); + } + + /** + * Sets the shifting flag. + */ + public void markForShift() { + isMarkedForShift_= true; + } + + /** + * Returns true if the shifting flag is set, false otherwise. + * @return true if the shifting flag is set, false otherwise + */ + public bool isMarkedForShift() { + return isMarkedForShift_; + } + public bool isMarkedForShift(bool v) { + isMarkedForShift_ = v; + return isMarkedForShift(); + } + + /** + * Clears the shifting and the stretching flag. + */ + public void clearMark() { + isMarkedForStretch_= false; + isMarkedForShift_= false; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/projection/SegmentUpdater.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/projection/SegmentUpdater.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,146 @@ +/******************************************************************************* + * 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 + * 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.text.projection.SegmentUpdater; + +import dwtx.jface.text.projection.ProjectionMapping; // packageimport +import dwtx.jface.text.projection.ChildDocumentManager; // packageimport +import dwtx.jface.text.projection.Segment; // packageimport +import dwtx.jface.text.projection.ProjectionDocument; // packageimport +import dwtx.jface.text.projection.FragmentUpdater; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport +import dwtx.jface.text.projection.ChildDocument; // packageimport +import dwtx.jface.text.projection.IMinimalMapping; // packageimport +import dwtx.jface.text.projection.Fragment; // packageimport +import dwtx.jface.text.projection.ProjectionTextStore; // packageimport +import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport + + +import dwt.dwthelper.utils; + + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadPositionCategoryException; +import dwtx.jface.text.DefaultPositionUpdater; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.Position; + + +/** + * The position updater used to adapt the segments of a projection document to + * changes of the master document. Depending on the flags set on a segment, a + * segment is either extended to shifted if an insertion happens at a segment's + * offset. The last segment is extended if an insert operation happens at the + * end of the segment. + * + * @since 3.0 + */ +class SegmentUpdater : DefaultPositionUpdater { + + private Segment fNextSegment= null; + private bool fIsProjectionChange= false; + + /** + * Creates the segment updater for the given category. + * + * @param segmentCategory the position category used for managing the segments of a projection document + */ + /+protected+/ this(String segmentCategory) { + super(segmentCategory); + } + + /* + * @see dwtx.jface.text.IPositionUpdater#update(dwtx.jface.text.DocumentEvent) + */ + public void update(DocumentEvent event) { + + Assert.isTrue( null !is cast(ProjectionDocumentEvent)event ); + fIsProjectionChange= (cast(ProjectionDocumentEvent) event).getChangeType() is ProjectionDocumentEvent.PROJECTION_CHANGE; + + try { + + Position[] category= event.getDocument().getPositions(getCategory()); + + fOffset= event.getOffset(); + fLength= event.getLength(); + fReplaceLength= (event.getText() is null ? 0 : event.getText().length()); + fDocument= event.getDocument(); + + for (int i= 0; i < category.length; i++) { + + fPosition= category[i]; + Assert.isTrue( null !is cast(Segment)fPosition ); + + if (i < category.length - 1) + fNextSegment= cast(Segment) category[i + 1]; + else + fNextSegment= null; + + fOriginalPosition.offset= fPosition.offset; + fOriginalPosition.length= fPosition.length; + + if (notDeleted()) + adaptToReplace(); + + } + + } catch (BadPositionCategoryException x) { + // do nothing + } + } + + /* + * @see dwtx.jface.text.DefaultPositionUpdater#adaptToInsert() + */ + protected void adaptToInsert() { + + Segment segment= cast(Segment) fPosition; + int myStart= segment.offset; + int myEnd= segment.offset + segment.length - (segment.isMarkedForStretch || fNextSegment is null || isAffectingReplace() ? 0 : 1); + myEnd= Math.max(myStart, myEnd); + int yoursStart= fOffset; + + try { + + if (myEnd < yoursStart) + return; + + if (segment.isMarkedForStretch) { + Assert.isTrue(fIsProjectionChange); + segment.isMarkedForShift= false; + if (fNextSegment !is null) { + fNextSegment.isMarkedForShift= true; + fNextSegment.isMarkedForStretch= false; + } + } + + if (fLength <= 0) { + + if (myStart < (yoursStart + (segment.isMarkedForShift ? 0 : 1))) + fPosition.length += fReplaceLength; + else + fPosition.offset += fReplaceLength; + + } else { + + if (myStart <= yoursStart && fOriginalPosition.offset <= yoursStart) + fPosition.length += fReplaceLength; + else + fPosition.offset += fReplaceLength; + } + + } finally { + segment.clearMark(); + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/quickassist/IQuickAssistAssistant.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/quickassist/IQuickAssistAssistant.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,189 @@ +/******************************************************************************* + * 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 + * 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.text.quickassist.IQuickAssistAssistant; + +import dwtx.jface.text.quickassist.QuickAssistAssistant; // packageimport +import dwtx.jface.text.quickassist.IQuickAssistAssistantExtension; // packageimport +import dwtx.jface.text.quickassist.IQuickAssistInvocationContext; // packageimport +import dwtx.jface.text.quickassist.IQuickFixableAnnotation; // packageimport +import dwtx.jface.text.quickassist.IQuickAssistProcessor; // packageimport + + +import dwt.dwthelper.utils; + + + + +import dwt.graphics.Color; +import dwtx.jface.preference.JFacePreferences; +import dwtx.jface.text.IInformationControlCreator; +import dwtx.jface.text.contentassist.ICompletionListener; +import dwtx.jface.text.source.Annotation; +import dwtx.jface.text.source.ISourceViewer; +import dwtx.jface.text.source.ISourceViewerExtension3; + + +/** + * An IQuickAssistAssistant provides support for quick fixes and quick + * assists. + * The quick assist assistant is a {@link ISourceViewer} add-on. Its + * purpose is to propose, display, and insert quick assists and quick fixes + * available at the current source viewer's quick assist invocation context. + *

                  + * The quick assist assistant can be configured with a {@link IQuickAssistProcessor} + * which provides the possible quick assist and quick fix completions. + *

                  + * In order to provide backward compatibility for clients of + * IQuickAssistAssistant, extension interfaces are used to + * provide a means of evolution. The following extension interfaces exist: + *
                    + *
                  • {@link IQuickAssistAssistantExtension} since version 3.4 introducing the + * following function: + *
                      + *
                    • allows to get a handler for the given command identifier
                    • + *
                    • allows to enable support for colored labels in the proposal popup
                    • + *
                    + *
                  • + *

                    + *

                    + * The interface can be implemented by clients. By default, clients use + * {@link QuickAssistAssistant} as the standard + * implementer of this interface. + *

                    + * + * @see ISourceViewer + * @see IQuickAssistProcessor + * @see IQuickAssistAssistantExtension + * @since 3.2 + */ + public interface IQuickAssistAssistant { + + /** + * Installs quick assist support on the given source viewer. + *

                    + * Note: This quick assist assistant will only be able to query the invocation context + * if sourceViewer also implements {@link ISourceViewerExtension3}. + *

                    + * + * @param sourceViewer the source viewer on which quick assist will work + */ + void install(ISourceViewer sourceViewer); + + /** + * Sets the information control creator for the additional information control. + * + * @param creator the information control creator for the additional information control + */ + void setInformationControlCreator(IInformationControlCreator creator); + + /** + * Uninstalls quick assist support from the source viewer it has + * previously be installed on. + */ + void uninstall(); + + /** + * Shows all possible quick fixes and quick assists at the viewer's cursor position. + * + * @return an optional error message if no proposals can be computed + */ + String showPossibleQuickAssists(); + + /** + * Registers a given quick assist processor for a particular content type. If there is already + * a processor registered, the new processor is registered instead of the old one. + * + * @param processor the quick assist processor to register, or null to remove + * an existing one + */ + void setQuickAssistProcessor(IQuickAssistProcessor processor); + + /** + * Returns the quick assist processor to be used for the given content type. + * + * @return the quick assist processor or null if none exists + */ + IQuickAssistProcessor getQuickAssistProcessor(); + + /** + * Tells whether this assistant has a fix for the given annotation. + *

                    + * Note: This test must be fast and optimistic i.e. it is OK to return + * true even though there might be no quick fix. + *

                    + * + * @param annotation the annotation + * @return true if the assistant has a fix for the given annotation + */ + bool canFix(Annotation annotation); + + /** + * Tells whether this assistant has assists for the given invocation context. + * + * @param invocationContext the invocation context + * @return true if the assistant has a fix for the given annotation + */ + bool canAssist(IQuickAssistInvocationContext invocationContext); + + /** + * Sets the proposal selector's background color. + *

                    + * Note: As of 3.4, you should only call this + * method if you want to override the {@link JFacePreferences#CONTENT_ASSIST_BACKGROUND_COLOR}. + *

                    + * + * @param background the background color + */ + void setProposalSelectorBackground(Color background); + + /** + * Sets the proposal's foreground color. + *

                    + * Note: As of 3.4, you should only call this + * method if you want to override the {@link JFacePreferences#CONTENT_ASSIST_FOREGROUND_COLOR}. + *

                    + * + * @param foreground the foreground color + */ + void setProposalSelectorForeground(Color foreground); + + /** + * Adds a completion listener that will be informed before proposals are computed. + * + * @param listener the listener + */ + void addCompletionListener(ICompletionListener listener); + + /** + * Removes a completion listener. + * + * @param listener the listener to remove + */ + void removeCompletionListener(ICompletionListener listener); + + /** + * Enables displaying a status line below the proposal popup. The default is not to show the + * status line. The contents of the status line may be set via {@link #setStatusMessage(String)}. + * + * @param show true to show a message line, false to not show one. + */ + public void setStatusLineVisible(bool show); + + /** + * Sets the caption message displayed at the bottom of the completion proposal popup. + * + * @param message the message + */ + public void setStatusMessage(String message); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/quickassist/IQuickAssistAssistantExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/quickassist/IQuickAssistAssistantExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,66 @@ +/******************************************************************************* + * 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 + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.text.quickassist.IQuickAssistAssistantExtension; + +import dwtx.jface.text.quickassist.QuickAssistAssistant; // packageimport +import dwtx.jface.text.quickassist.IQuickAssistAssistant; // packageimport +import dwtx.jface.text.quickassist.IQuickAssistInvocationContext; // packageimport +import dwtx.jface.text.quickassist.IQuickFixableAnnotation; // packageimport +import dwtx.jface.text.quickassist.IQuickAssistProcessor; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.core.commands.IHandler; +import dwtx.jface.text.contentassist.ICompletionProposalExtension6; + + +/** + * Extends {@link IQuickAssistAssistant} with the following function: + *
                      + *
                    • allows to get a handler for the given command identifier
                    • + *
                    • allows to enable support for colored labels in the proposal popup
                    • + *
                    + * + * @since 3.4 + */ +public interface IQuickAssistAssistantExtension { + + /** + * Returns the handler for the given command identifier. + *

                    + * The same handler instance will be returned when called a more than once + * with the same command identifier. + *

                    + * + * @param commandId the command identifier + * @return the handler for the given command identifier + * @throws IllegalArgumentException if the command is not supported by this + * content assistant + * @throws IllegalStateException if called when this content assistant is + * uninstalled + */ + IHandler getHandler(String commandId); + + /** + * Enables the support for colored labels in the proposal popup. + *

                    Completion proposals can implement {@link ICompletionProposalExtension6} + * to provide colored proposal labels.

                    + * + * @param isEnabled if true the support for colored labels is enabled in the proposal popup + * @since 3.4 + */ + void enableColoredLabels(bool isEnabled); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/quickassist/IQuickAssistInvocationContext.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/quickassist/IQuickAssistInvocationContext.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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 + * 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.text.quickassist.IQuickAssistInvocationContext; + +import dwtx.jface.text.quickassist.QuickAssistAssistant; // packageimport +import dwtx.jface.text.quickassist.IQuickAssistAssistant; // packageimport +import dwtx.jface.text.quickassist.IQuickAssistAssistantExtension; // packageimport +import dwtx.jface.text.quickassist.IQuickFixableAnnotation; // packageimport +import dwtx.jface.text.quickassist.IQuickAssistProcessor; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.source.ISourceViewer; + + +/** + * Context information for quick fix and quick assist processors. + *

                    + * This interface can be implemented by clients.

                    + * + * @since 3.2 + */ +public interface IQuickAssistInvocationContext { + + /** + * Returns the offset where quick assist was invoked. + * + * @return the invocation offset or -1 if unknown + */ + int getOffset(); + + /** + * Returns the length of the selection at the invocation offset. + * + * @return the length of the current selection or -1 if none or unknown + */ + int getLength(); + + /** + * Returns the viewer for this context. + * + * @return the viewer or null if not available + */ + ISourceViewer getSourceViewer(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/quickassist/IQuickAssistProcessor.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/quickassist/IQuickAssistProcessor.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,78 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.text.quickassist.IQuickAssistProcessor; + +import dwtx.jface.text.quickassist.QuickAssistAssistant; // packageimport +import dwtx.jface.text.quickassist.IQuickAssistAssistant; // packageimport +import dwtx.jface.text.quickassist.IQuickAssistAssistantExtension; // packageimport +import dwtx.jface.text.quickassist.IQuickAssistInvocationContext; // packageimport +import dwtx.jface.text.quickassist.IQuickFixableAnnotation; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.contentassist.ICompletionProposal; +import dwtx.jface.text.source.Annotation; + + +/** + * Quick assist processor for quick fixes and quick assists. + *

                    + * A processor can provide just quick fixes, just quick assists + * or both. + *

                    + *

                    + * This interface can be implemented by clients.

                    + * + * @since 3.2 + */ +public interface IQuickAssistProcessor { + + /** + * Returns the reason why this quick assist processor + * was unable to produce any completion proposals. + * + * @return an error message or null if no error occurred + */ + String getErrorMessage(); + + /** + * Tells whether this processor has a fix for the given annotation. + *

                    + * Note: This test must be fast and optimistic i.e. it is OK to return + * true even though there might be no quick fix. + *

                    + * + * @param annotation the annotation + * @return true if the assistant has a fix for the given annotation + */ + bool canFix(Annotation annotation); + + /** + * Tells whether this assistant has assists for the given invocation context. + * + * @param invocationContext the invocation context + * @return true if the assistant has a fix for the given annotation + */ + bool canAssist(IQuickAssistInvocationContext invocationContext); + + /** + * Returns a list of quick assist and quick fix proposals for the + * given invocation context. + * + * @param invocationContext the invocation context + * @return an array of completion proposals or null if no proposals are available + */ + ICompletionProposal[] computeQuickAssistProposals(IQuickAssistInvocationContext invocationContext); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/quickassist/IQuickFixableAnnotation.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/quickassist/IQuickFixableAnnotation.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,75 @@ +/******************************************************************************* + * 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 + * 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.text.quickassist.IQuickFixableAnnotation; + +import dwtx.jface.text.quickassist.QuickAssistAssistant; // packageimport +import dwtx.jface.text.quickassist.IQuickAssistAssistant; // packageimport +import dwtx.jface.text.quickassist.IQuickAssistAssistantExtension; // packageimport +import dwtx.jface.text.quickassist.IQuickAssistInvocationContext; // packageimport +import dwtx.jface.text.quickassist.IQuickAssistProcessor; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.core.runtime.AssertionFailedException; +import dwtx.jface.text.source.Annotation; + + +/** + * Allows an annotation to tell whether there are quick fixes + * for it and to cache that state. + *

                    + * Caching the state is important to improve overall performance as calling + * {@link dwtx.jface.text.quickassist.IQuickAssistAssistant#canFix(Annotation)} + * can be expensive. + *

                    + *

                    + * This interface can be implemented by clients.

                    + * + * @since 3.2 + */ +public interface IQuickFixableAnnotation { + + /** + * Sets whether there are quick fixes available for + * this annotation. + * + * @param state true if there are quick fixes available, false otherwise + */ + void setQuickFixable(bool state); + + /** + * Tells whether the quick fixable state has been set. + *

                    + * Normally this means {@link #setQuickFixable(bool)} has been + * called at least once but it can also be hard-coded, e.g. always + * return true. + *

                    + * + * @return true if the state has been set + */ + bool isQuickFixableStateSet(); + + /** + * Tells whether there are quick fixes for this annotation. + *

                    + * Note: This method must only be called + * if {@link #isQuickFixableStateSet()} returns true.

                    + * + * @return true if this annotation offers quick fixes + * @throws AssertionFailedException if called when {@link #isQuickFixableStateSet()} is false + */ + bool isQuickFixable() ; + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/quickassist/QuickAssistAssistant.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/quickassist/QuickAssistAssistant.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,270 @@ +/******************************************************************************* + * 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 + * 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.text.quickassist.QuickAssistAssistant; + +import dwtx.jface.text.quickassist.IQuickAssistAssistant; // packageimport +import dwtx.jface.text.quickassist.IQuickAssistAssistantExtension; // packageimport +import dwtx.jface.text.quickassist.IQuickAssistInvocationContext; // packageimport +import dwtx.jface.text.quickassist.IQuickFixableAnnotation; // packageimport +import dwtx.jface.text.quickassist.IQuickAssistProcessor; // packageimport + + +import dwt.dwthelper.utils; + + + + +import dwt.graphics.Color; +import dwtx.core.commands.IHandler; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IInformationControlCreator; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.contentassist.ContentAssistant; +import dwtx.jface.text.contentassist.ICompletionListener; +import dwtx.jface.text.contentassist.ICompletionProposal; +import dwtx.jface.text.contentassist.IContentAssistProcessor; +import dwtx.jface.text.contentassist.IContextInformation; +import dwtx.jface.text.contentassist.IContextInformationValidator; +import dwtx.jface.text.source.Annotation; +import dwtx.jface.text.source.ISourceViewer; +import dwtx.jface.text.source.TextInvocationContext; + + +/** + * Default implementation of IQuickAssistAssistant. + * + * @since 3.2 + */ +public class QuickAssistAssistant : IQuickAssistAssistant, IQuickAssistAssistantExtension { + + + private static final class QuickAssistAssistantImpl : ContentAssistant { + /* + * @see dwtx.jface.text.contentassist.ContentAssistant#possibleCompletionsClosed() + */ + public void possibleCompletionsClosed() { + super.possibleCompletionsClosed(); + } + + /* + * @see dwtx.jface.text.contentassist.ContentAssistant#hide() + * @since 3.4 + */ + protected void hide() { + super.hide(); + } + } + + + private static final class ContentAssistProcessor : IContentAssistProcessor { + + private IQuickAssistProcessor fQuickAssistProcessor; + + this(IQuickAssistProcessor processor) { + fQuickAssistProcessor= processor; + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(dwtx.jface.text.ITextViewer, int) + */ + public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) { + // panic code - should not happen + if (!( cast(ISourceViewer)viewer )) + return null; + + return fQuickAssistProcessor.computeQuickAssistProposals(new TextInvocationContext(cast(ISourceViewer)viewer, offset, -1)); + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(dwtx.jface.text.ITextViewer, int) + */ + public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) { + return null; + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistProcessor#getCompletionProposalAutoActivationCharacters() + */ + public char[] getCompletionProposalAutoActivationCharacters() { + return null; + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistProcessor#getContextInformationAutoActivationCharacters() + */ + public char[] getContextInformationAutoActivationCharacters() { + return null; + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistProcessor#getErrorMessage() + */ + public String getErrorMessage() { + return null; + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistProcessor#getContextInformationValidator() + */ + public IContextInformationValidator getContextInformationValidator() { + return null; + } + + } + + private QuickAssistAssistantImpl fQuickAssistAssistantImpl; + private IQuickAssistProcessor fQuickAssistProcessor; + + public this() { + fQuickAssistAssistantImpl= new QuickAssistAssistantImpl(); + fQuickAssistAssistantImpl.enableAutoActivation(false); + fQuickAssistAssistantImpl.enableAutoInsert(false); + } + + /* + * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#showPossibleQuickAssists() + */ + public String showPossibleQuickAssists() { + return fQuickAssistAssistantImpl.showPossibleCompletions(); + } + + /* + * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#getQuickAssistProcessor(java.lang.String) + */ + public IQuickAssistProcessor getQuickAssistProcessor() { + return fQuickAssistProcessor; + } + + /* + * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#setQuickAssistProcessor(dwtx.jface.text.quickassist.IQuickAssistProcessor) + */ + public void setQuickAssistProcessor(IQuickAssistProcessor processor) { + fQuickAssistProcessor= processor; + fQuickAssistAssistantImpl.setDocumentPartitioning("__" ~ this.classinfo.name ~ "_partitioning"); //$NON-NLS-1$ //$NON-NLS-2$ + fQuickAssistAssistantImpl.setContentAssistProcessor(new ContentAssistProcessor(processor), IDocument.DEFAULT_CONTENT_TYPE); + } + + /* + * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#canFix(dwtx.jface.text.source.Annotation) + */ + public bool canFix(Annotation annotation) { + return fQuickAssistProcessor !is null && fQuickAssistProcessor.canFix(annotation); + } + + /* + * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#canAssist(dwtx.jface.text.quickassist.IQuickAssistInvocationContext) + */ + public bool canAssist(IQuickAssistInvocationContext invocationContext) { + return fQuickAssistProcessor !is null && fQuickAssistProcessor.canAssist(invocationContext); + } + + /* + * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#install(dwtx.jface.text.ITextViewer) + */ + public void install(ISourceViewer sourceViewer) { + fQuickAssistAssistantImpl.install(sourceViewer); + } + + /* + * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#setInformationControlCreator(dwtx.jface.text.IInformationControlCreator) + */ + public void setInformationControlCreator(IInformationControlCreator creator) { + fQuickAssistAssistantImpl.setInformationControlCreator(creator); + } + + /* + * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#uninstall() + */ + public void uninstall() { + fQuickAssistAssistantImpl.uninstall(); + } + + /* + * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#setProposalSelectorBackground(dwt.graphics.Color) + */ + public void setProposalSelectorBackground(Color background) { + fQuickAssistAssistantImpl.setProposalSelectorBackground(background); + } + + /* + * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#setProposalSelectorForeground(dwt.graphics.Color) + */ + public void setProposalSelectorForeground(Color foreground) { + fQuickAssistAssistantImpl.setProposalSelectorForeground(foreground); + } + + /** + * Callback to signal this quick assist assistant that the presentation of the + * possible completions has been stopped. + */ + protected void possibleCompletionsClosed() { + fQuickAssistAssistantImpl.possibleCompletionsClosed(); + } + + /* + * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#addCompletionListener(dwtx.jface.text.contentassist.ICompletionListener) + */ + public void addCompletionListener(ICompletionListener listener) { + fQuickAssistAssistantImpl.addCompletionListener(listener); + } + + /* + * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#removeCompletionListener(dwtx.jface.text.contentassist.ICompletionListener) + */ + public void removeCompletionListener(ICompletionListener listener) { + fQuickAssistAssistantImpl.removeCompletionListener(listener); + } + + /* + * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#setStatusLineVisible(bool) + */ + public void setStatusLineVisible(bool show) { + fQuickAssistAssistantImpl.setStatusLineVisible(show); + + } + + /* + * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#setStatusMessage(java.lang.String) + */ + public void setStatusMessage(String message) { + fQuickAssistAssistantImpl.setStatusMessage(message); + } + + /** + * {@inheritDoc} + * + * @since 3.4 + */ + public final IHandler getHandler(String commandId) { + return fQuickAssistAssistantImpl.getHandler(commandId); + } + + /** + * Hides any open pop-ups. + * + * @since 3.4 + */ + protected void hide() { + fQuickAssistAssistantImpl.hide(); + } + + /** + * {@inheritDoc} + * + * @since 3.4 + */ + public void enableColoredLabels(bool isEnabled) { + fQuickAssistAssistantImpl.enableColoredLabels(isEnabled); + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/reconciler/AbstractReconcileStep.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/reconciler/AbstractReconcileStep.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,204 @@ +/******************************************************************************* + * 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 + * 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.text.reconciler.AbstractReconcileStep; + +import dwtx.jface.text.reconciler.IReconciler; // packageimport +import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport +import dwtx.jface.text.reconciler.MonoReconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcileStep; // packageimport +import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport +import dwtx.jface.text.reconciler.Reconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport +import dwtx.jface.text.reconciler.DirtyRegion; // packageimport +import dwtx.jface.text.reconciler.IReconcileResult; // packageimport +import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + +import dwtx.core.runtime.Assert; +import dwtx.core.runtime.IProgressMonitor; +import dwtx.jface.text.IRegion; + + +/** + * Abstract implementation of a reconcile step. + * + * @since 3.0 + */ +public abstract class AbstractReconcileStep : IReconcileStep { + + private IReconcileStep fNextStep; + private IReconcileStep fPreviousStep; + private IProgressMonitor fProgressMonitor; + protected IReconcilableModel fInputModel; + + /** + * Creates an intermediate reconcile step which adds + * the given step to the pipe. + * + * @param step the reconcile step + */ + public this(IReconcileStep step) { + Assert.isNotNull(cast(Object)step); + fNextStep= step; + fNextStep.setPreviousStep(this); + } + + /** + * Creates the last reconcile step of the pipe. + */ + public this() { + } + + public bool isLastStep() { + return fNextStep is null; + } + + public bool isFirstStep() { + return fPreviousStep is null; + } + + /* + * @see dwtx.text.reconcilerpipe.IReconcilerResultCollector#setProgressMonitor(dwtx.core.runtime.IProgressMonitor) + */ + public void setProgressMonitor(IProgressMonitor monitor) { + fProgressMonitor= monitor; + + if (!isLastStep()) + fNextStep.setProgressMonitor(monitor); + } + + /* + * @see dwtx.jface.text.reconciler.IReconcileStep#getProgressMonitor() + */ + public IProgressMonitor getProgressMonitor() { + return fProgressMonitor; + } + + /* + * @see IReconcileStep#reconcile(IRegion) + */ + public final IReconcileResult[] reconcile(IRegion partition) { + IReconcileResult[] result= reconcileModel(null, partition); + if (!isLastStep()) { + fNextStep.setInputModel(getModel()); + IReconcileResult[] nextResult= fNextStep.reconcile(partition); + return merge(result, convertToInputModel(nextResult)); + } + return result; + } + + /* + * @see IReconcileStep#reconcile(dwtx.jface.text.reconciler.DirtyRegion, dwtx.jface.text.IRegion) + */ + public final IReconcileResult[] reconcile(DirtyRegion dirtyRegion, IRegion subRegion) { + IReconcileResult[] result= reconcileModel(dirtyRegion, subRegion); + if (!isLastStep()) { + fNextStep.setInputModel(getModel()); + IReconcileResult[] nextResult= fNextStep.reconcile(dirtyRegion, subRegion); + return merge(result, convertToInputModel(nextResult)); + } + return result; + } + + + /** + * Reconciles the model of this reconcile step. The + * result is based on the input model. + * + * @param dirtyRegion the document region which has been changed + * @param subRegion the sub region in the dirty region which should be reconciled + * @return an array with reconcile results + */ + abstract protected IReconcileResult[] reconcileModel(DirtyRegion dirtyRegion, IRegion subRegion); + + /** + * Adapts the given an array with reconcile results to + * this step's input model and returns it. + * + * @param inputResults an array with reconcile results + * @return an array with the reconcile results adapted to the input model + */ + protected IReconcileResult[] convertToInputModel(IReconcileResult[] inputResults) { + return inputResults; + } + + /** + * Merges the two reconcile result arrays. + * + * @param results1 an array with reconcile results + * @param results2 an array with reconcile results + * @return an array with the merged reconcile results + */ + private IReconcileResult[] merge(IReconcileResult[] results1, IReconcileResult[] results2) { + if (results1 is null) + return results2; + + if (results2 is null) + return results1; + + // XXX: not yet performance optimized + Collection collection= new ArrayList(Arrays.asList(arraycast!(Object)(results1))); + collection.addAll(Arrays.asList(arraycast!(Object)(results2))); + return arraycast!(IReconcileResult)(collection.toArray()); + } + + /* + * @see IProgressMonitor#isCanceled() + */ + protected final bool isCanceled() { + return fProgressMonitor !is null && fProgressMonitor.isCanceled(); + } + + /* + * @see IReconcileStep#setPreviousStep(IReconcileStep) + */ + public void setPreviousStep(IReconcileStep step) { + Assert.isNotNull(cast(Object)step); + Assert.isTrue(fPreviousStep is null); + fPreviousStep= step; + } + + /* + * @see IReconcileStep#setInputModel(Object) + */ + public void setInputModel(IReconcilableModel inputModel) { + fInputModel= inputModel; + + if (!isLastStep()) + fNextStep.setInputModel(getModel()); + } + + /** + * Returns the reconcilable input model. + * + * @return the reconcilable input model. + */ + public IReconcilableModel getInputModel() { + return fInputModel; + } + + /** + * Returns the reconcilable model. + * + * @return the reconcilable model + */ + abstract public IReconcilableModel getModel(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/reconciler/AbstractReconciler.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/reconciler/AbstractReconciler.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,635 @@ +/******************************************************************************* + * 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 + * 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.text.reconciler.AbstractReconciler; + +import dwtx.jface.text.reconciler.IReconciler; // packageimport +import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport +import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport +import dwtx.jface.text.reconciler.MonoReconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcileStep; // packageimport +import dwtx.jface.text.reconciler.Reconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport +import dwtx.jface.text.reconciler.DirtyRegion; // packageimport +import dwtx.jface.text.reconciler.IReconcileResult; // packageimport +import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport + + +import dwt.dwthelper.utils; +import tango.core.Thread; + +import dwtx.core.runtime.Assert; +import dwtx.core.runtime.IProgressMonitor; +import dwtx.core.runtime.NullProgressMonitor; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentListener; +import dwtx.jface.text.ITextInputListener; +import dwtx.jface.text.ITextViewer; + + +/** + * Abstract implementation of {@link IReconciler}. The reconciler + * listens to input document changes as well as changes of + * the input document of the text viewer it is installed on. Depending on + * its configuration it manages the received change notifications in a + * queue folding neighboring or overlapping changes together. The reconciler + * processes the dirty regions as a background activity after having waited for further + * changes for the configured duration of time. A reconciler is started using the + * {@link #install(ITextViewer)} method. As a first step {@link #initialProcess()} is + * executed in the background. Then, the reconciling thread waits for changes that + * need to be reconciled. A reconciler can be resumed by calling {@link #forceReconciling()} + * independent from the existence of actual changes. This mechanism is for subclasses only. + * It is the clients responsibility to stop a reconciler using its {@link #uninstall()} + * method. Unstopped reconcilers do not free their resources. + *

                    + * It is subclass responsibility to specify how dirty regions are processed. + *

                    + * + * @see dwtx.jface.text.IDocumentListener + * @see dwtx.jface.text.ITextInputListener + * @see dwtx.jface.text.reconciler.DirtyRegion + * @since 2.0 + */ +abstract public class AbstractReconciler : IReconciler { + + + /** + * Background thread for the reconciling activity. + */ + class BackgroundThread { + Thread thread; + + /** Has the reconciler been canceled. */ + private bool fCanceled= false; + /** Has the reconciler been reset. */ + private bool fReset= false; + /** Some changes need to be processed. */ + private bool fIsDirty= false; + /** Is a reconciling strategy active. */ + private bool fIsActive= false; + + /** + * Creates a new background thread. The thread + * runs with minimal priority. + * + * @param name the thread's name + */ + public this(String name) { + thread = new Thread( &run ); + thread.name = name; + thread.priority = Thread.PRIORITY_MIN; + thread.isDaemon(true); + } + + public void start(){ + thread.start(); + } + public bool isAlive(){ + return thread.isRunning(); + } + public Thread getThread(){ + return thread; + } + /** + * Returns whether a reconciling strategy is active right now. + * + * @return true if a activity is active + */ + public bool isActive() { + return fIsActive; + } + + /** + * Returns whether some changes need to be processed. + * + * @return true if changes wait to be processed + * @since 3.0 + */ + public synchronized bool isDirty() { + return fIsDirty; + } + + /** + * Cancels the background thread. + */ + public void cancel() { + fCanceled= true; + IProgressMonitor pm= fProgressMonitor; + if (pm !is null) + pm.setCanceled(true); + synchronized (fDirtyRegionQueue) { + fDirtyRegionQueue.notifyAll(); + } + } + + /** + * Suspends the caller of this method until this background thread has + * emptied the dirty region queue. + */ + public void suspendCallerWhileDirty() { + bool isDirty; + do { + synchronized (fDirtyRegionQueue) { + isDirty= fDirtyRegionQueue.getSize() > 0; + if (isDirty) { + try { + fDirtyRegionQueue.wait(); + } catch (InterruptedException x) { + } + } + } + } while (isDirty); + } + + /** + * Reset the background thread as the text viewer has been changed, + */ + public void reset() { + + if (fDelay > 0) { + + synchronized (this) { + fIsDirty= true; + fReset= true; + } + + } else { + + synchronized (this) { + fIsDirty= true; + } + + synchronized (fDirtyRegionQueue) { + fDirtyRegionQueue.notifyAll(); + } + } + + reconcilerReset(); + } + + /** + * The background activity. Waits until there is something in the + * queue managing the changes that have been applied to the text viewer. + * Removes the first change from the queue and process it. + *

                    + * Calls {@link AbstractReconciler#initialProcess()} on entrance. + *

                    + */ + public void run() { + + synchronized (fDirtyRegionQueue) { + try { + fDirtyRegionQueue.wait(fDelay); + } catch (InterruptedException x) { + } + } + + if (fCanceled) + return; + + initialProcess(); + + while (!fCanceled) { + + synchronized (fDirtyRegionQueue) { + try { + fDirtyRegionQueue.wait(fDelay); + } catch (InterruptedException x) { + } + } + + if (fCanceled) + break; + + if (!isDirty()) + continue; + + synchronized (this) { + if (fReset) { + fReset= false; + continue; + } + } + + DirtyRegion r= null; + synchronized (fDirtyRegionQueue) { + r= fDirtyRegionQueue.removeNextDirtyRegion(); + } + + fIsActive= true; + + fProgressMonitor.setCanceled(false); + + process(r); + + synchronized (fDirtyRegionQueue) { + if (0 is fDirtyRegionQueue.getSize()) { + synchronized (this) { + fIsDirty= fProgressMonitor.isCanceled(); + } + fDirtyRegionQueue.notifyAll(); + } + } + + fIsActive= false; + } + } + } + + /** + * Internal document listener and text input listener. + */ + class Listener : IDocumentListener, ITextInputListener { + + /* + * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent) + */ + public void documentAboutToBeChanged(DocumentEvent e) { + } + + /* + * @see IDocumentListener#documentChanged(DocumentEvent) + */ + public void documentChanged(DocumentEvent e) { + + if (!fThread.isDirty() && fThread.isAlive()) { + if (!fIsAllowedToModifyDocument && Thread.getThis() is fThread.getThread()) + throw new UnsupportedOperationException("The reconciler thread is not allowed to modify the document"); //$NON-NLS-1$ + aboutToBeReconciled(); + } + + /* + * The second OR condition handles the case when the document + * gets changed while still inside initialProcess(). + */ + if (fThread.isActive() || fThread.isDirty() && fThread.isAlive()) + fProgressMonitor.setCanceled(true); + + if (fIsIncrementalReconciler) + createDirtyRegion(e); + + fThread.reset(); + + } + + /* + * @see ITextInputListener#inputDocumentAboutToBeChanged(IDocument, IDocument) + */ + public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { + + if (oldInput is fDocument) { + + if (fDocument !is null) + fDocument.removeDocumentListener(this); + + if (fIsIncrementalReconciler) { + synchronized (fDirtyRegionQueue) { + fDirtyRegionQueue.purgeQueue(); + } + if (fDocument !is null && fDocument.getLength() > 0 && fThread.isDirty() && fThread.isAlive()) { + DocumentEvent e= new DocumentEvent(fDocument, 0, fDocument.getLength(), ""); //$NON-NLS-1$ + createDirtyRegion(e); + fThread.reset(); + fThread.suspendCallerWhileDirty(); + } + } + + fDocument= null; + } + } + + /* + * @see ITextInputListener#inputDocumentChanged(IDocument, IDocument) + */ + public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { + + fDocument= newInput; + if (fDocument is null) + return; + + + reconcilerDocumentChanged(fDocument); + + fDocument.addDocumentListener(this); + + if (!fThread.isDirty()) + aboutToBeReconciled(); + + startReconciling(); + } + } + + /** Queue to manage the changes applied to the text viewer. */ + private DirtyRegionQueue fDirtyRegionQueue; + /** The background thread. */ + private BackgroundThread fThread; + /** Internal document and text input listener. */ + private Listener fListener; + /** The background thread delay. */ + private int fDelay= 500; + /** Are there incremental reconciling strategies? */ + private bool fIsIncrementalReconciler= true; + /** The progress monitor used by this reconciler. */ + private IProgressMonitor fProgressMonitor; + /** + * Tells whether this reconciler is allowed to modify the document. + * @since 3.2 + */ + private bool fIsAllowedToModifyDocument= true; + + + /** The text viewer's document. */ + private IDocument fDocument; + /** The text viewer */ + private ITextViewer fViewer; + + + /** + * Processes a dirty region. If the dirty region is null the whole + * document is consider being dirty. The dirty region is partitioned by the + * document and each partition is handed over to a reconciling strategy registered + * for the partition's content type. + * + * @param dirtyRegion the dirty region to be processed + */ + abstract protected void process(DirtyRegion dirtyRegion); + + /** + * Hook called when the document whose contents should be reconciled + * has been changed, i.e., the input document of the text viewer this + * reconciler is installed on. Usually, subclasses use this hook to + * inform all their reconciling strategies about the change. + * + * @param newDocument the new reconciler document + */ + abstract protected void reconcilerDocumentChanged(IDocument newDocument); + + + /** + * Creates a new reconciler without configuring it. + */ + protected this() { + fProgressMonitor= new NullProgressMonitor(); + } + + /** + * Tells the reconciler how long it should wait for further text changes before + * activating the appropriate reconciling strategies. + * + * @param delay the duration in milliseconds of a change collection period. + */ + public void setDelay(int delay) { + fDelay= delay; + } + + /** + * Tells the reconciler whether any of the available reconciling strategies + * is interested in getting detailed dirty region information or just in the + * fact that the document has been changed. In the second case, the reconciling + * can not incrementally be pursued. + * + * @param isIncremental indicates whether this reconciler will be configured with + * incremental reconciling strategies + * + * @see DirtyRegion + * @see IReconcilingStrategy + */ + public void setIsIncrementalReconciler(bool isIncremental) { + fIsIncrementalReconciler= isIncremental; + } + + /** + * Tells the reconciler whether it is allowed to change the document + * inside its reconciler thread. + *

                    + * If this is set to false an {@link UnsupportedOperationException} + * will be thrown when this restriction will be violated. + *

                    + * + * @param isAllowedToModify indicates whether this reconciler is allowed to modify the document + * @since 3.2 + */ + public void setIsAllowedToModifyDocument(bool isAllowedToModify) { + fIsAllowedToModifyDocument= isAllowedToModify; + } + + /** + * Sets the progress monitor of this reconciler. + * + * @param monitor the monitor to be used + */ + public void setProgressMonitor(IProgressMonitor monitor) { + Assert.isLegal(monitor !is null); + fProgressMonitor= monitor; + } + + /** + * Returns whether any of the reconciling strategies is interested in + * detailed dirty region information. + * + * @return whether this reconciler is incremental + * + * @see IReconcilingStrategy + */ + protected bool isIncrementalReconciler() { + return fIsIncrementalReconciler; + } + + /** + * Returns the input document of the text viewer this reconciler is installed on. + * + * @return the reconciler document + */ + protected IDocument getDocument() { + return fDocument; + } + + /** + * Returns the text viewer this reconciler is installed on. + * + * @return the text viewer this reconciler is installed on + */ + protected ITextViewer getTextViewer() { + return fViewer; + } + + /** + * Returns the progress monitor of this reconciler. + * + * @return the progress monitor of this reconciler + */ + protected IProgressMonitor getProgressMonitor() { + return fProgressMonitor; + } + + /* + * @see IReconciler#install(ITextViewer) + */ + public void install(ITextViewer textViewer) { + + Assert.isNotNull(cast(Object)textViewer); + fViewer= textViewer; + + synchronized (this) { + if (fThread !is null) + return; + fThread= new BackgroundThread(this.classinfo.name); + } + + fDirtyRegionQueue= new DirtyRegionQueue(); + + fListener= new Listener(); + fViewer.addTextInputListener(fListener); + + // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=67046 + // if the reconciler gets installed on a viewer that already has a document + // (e.g. when reusing editors), we force the listener to register + // itself as document listener, because there will be no input change + // on the viewer. + // In order to do that, we simulate an input change. + IDocument document= textViewer.getDocument(); + if (document !is null) { + fListener.inputDocumentAboutToBeChanged(fDocument, document); + fListener.inputDocumentChanged(fDocument, document); + } + } + + /* + * @see IReconciler#uninstall() + */ + public void uninstall() { + if (fListener !is null) { + + fViewer.removeTextInputListener(fListener); + if (fDocument !is null) { + fListener.inputDocumentAboutToBeChanged(fDocument, null); + fListener.inputDocumentChanged(fDocument, null); + } + fListener= null; + + synchronized (this) { + // http://dev.eclipse.org/bugs/show_bug.cgi?id=19135 + BackgroundThread bt= fThread; + fThread= null; + bt.cancel(); + } + } + } + + /** + * Creates a dirty region for a document event and adds it to the queue. + * + * @param e the document event for which to create a dirty region + */ + private void createDirtyRegion(DocumentEvent e) { + synchronized (fDirtyRegionQueue) { + if (e.getLength() is 0 && e.getText() !is null) { + // Insert + fDirtyRegionQueue.addDirtyRegion(new DirtyRegion(e.getOffset(), e.getText().length(), DirtyRegion.INSERT, e.getText())); + + } else if (e.getText() is null || e.getText().length() is 0) { + // Remove + fDirtyRegionQueue.addDirtyRegion(new DirtyRegion(e.getOffset(), e.getLength(), DirtyRegion.REMOVE, null)); + + } else { + // Replace (Remove + Insert) + fDirtyRegionQueue.addDirtyRegion(new DirtyRegion(e.getOffset(), e.getLength(), DirtyRegion.REMOVE, null)); + fDirtyRegionQueue.addDirtyRegion(new DirtyRegion(e.getOffset(), e.getText().length(), DirtyRegion.INSERT, e.getText())); + } + } + } + + /** + * Hook for subclasses which want to perform some + * action as soon as reconciliation is needed. + *

                    + * Default implementation is to do nothing. + *

                    + * + * @since 3.0 + */ + protected void aboutToBeReconciled() { + } + + /** + * This method is called on startup of the background activity. It is called only + * once during the life time of the reconciler. Clients may reimplement this method. + */ + protected void initialProcess() { + } + + /** + * Forces the reconciler to reconcile the structure of the whole document. + * Clients may extend this method. + */ + protected void forceReconciling() { + + if (fDocument !is null) { + + if (!fThread.isDirty()&& fThread.isAlive()) + aboutToBeReconciled(); + + if (fThread.isActive()) + fProgressMonitor.setCanceled(true); + + if (fIsIncrementalReconciler) { + DocumentEvent e= new DocumentEvent(fDocument, 0, fDocument.getLength(), fDocument.get()); + createDirtyRegion(e); + } + + startReconciling(); + } + } + + /** + * Starts the reconciler to reconcile the queued dirty-regions. + * Clients may extend this method. + */ + protected synchronized void startReconciling() { + if (fThread is null) + return; + + if (!fThread.isAlive()) { +// DWT +// try { + fThread.start(); +// } catch (IllegalThreadStateException e) { + // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=40549 + // This is the only instance where the thread is started; since + // we checked that it is not alive, it must be dead already due + // to a run-time exception or error. Exit. +// } + } else { + fThread.reset(); + } + } + + /** + * Hook that is called after the reconciler thread has been reset. + */ + protected void reconcilerReset() { + } + + /** + * Tells whether the code is running in this reconciler's + * background thread. + * + * @return true if running in this reconciler's background thread + * @since 3.4 + */ + protected bool isRunningInReconcilerThread() { + return Thread.getThis() is fThread.getThread(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/reconciler/DirtyRegion.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/reconciler/DirtyRegion.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.reconciler.DirtyRegion; + +import dwtx.jface.text.reconciler.IReconciler; // packageimport +import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport +import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport +import dwtx.jface.text.reconciler.MonoReconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcileStep; // packageimport +import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport +import dwtx.jface.text.reconciler.Reconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport +import dwtx.jface.text.reconciler.IReconcileResult; // packageimport +import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.ITypedRegion; + + +/** + * A dirty region describes a document range which has been changed. + */ +public class DirtyRegion : ITypedRegion { + + /** + * Identifies an insert operation. + */ + final static public String INSERT= "__insert"; //$NON-NLS-1$ + /** + * Identifies a remove operation. + */ + final static public String REMOVE= "__remove"; //$NON-NLS-1$ + + /** The region's offset. */ + private int fOffset; + /** The region's length. */ + private int fLength; + /** Indicates the type of the applied change. */ + private String fType; + /** The text which has been inserted. */ + private String fText; + + /** + * Creates a new dirty region. + * + * @param offset the offset within the document where the change occurred + * @param length the length of the text within the document that changed + * @param type the type of change that this region represents: {@link #INSERT} {@link #REMOVE} + * @param text the substitution text + */ + public this(int offset, int length, String type, String text) { + fOffset= offset; + fLength= length; + fType= normalizeTypeValue(type); + fText= text; + } + + /** + * Computes the normalized type value to ensure that the implementation can use object identity rather + * than equality. + * + * @param type the type value + * @return the normalized type value or null + * @since 3.1 + */ + private String normalizeTypeValue(String type) { + if (INSERT.equals(type)) + return INSERT; + if (REMOVE.equals(type)) + return REMOVE; + return null; + } + + /* + * @see ITypedRegion#getOffset() + */ + public int getOffset() { + return fOffset; + } + + /* + * @see ITypedRegion#getLength() + */ + public int getLength() { + return fLength; + } + + /* + * @see ITypedRegion#getType + */ + public String getType() { + return fType; + } + + /** + * Returns the text that changed as part of the region change. + * + * @return the changed text + */ + public String getText() { + return fText; + } + + /** + * Modify the receiver so that it encompasses the region specified by the dirty region. + * + * @param dr the dirty region with which to merge + */ + void mergeWith(DirtyRegion dr) { + int start= Math.min(fOffset, dr.fOffset); + int end= Math.max(fOffset + fLength, dr.fOffset + dr.fLength); + fOffset= start; + fLength= end - start; + fText= (dr.fText is null ? fText : (fText is null) ? dr.fText : fText ~ dr.fText); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/reconciler/DirtyRegionQueue.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/reconciler/DirtyRegionQueue.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,135 @@ +/******************************************************************************* + * 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 + * 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.text.reconciler.DirtyRegionQueue; + +import dwtx.jface.text.reconciler.IReconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport +import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport +import dwtx.jface.text.reconciler.MonoReconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcileStep; // packageimport +import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport +import dwtx.jface.text.reconciler.Reconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport +import dwtx.jface.text.reconciler.DirtyRegion; // packageimport +import dwtx.jface.text.reconciler.IReconcileResult; // packageimport +import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + +import tango.core.sync.Mutex; +import tango.core.sync.Condition; + +/** + * Queue used by {@link dwtx.jface.text.reconciler.AbstractReconciler} to manage + * dirty regions. When a dirty region is inserted into the queue, the queue tries + * to fold it into the neighboring dirty region. + * + * @see dwtx.jface.text.reconciler.AbstractReconciler + * @see dwtx.jface.text.reconciler.DirtyRegion + */ +class DirtyRegionQueue : Mutex { + + /** The list of dirty regions. */ + private List fDirtyRegions; + private Condition cond; + /** + * Creates a new empty dirty region. + */ + public this() { + //super(); + fDirtyRegions= new ArrayList(); + cond = new Condition(this); + } + + public void wait(){ + cond.wait(); + } + public void wait(int delay){ + cond.wait(delay/1000.0); + } + public void notifyAll(){ + cond.notifyAll(); + } + + /** + * Adds a dirty region to the end of the dirty-region queue. + * + * @param dr the dirty region to add + */ + public void addDirtyRegion(DirtyRegion dr) { + // If the dirty region being added is directly after the last dirty + // region on the queue then merge the two dirty regions together. + DirtyRegion lastDR= getLastDirtyRegion(); + bool wasMerged= false; + if (lastDR !is null) + if (lastDR.getType() is dr.getType()) + if (lastDR.getType() is DirtyRegion.INSERT) { + if (lastDR.getOffset() + lastDR.getLength() is dr.getOffset()) { + lastDR.mergeWith(dr); + wasMerged= true; + } + } else if (lastDR.getType() is DirtyRegion.REMOVE) { + if (dr.getOffset() + dr.getLength() is lastDR.getOffset()) { + lastDR.mergeWith(dr); + wasMerged= true; + } + } + + if (!wasMerged) + // Don't merge- just add the new one onto the queue. + fDirtyRegions.add(dr); + } + + /** + * Returns the last dirty region that was added to the queue. + * + * @return the last DirtyRegion on the queue + */ + private DirtyRegion getLastDirtyRegion() { + int size= fDirtyRegions.size(); + return (size is 0 ? null : cast(DirtyRegion) fDirtyRegions.get(size - 1)); + } + + /** + * Returns the number of regions in the queue. + * + * @return the dirty-region queue-size + */ + public int getSize() { + return fDirtyRegions.size(); + } + + /** + * Throws away all entries in the queue. + */ + public void purgeQueue() { + fDirtyRegions.clear(); + } + + /** + * Removes and returns the first dirty region in the queue + * + * @return the next dirty region on the queue + */ + public DirtyRegion removeNextDirtyRegion() { + if (fDirtyRegions.size() is 0) + return null; + DirtyRegion dr= cast(DirtyRegion) fDirtyRegions.get(0); + fDirtyRegions.remove(0); + return dr; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/reconciler/IReconcilableModel.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/reconciler/IReconcilableModel.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.reconciler.IReconcilableModel; + +import dwtx.jface.text.reconciler.IReconciler; // packageimport +import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport +import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport +import dwtx.jface.text.reconciler.MonoReconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcileStep; // packageimport +import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport +import dwtx.jface.text.reconciler.Reconciler; // packageimport +import dwtx.jface.text.reconciler.DirtyRegion; // packageimport +import dwtx.jface.text.reconciler.IReconcileResult; // packageimport +import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Tagging interface for a model that can get reconciled during a + * {@linkplain dwtx.jface.text.reconciler.IReconcileStep reconcile step}. + *

                    + * This model is not directly used by a {@linkplain dwtx.jface.text.reconciler.IReconciler reconciler} + * or a {@linkplain dwtx.jface.text.reconciler.IReconcilingStrategy reconciling strategy}. + *

                    + * + *

                    + * This interface must be implemented by clients that want to use one of + * their models as a reconcile step's input model. + *

                    + * + * @see dwtx.jface.text.reconciler.IReconcileStep#setInputModel(IReconcilableModel) + * @since 3.0 + */ +public interface IReconcilableModel { + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/reconciler/IReconcileResult.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/reconciler/IReconcileResult.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.reconciler.IReconcileResult; + +import dwtx.jface.text.reconciler.IReconciler; // packageimport +import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport +import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport +import dwtx.jface.text.reconciler.MonoReconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcileStep; // packageimport +import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport +import dwtx.jface.text.reconciler.Reconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport +import dwtx.jface.text.reconciler.DirtyRegion; // packageimport +import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Tagging interface for the {@linkplain dwtx.jface.text.reconciler.IReconcileStep reconcile step} + * result's array element type. + *

                    + * This interface must be implemented by clients that want to + * let one of their model elements be part of a reconcile step result. + *

                    + * + * @see dwtx.jface.text.reconciler.IReconcileStep + * @since 3.0 + */ +public interface IReconcileResult { + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/reconciler/IReconcileStep.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/reconciler/IReconcileStep.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.reconciler.IReconcileStep; + +import dwtx.jface.text.reconciler.IReconciler; // packageimport +import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport +import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport +import dwtx.jface.text.reconciler.MonoReconciler; // packageimport +import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport +import dwtx.jface.text.reconciler.Reconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport +import dwtx.jface.text.reconciler.DirtyRegion; // packageimport +import dwtx.jface.text.reconciler.IReconcileResult; // packageimport +import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.core.runtime.IProgressMonitor; +import dwtx.jface.text.IRegion; + + +/** + * A reconcile step is one of several steps of a + * {@linkplain dwtx.jface.text.reconciler.IReconcilingStrategy reconcile strategy} + * that consists of several steps. This relationship is not coded into an interface but + * should be used by clients who's reconcile strategy consists of several steps. + *

                    + * If a reconcile step has an {@linkplain dwtx.jface.text.reconciler.IReconcilableModel input model} + * it will compute the correct model for the next step in the chain and set the next steps + * input model before reconcile gets called on that next step. After the last + * step has reconciled the {@linkplain dwtx.jface.text.reconciler.IReconcileResult reconcile result} + * array gets returned to the previous step. Each step in the chain adapts the result to its + * input model and returns it to its previous step. + *

                    + *

                    + * Example: Assume a strategy consists of steps A, B and C. And the main model is M. + * The strategy will set M to be A's input model. What will happen is: + *

                      + *
                    1. A.setInputModel(M)
                    2. + *
                    3. A.reconcile: A reconciles M
                    4. + *
                    5. A computes the model for B => MB
                    6. + *
                    7. B.setInputModel(MB)
                    8. + *
                    9. B.reconcile: B reconciles MB
                    10. + *
                    11. B computes the model for C => MC
                    12. + *
                    13. C.setInputModel(MC)
                    14. + *
                    15. C.reconcile: C reconciles MC
                    16. + *
                    17. C returns result RC to step B
                    18. + *
                    19. B adapts the RC to MB and merges with its own results
                    20. + *
                    21. B returns result RB to step A
                    22. + *
                    23. A adapts the result to M and merges with its own results
                    24. + *
                    25. A returns the result to the reconcile strategy
                    26. + *
                    + *

                    + *

                    + * This interface must be implemented by clients. + *

                    + * @since 3.0 + */ +public interface IReconcileStep { + + /** + * Returns whether this is the last reconcile step or not. + * + * @return true iff this is the last reconcile step + */ + bool isLastStep(); + + /** + * Returns whether this is the first reconcile step or not. + * + * @return true iff this is the first reconcile step + */ + bool isFirstStep(); + + /** + * Sets the step which is in front of this step in the pipe. + *

                    + * Note: This method must be called at most once per reconcile step. + *

                    + * + * @param step the previous step + * @throws RuntimeException if called more than once + */ + void setPreviousStep(IReconcileStep step); + + /** + * Activates incremental reconciling of the specified dirty region. + * As a dirty region might span multiple content types, the segment of the + * dirty region which should be investigated is also provided to this + * reconciling strategy. The given regions refer to the document passed into + * the most recent call of {@link IReconcilingStrategy#setDocument(dwtx.jface.text.IDocument)}. + * + * @param dirtyRegion the document region which has been changed + * @param subRegion the sub region in the dirty region which should be reconciled + * @return an array with reconcile results + */ + IReconcileResult[] reconcile(DirtyRegion dirtyRegion, IRegion subRegion); + + /** + * Activates non-incremental reconciling. The reconciling strategy is just told + * that there are changes and that it should reconcile the given partition of the + * document most recently passed into {@link IReconcilingStrategy#setDocument(dwtx.jface.text.IDocument)}. + * + * @param partition the document partition to be reconciled + * @return an array with reconcile results + */ + IReconcileResult[] reconcile(IRegion partition); + + /** + * Sets the progress monitor for this reconcile step. + * + * @param monitor the progress monitor to be used + */ + void setProgressMonitor(IProgressMonitor monitor); + + /** + * Returns the progress monitor used to report progress. + * + * @return a progress monitor or null if no progress monitor is available + */ + public IProgressMonitor getProgressMonitor(); + + /** + * Tells this reconcile step on which model it will + * work. This method will be called before any other method + * and can be called multiple times. The regions passed to the + * other methods always refer to the most recent model + * passed into this method. + * + * @param inputModel the model on which this step will work + */ + void setInputModel(IReconcilableModel inputModel); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/reconciler/IReconciler.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/reconciler/IReconciler.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,93 @@ +/******************************************************************************* + * 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 + * 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.text.reconciler.IReconciler; + +import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport +import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport +import dwtx.jface.text.reconciler.MonoReconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcileStep; // packageimport +import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport +import dwtx.jface.text.reconciler.Reconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport +import dwtx.jface.text.reconciler.DirtyRegion; // packageimport +import dwtx.jface.text.reconciler.IReconcileResult; // packageimport +import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.ITextViewer; + + +/** + * An IReconciler defines and maintains a model of the content + * of the text viewer's document in the presence of changes applied to this + * document. An IReconciler is a {@link dwtx.jface.text.ITextViewer} add-on. + *

                    + * Reconcilers are assumed to be asynchronous, i.e. they allow a certain + * temporal window of inconsistency between the document and the model of + * the content of this document. + *

                    + *

                    + * Reconcilers have a list of {@link dwtx.jface.text.reconciler.IReconcilingStrategy} + * objects each of which is registered for a particular document content type. + * The reconciler uses the strategy objects to react on the changes applied + * to the text viewer's document. + *

                    + *

                    + * In order to provide backward compatibility for clients of IReconciler, extension + * interfaces are used to provide a means of evolution. The following extension interfaces exist: + *

                      + *
                    • {@link dwtx.jface.text.reconciler.IReconcilerExtension} since version 3.0 introducing + * the ability to be aware of documents with multiple partitionings.
                    • + *
                    + *

                    + *

                    + * The interface can be implemented by clients. By default, clients use + * {@link dwtx.jface.text.reconciler.MonoReconciler} or + * {@link dwtx.jface.text.reconciler.Reconciler} as the standard + * implementers of this interface. + *

                    + * + * @see ITextViewer + * @see IReconcilingStrategy + */ +public interface IReconciler { + + /** + * Installs the reconciler on the given text viewer. After this method has been + * finished, the reconciler is operational, i.e., it works without requesting + * further client actions until uninstall is called. + * + * @param textViewer the viewer on which the reconciler is installed + */ + void install(ITextViewer textViewer); + + /** + * Removes the reconciler from the text viewer it has + * previously been installed on. + */ + void uninstall(); + + /** + * Returns the reconciling strategy registered with the reconciler + * for the specified content type. + * + * @param contentType the content type for which to determine the reconciling strategy + * @return the reconciling strategy registered for the given content type, or + * null if there is no such strategy + */ + IReconcilingStrategy getReconcilingStrategy(String contentType); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/reconciler/IReconcilerExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/reconciler/IReconcilerExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,46 @@ +/******************************************************************************* + * 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 + * 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.text.reconciler.IReconcilerExtension; + +import dwtx.jface.text.reconciler.IReconciler; // packageimport +import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport +import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport +import dwtx.jface.text.reconciler.MonoReconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcileStep; // packageimport +import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport +import dwtx.jface.text.reconciler.Reconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport +import dwtx.jface.text.reconciler.DirtyRegion; // packageimport +import dwtx.jface.text.reconciler.IReconcileResult; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Extends {@link dwtx.jface.text.reconciler.IReconciler} with + * the ability to be aware of documents with multiple partitionings. + * + * @since 3.0 + */ +public interface IReconcilerExtension { + + /** + * Returns the partitioning this reconciler is using. + * + * @return the partitioning this reconciler is using + */ + String getDocumentPartitioning(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/reconciler/IReconcilingStrategy.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/reconciler/IReconcilingStrategy.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.reconciler.IReconcilingStrategy; + +import dwtx.jface.text.reconciler.IReconciler; // packageimport +import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport +import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport +import dwtx.jface.text.reconciler.MonoReconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcileStep; // packageimport +import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport +import dwtx.jface.text.reconciler.Reconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport +import dwtx.jface.text.reconciler.DirtyRegion; // packageimport +import dwtx.jface.text.reconciler.IReconcileResult; // packageimport +import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; + + +/** + * A reconciling strategy is used by an reconciler to reconcile a model + * based on text of a particular content type. It provides methods for + * incremental as well as non-incremental reconciling. + *

                    + * If a reconcile strategy consists of several steps between which + * model transformation is desired the each step should implement + * {@link dwtx.jface.text.reconciler.IReconcileStep}. + *

                    + *

                    + * In order to provide backward compatibility for clients of IReconcilingStrategy, extension + * interfaces are used to provide a means of evolution. The following extension interfaces exist: + *

                      + *
                    • {@link dwtx.jface.text.reconciler.IReconcilingStrategyExtension} since version 2.0 introducing + * the following functions: + *
                        + *
                      • usage of a progress monitor
                      • + *
                      • initial reconciling step: if a reconciler runs as periodic activity in the background, this + * methods offers the reconciler a chance for initializing its strategies and achieving a + * reconciled state before the periodic activity starts.
                      • + *
                      + *
                    • + *
                    + *

                    + *

                    + * This interface must be implemented by clients. Implementers should be + * registered with a reconciler in order get involved in the reconciling + * process. + *

                    + */ +public interface IReconcilingStrategy { + + /** + * Tells this reconciling strategy on which document it will + * work. This method will be called before any other method + * and can be called multiple times. The regions passed to the + * other methods always refer to the most recent document + * passed into this method. + * + * @param document the document on which this strategy will work + */ + void setDocument(IDocument document); + + /** + * Activates incremental reconciling of the specified dirty region. + * As a dirty region might span multiple content types, the segment of the + * dirty region which should be investigated is also provided to this + * reconciling strategy. The given regions refer to the document passed into + * the most recent call of {@link #setDocument(IDocument)}. + * + * @param dirtyRegion the document region which has been changed + * @param subRegion the sub region in the dirty region which should be reconciled + */ + void reconcile(DirtyRegion dirtyRegion, IRegion subRegion); + + /** + * Activates non-incremental reconciling. The reconciling strategy is just told + * that there are changes and that it should reconcile the given partition of the + * document most recently passed into {@link #setDocument(IDocument)}. + * + * @param partition the document partition to be reconciled + */ + void reconcile(IRegion partition); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/reconciler/IReconcilingStrategyExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/reconciler/IReconcilingStrategyExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.reconciler.IReconcilingStrategyExtension; + +import dwtx.jface.text.reconciler.IReconciler; // packageimport +import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport +import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport +import dwtx.jface.text.reconciler.MonoReconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcileStep; // packageimport +import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport +import dwtx.jface.text.reconciler.Reconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport +import dwtx.jface.text.reconciler.DirtyRegion; // packageimport +import dwtx.jface.text.reconciler.IReconcileResult; // packageimport +import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.core.runtime.IProgressMonitor; + + +/** + * Extends {@link dwtx.jface.text.reconciler.IReconcilingStrategy} + * with the following functions: + *
                      + *
                    • usage of a progress monitor
                    • + *
                    • initial reconciling step: if a reconciler runs as periodic activity in the background, this + * methods offers the reconciler a chance for initializing its strategies and achieving a + * reconciled state before the periodic activity starts.
                    • + *
                    + * + * @since 2.0 + */ +public interface IReconcilingStrategyExtension { + + /** + * Tells this reconciling strategy with which progress monitor + * it will work. This method will be called before any other + * method and can be called multiple times. + * + * @param monitor the progress monitor with which this strategy will work + */ + void setProgressMonitor(IProgressMonitor monitor); + + /** + * Called only once in the life time of this reconciling strategy. + */ + void initialReconcile(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/reconciler/MonoReconciler.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/reconciler/MonoReconciler.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,126 @@ +/******************************************************************************* + * 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.text.reconciler.MonoReconciler; + +import dwtx.jface.text.reconciler.IReconciler; // packageimport +import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport +import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport +import dwtx.jface.text.reconciler.IReconcileStep; // packageimport +import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport +import dwtx.jface.text.reconciler.Reconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport +import dwtx.jface.text.reconciler.DirtyRegion; // packageimport +import dwtx.jface.text.reconciler.IReconcileResult; // packageimport +import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.core.runtime.Assert; +import dwtx.core.runtime.IProgressMonitor; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.Region; + + +/** + * Standard implementation of {@link dwtx.jface.text.reconciler.IReconciler}. + * The reconciler is configured with a single {@linkplain dwtx.jface.text.reconciler.IReconcilingStrategy reconciling strategy} + * that is used independently from where a dirty region is located in the reconciler's + * document. + *

                    + * Usually, clients instantiate this class and configure it before using it. + *

                    + * + * @see dwtx.jface.text.IDocumentListener + * @see dwtx.jface.text.ITextInputListener + * @see dwtx.jface.text.reconciler.DirtyRegion + * @since 2.0 + */ +public class MonoReconciler : AbstractReconciler { + + + /** The reconciling strategy. */ + private IReconcilingStrategy fStrategy; + + + /** + * Creates a new reconciler that uses the same reconciling strategy to + * reconcile its document independent of the type of the document's contents. + * + * @param strategy the reconciling strategy to be used + * @param isIncremental the indication whether strategy is incremental or not + */ + public this(IReconcilingStrategy strategy, bool isIncremental) { + Assert.isNotNull(cast(Object)strategy); + fStrategy= strategy; + if ( cast(IReconcilingStrategyExtension)fStrategy ) { + IReconcilingStrategyExtension extension= cast(IReconcilingStrategyExtension)fStrategy; + extension.setProgressMonitor(getProgressMonitor()); + } + + setIsIncrementalReconciler(isIncremental); + } + + /* + * @see IReconciler#getReconcilingStrategy(String) + */ + public IReconcilingStrategy getReconcilingStrategy(String contentType) { + Assert.isNotNull(contentType); + return fStrategy; + } + + /* + * @see AbstractReconciler#process(DirtyRegion) + */ + protected void process(DirtyRegion dirtyRegion) { + + if(dirtyRegion !is null) + fStrategy.reconcile(dirtyRegion, dirtyRegion); + else { + IDocument document= getDocument(); + if (document !is null) + fStrategy.reconcile(new Region(0, document.getLength())); + } + } + + /* + * @see AbstractReconciler#reconcilerDocumentChanged(IDocument) + */ + protected void reconcilerDocumentChanged(IDocument document) { + fStrategy.setDocument(document); + } + + /* + * @see AbstractReconciler#setProgressMonitor(IProgressMonitor) + */ + public void setProgressMonitor(IProgressMonitor monitor) { + super.setProgressMonitor(monitor); + if ( cast(IReconcilingStrategyExtension)fStrategy ) { + IReconcilingStrategyExtension extension= cast(IReconcilingStrategyExtension) fStrategy; + extension.setProgressMonitor(monitor); + } + } + + /* + * @see AbstractReconciler#initialProcess() + */ + protected void initialProcess() { + if ( cast(IReconcilingStrategyExtension)fStrategy ) { + IReconcilingStrategyExtension extension= cast(IReconcilingStrategyExtension) fStrategy; + extension.initialReconcile(); + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/reconciler/Reconciler.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/reconciler/Reconciler.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,243 @@ +/******************************************************************************* + * 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.text.reconciler.Reconciler; + +import dwtx.jface.text.reconciler.IReconciler; // packageimport +import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport +import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport +import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport +import dwtx.jface.text.reconciler.MonoReconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcileStep; // packageimport +import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport +import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport +import dwtx.jface.text.reconciler.DirtyRegion; // packageimport +import dwtx.jface.text.reconciler.IReconcileResult; // packageimport +import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + + + +import dwtx.core.runtime.Assert; +import dwtx.core.runtime.IProgressMonitor; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentExtension3; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITypedRegion; +import dwtx.jface.text.Region; +import dwtx.jface.text.TextUtilities; +import dwtx.jface.text.TypedRegion; + + +/** + * Standard implementation of {@link dwtx.jface.text.reconciler.IReconciler}. + * The reconciler is configured with a set of {@linkplain dwtx.jface.text.reconciler.IReconcilingStrategy reconciling strategies} + * each of which is responsible for a particular content type. + *

                    + * Usually, clients instantiate this class and configure it before using it. + *

                    + * + * @see dwtx.jface.text.IDocumentListener + * @see dwtx.jface.text.ITextInputListener + * @see dwtx.jface.text.reconciler.DirtyRegion + */ +public class Reconciler : AbstractReconciler , IReconcilerExtension { + + /** The map of reconciling strategies. */ + private Map fStrategies; + + /** + * The partitioning this reconciler uses. + *@since 3.0 + */ + private String fPartitioning; + + /** + * Creates a new reconciler with the following configuration: it is + * an incremental reconciler with a standard delay of 500 milliseconds. There + * are no predefined reconciling strategies. The partitioning it uses + * is the default partitioning {@link IDocumentExtension3#DEFAULT_PARTITIONING}. + */ + public this() { + super(); + fPartitioning= IDocumentExtension3.DEFAULT_PARTITIONING; + } + + /** + * Sets the document partitioning for this reconciler. + * + * @param partitioning the document partitioning for this reconciler + * @since 3.0 + */ + public void setDocumentPartitioning(String partitioning) { + Assert.isNotNull(partitioning); + fPartitioning= partitioning; + } + + /* + * @see dwtx.jface.text.reconciler.IReconcilerExtension#getDocumentPartitioning() + * @since 3.0 + */ + public String getDocumentPartitioning() { + return fPartitioning; + } + + /** + * Registers a given reconciling strategy for a particular content type. + * If there is already a strategy registered for this type, the new strategy + * is registered instead of the old one. + * + * @param strategy the reconciling strategy to register, or null to remove an existing one + * @param contentType the content type under which to register + */ + public void setReconcilingStrategy(IReconcilingStrategy strategy, String contentType) { + + Assert.isNotNull(contentType); + + if (fStrategies is null) + fStrategies= new HashMap(); + + if (strategy is null) + fStrategies.remove(contentType); + else { + fStrategies.put(contentType, cast(Object)strategy); + if (cast(IReconcilingStrategyExtension )strategy && getProgressMonitor() !is null) { + IReconcilingStrategyExtension extension= cast(IReconcilingStrategyExtension) strategy; + extension.setProgressMonitor(getProgressMonitor()); + } + } + } + + /* + * @see IReconciler#getReconcilingStrategy(String) + */ + public IReconcilingStrategy getReconcilingStrategy(String contentType) { + + Assert.isNotNull(contentType); + + if (fStrategies is null) + return null; + + return cast(IReconcilingStrategy) fStrategies.get(contentType); + } + + /** + * Processes a dirty region. If the dirty region is null the whole + * document is consider being dirty. The dirty region is partitioned by the + * document and each partition is handed over to a reconciling strategy registered + * for the partition's content type. + * + * @param dirtyRegion the dirty region to be processed + * @see AbstractReconciler#process(DirtyRegion) + */ + protected void process(DirtyRegion dirtyRegion) { + + IRegion region= dirtyRegion; + + if (region is null) + region= new Region(0, getDocument().getLength()); + + ITypedRegion[] regions= computePartitioning(region.getOffset(), region.getLength()); + + for (int i= 0; i < regions.length; i++) { + ITypedRegion r= regions[i]; + IReconcilingStrategy s= getReconcilingStrategy(r.getType()); + if (s is null) + continue; + + if(dirtyRegion !is null) + s.reconcile(dirtyRegion, r); + else + s.reconcile(r); + } + } + + /* + * @see AbstractReconciler#reconcilerDocumentChanged(IDocument) + * @since 2.0 + */ + protected void reconcilerDocumentChanged(IDocument document) { + if (fStrategies !is null) { + Iterator e= fStrategies.values().iterator(); + while (e.hasNext()) { + IReconcilingStrategy strategy= cast(IReconcilingStrategy) e.next(); + strategy.setDocument(document); + } + } + } + + /* + * @see AbstractReconciler#setProgressMonitor(IProgressMonitor) + * @since 2.0 + */ + public void setProgressMonitor(IProgressMonitor monitor) { + super.setProgressMonitor(monitor); + + if (fStrategies !is null) { + Iterator e= fStrategies.values().iterator(); + while (e.hasNext()) { + IReconcilingStrategy strategy= cast(IReconcilingStrategy) e.next(); + if ( cast(IReconcilingStrategyExtension)strategy ) { + IReconcilingStrategyExtension extension= cast(IReconcilingStrategyExtension) strategy; + extension.setProgressMonitor(monitor); + } + } + } + } + + /* + * @see AbstractReconciler#initialProcess() + * @since 2.0 + */ + protected void initialProcess() { + ITypedRegion[] regions= computePartitioning(0, getDocument().getLength()); + List contentTypes= new ArrayList(regions.length); + for (int i= 0; i < regions.length; i++) { + String contentType= regions[i].getType(); + if( contentTypes.contains(contentType)) + continue; + contentTypes.add(contentType); + IReconcilingStrategy s= getReconcilingStrategy(contentType); + if ( cast(IReconcilingStrategyExtension)s ) { + IReconcilingStrategyExtension e= cast(IReconcilingStrategyExtension) s; + e.initialReconcile(); + } + } + } + + /** + * Computes and returns the partitioning for the given region of the input document + * of the reconciler's connected text viewer. + * + * @param offset the region offset + * @param length the region length + * @return the computed partitioning + * @since 3.0 + */ + private ITypedRegion[] computePartitioning(int offset, int length) { + ITypedRegion[] regions= null; + try { + regions= TextUtilities.computePartitioning(getDocument(), getDocumentPartitioning(), offset, length, false); + } catch (BadLocationException x) { + regions= new ITypedRegion[0]; + } + return regions; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/revisions/IRevisionListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/revisions/IRevisionListener.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,42 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.text.revisions.IRevisionListener; + +import dwtx.jface.text.revisions.IRevisionRulerColumnExtension; // packageimport +import dwtx.jface.text.revisions.RevisionRange; // packageimport +import dwtx.jface.text.revisions.IRevisionRulerColumn; // packageimport +import dwtx.jface.text.revisions.RevisionEvent; // packageimport +import dwtx.jface.text.revisions.RevisionInformation; // packageimport +import dwtx.jface.text.revisions.Revision; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * A listener which is notified when revision information changes. + * + * @see RevisionInformation + * @see IRevisionRulerColumnExtension + * @since 3.3 + */ +public interface IRevisionListener { + /** + * Notifies the receiver that the revision information has been updated. This typically occurs + * when revision information is being displayed in an editor and the annotated document is + * modified. + * + * @param e the revision event describing the change + */ + void revisionInformationChanged(RevisionEvent e); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/revisions/IRevisionRulerColumn.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/revisions/IRevisionRulerColumn.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,52 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.text.revisions.IRevisionRulerColumn; + +import dwtx.jface.text.revisions.IRevisionListener; // packageimport +import dwtx.jface.text.revisions.IRevisionRulerColumnExtension; // packageimport +import dwtx.jface.text.revisions.RevisionRange; // packageimport +import dwtx.jface.text.revisions.RevisionEvent; // packageimport +import dwtx.jface.text.revisions.RevisionInformation; // packageimport +import dwtx.jface.text.revisions.Revision; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.source.IVerticalRulerColumn; +import dwtx.jface.text.source.IVerticalRulerInfo; +import dwtx.jface.text.source.IVerticalRulerInfoExtension; + +/** + * A vertical ruler column capable of displaying revision (annotate) information. + * + * In order to provide backward compatibility for clients of + * IRevisionRulerColumn, extension interfaces are used as a means + * of evolution. The following extension interfaces exist: + *
                      + *
                    • {@link IRevisionRulerColumnExtension} since + * version 3.3 allowing to register a selection listener on revisions and a configurable rendering mode. + *
                    • + *
                    + * + * @since 3.2 + * @see RevisionInformation + * @see IRevisionRulerColumnExtension + */ +public interface IRevisionRulerColumn : IVerticalRulerColumn, IVerticalRulerInfo, IVerticalRulerInfoExtension { + /** + * Sets the revision information. + * + * @param info the new revision information, or null to reset the ruler + */ + void setRevisionInformation(RevisionInformation info); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/revisions/IRevisionRulerColumnExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/revisions/IRevisionRulerColumnExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,133 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.text.revisions.IRevisionRulerColumnExtension; + +import dwtx.jface.text.revisions.IRevisionListener; // packageimport +import dwtx.jface.text.revisions.RevisionRange; // packageimport +import dwtx.jface.text.revisions.IRevisionRulerColumn; // packageimport +import dwtx.jface.text.revisions.RevisionEvent; // packageimport +import dwtx.jface.text.revisions.RevisionInformation; // packageimport +import dwtx.jface.text.revisions.Revision; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.core.runtime.Assert; +import dwtx.jface.viewers.ISelectionProvider; + + static this(){ + IRevisionRulerColumnExtension_AUTHOR= new IRevisionRulerColumnExtension_RenderingMode("Author"); //$NON-NLS-1$ + IRevisionRulerColumnExtension_AGE= new IRevisionRulerColumnExtension_RenderingMode("Age"); //$NON-NLS-1$ + IRevisionRulerColumnExtension_AUTHOR_SHADED_BY_AGE= new IRevisionRulerColumnExtension_RenderingMode("Both"); //$NON-NLS-1$ + } + + /** + * Rendering mode type-safe enum. + */ + final class RenderingMode { + private const String fName; + private this(String name) { + Assert.isLegal(name !is null); + fName= name; + } + /** + * Returns the name of the rendering mode. + * @return the name of the rendering mode + */ + public String name() { + return fName; + } + } + alias RenderingMode IRevisionRulerColumnExtension_RenderingMode; + + + /** + * Rendering mode that assigns a unique color to each revision author. + */ + static const RenderingMode IRevisionRulerColumnExtension_AUTHOR; + /** + * Rendering mode that assigns colors to revisions by their age. + *

                    + * Currently the most recent revision is red, the oldest is a faint yellow. + * The coloring scheme can change in future releases. + *

                    + */ + static const RenderingMode IRevisionRulerColumnExtension_AGE; + /** + * Rendering mode that assigns unique colors per revision author and + * uses different color intensity depending on the age. + *

                    + * Currently it selects lighter colors for older revisions and more intense + * colors for more recent revisions. + * The coloring scheme can change in future releases. + *

                    + */ + static const RenderingMode IRevisionRulerColumnExtension_AUTHOR_SHADED_BY_AGE; + +/** + * Extension interface for {@link IRevisionRulerColumn}. + *

                    + * Introduces the ability to register a selection listener on revisions and configurable rendering + * modes. + *

                    + * + * @see IRevisionRulerColumn + * @since 3.3 + */ +public interface IRevisionRulerColumnExtension { + + /** + * Changes the rendering mode and triggers redrawing if needed. + * + * @param mode the rendering mode + */ + void setRevisionRenderingMode(RenderingMode mode); + + /** + * Enables showing the revision id. + * + * @param show true to show the revision, false to hide it + */ + void showRevisionId(bool show); + + /** + * Enables showing the revision author. + * + * @param show true to show the author, false to hide it + */ + void showRevisionAuthor(bool show); + + /** + * Returns the revision selection provider. + * + * @return the revision selection provider + */ + ISelectionProvider getRevisionSelectionProvider(); + + /** + * Adds a revision listener that will be notified when the displayed revision information + * changes. + * + * @param listener the listener to add + */ + void addRevisionListener(IRevisionListener listener); + + /** + * Removes a previously registered revision listener; nothing happens if listener + * was not registered with the receiver. + * + * @param listener the listener to remove + */ + void removeRevisionListener(IRevisionListener listener); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/revisions/Revision.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/revisions/Revision.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,170 @@ +/******************************************************************************* + * 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.text.revisions.Revision; + +import dwtx.jface.text.revisions.IRevisionListener; // packageimport +import dwtx.jface.text.revisions.IRevisionRulerColumnExtension; // packageimport +import dwtx.jface.text.revisions.RevisionRange; // packageimport +import dwtx.jface.text.revisions.IRevisionRulerColumn; // packageimport +import dwtx.jface.text.revisions.RevisionEvent; // packageimport +import dwtx.jface.text.revisions.RevisionInformation; // packageimport + + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; +import dwtx.dwtxhelper.Date; + +import dwt.graphics.RGB; +import dwtx.jface.internal.text.revisions.ChangeRegion; +import dwtx.jface.internal.text.revisions.Hunk; +import dwtx.jface.text.IInformationControlCreator; +import dwtx.jface.text.source.ILineRange; + +/** + * Describes a revision of a document. A revision consists of one ore more {@link ILineRange}s. + *

                    + * Clients may subclass. + *

                    + * + * @since 3.2 + */ +public abstract class Revision { + /** The original list of change regions, element type: {@link ChangeRegion}. */ + private const List fChangeRegions; + /** + * The cached list of adjusted ranges, element type: {@link RevisionRange}. null + * if the list must be re-computed. Unmodifiable. + * + * @since 3.3 + */ + private List fRanges= null; + + /** + * Creates a new revision. + */ + protected this() { + fChangeRegions= new ArrayList(); + } + + /** + * Adds a line range to this revision. The range must be non-empty and have a legal start line + * (not -1). + * + * @param range a line range that was changed with this revision + * @throws IndexOutOfBoundsException if the line range is empty or has a negative start line + */ + public final void addRange(ILineRange range) { + fChangeRegions.add(new ChangeRegion(this, range)); + } + + /** + * Returns the contained {@link RevisionRange}s adapted to the current diff state. The returned + * information is only valid at the moment it is returned, and may change as the annotated + * document is modified. + * + * @return an unmodifiable view of the contained ranges (element type: {@link RevisionRange}) + */ + public final List getRegions() { + if (fRanges is null) { + List ranges= new ArrayList(fChangeRegions.size()); + for (Iterator it= fChangeRegions.iterator(); it.hasNext();) { + ChangeRegion region= cast(ChangeRegion) it.next(); + for (Iterator inner= region.getAdjustedRanges().iterator(); inner.hasNext();) { + ILineRange range= cast(ILineRange) inner.next(); + ranges.add(new RevisionRange(this, range)); + } + } + fRanges= Collections.unmodifiableList(ranges); + } + return fRanges; + } + + /** + * Adjusts the revision information to the given diff information. Any previous diff information + * is discarded. + * + * @param hunks the diff hunks to adjust the revision information to + * @since 3.3 + */ + final void applyDiff(Hunk[] hunks) { + fRanges= null; // mark for recomputation + for (Iterator regions= fChangeRegions.iterator(); regions.hasNext();) { + ChangeRegion region= cast(ChangeRegion) regions.next(); + region.clearDiff(); + for (int i= 0; i < hunks.length; i++) { + Hunk hunk= hunks[i]; + region.adjustTo(hunk); + } + } + } + + /** + * Returns the hover information that will be shown when the user hovers over the a change + * region of this revision. + *

                    + * Note: The hover information control which is used to display the information + * must be able process the given object. If the default information control creator is used + * the supported format is simple text, full HTML or an HTML fragment. + *

                    + * + * @return the hover information for this revision or null for no hover + * @see RevisionInformation#setHoverControlCreator(IInformationControlCreator) + */ + public abstract Object getHoverInfo(); + + /** + * Returns the author color for this revision. This color can be used to visually distinguish + * one revision from another, for example as background color. + *

                    + * Revisions from the same author must return the same color and revisions from different authors + * must return distinct colors.

                    + * + * @return the RGB color for this revision's author + */ + public abstract RGB getColor(); + + /** + * Returns the unique (within the document) id of this revision. This may be the version string + * or a different identifier. + * + * @return the id of this revision + */ + public abstract String getId(); + + /** + * Returns the modification date of this revision. + * + * @return the modification date of this revision + */ + public abstract Date getDate(); + + /* + * @see java.lang.Object#toString() + */ + public override String toString() { + return "Revision " ~ getId(); //$NON-NLS-1$ + } + + /** + * Returns the display string for the author of this revision. + *

                    + * Subclasses should replace - the default implementation returns the empty string. + *

                    + * + * @return the author name + * @since 3.3 + */ + public String getAuthor() { + return ""; //$NON-NLS-1$ + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/revisions/RevisionEvent.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/revisions/RevisionEvent.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,59 @@ +/******************************************************************************* + * 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 + * 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.text.revisions.RevisionEvent; + +import dwtx.jface.text.revisions.IRevisionListener; // packageimport +import dwtx.jface.text.revisions.IRevisionRulerColumnExtension; // packageimport +import dwtx.jface.text.revisions.RevisionRange; // packageimport +import dwtx.jface.text.revisions.IRevisionRulerColumn; // packageimport +import dwtx.jface.text.revisions.RevisionInformation; // packageimport +import dwtx.jface.text.revisions.Revision; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.core.runtime.Assert; + + +/** + * Informs about a change of revision information. + *

                    + * Clients may use but not instantiate this class. + *

                    + * + * @since 3.3 + * @noinstantiate This class is not intended to be instantiated by clients. + */ +public final class RevisionEvent { + + private const RevisionInformation fInformation; + + /** + * Creates a new event. + * + * @param information the revision info + */ + public this(RevisionInformation information) { + Assert.isLegal(information !is null); + fInformation= information; + } + + /** + * Returns the revision information that has changed. + * + * @return the revision information that has changed + */ + public RevisionInformation getRevisionInformation() { + return fInformation; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/revisions/RevisionInformation.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/revisions/RevisionInformation.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,186 @@ +/******************************************************************************* + * 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 + * 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.text.revisions.RevisionInformation; + +import dwtx.jface.text.revisions.IRevisionListener; // packageimport +import dwtx.jface.text.revisions.IRevisionRulerColumnExtension; // packageimport +import dwtx.jface.text.revisions.RevisionRange; // packageimport +import dwtx.jface.text.revisions.IRevisionRulerColumn; // packageimport +import dwtx.jface.text.revisions.RevisionEvent; // packageimport +import dwtx.jface.text.revisions.Revision; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + + + +import dwtx.core.runtime.Assert; +import dwtx.jface.internal.text.revisions.Hunk; +import dwtx.jface.text.IInformationControlCreator; +import dwtx.jface.text.ITextHoverExtension; +import dwtx.jface.text.information.IInformationProviderExtension2; + +/** + * Encapsulates revision information for one line-based document. + *

                    + * Clients may instantiate. + *

                    + * + * @since 3.2 + * @see Revision + */ +public final class RevisionInformation : ITextHoverExtension, IInformationProviderExtension2 { + /** The revisions, element type: {@link Revision}. */ + private const List fRevisions; + /** A unmodifiable view of fRevisions. */ + private const List fRORevisions; + /** + * The flattened list of {@link RevisionRange}s, unmodifiable. null if the list + * must be re-computed. + * + * @since 3.3 + */ + private List fRanges= null; + + /** + * The hover control creator. Can be null. + * + * @since 3.3 + */ + private IInformationControlCreator fHoverControlCreator; + + /** + * The information presenter control creator. Can be null. + * + * @since 3.3 + */ + private IInformationControlCreator fInformationPresenterControlCreator; + + /** + * Creates a new revision information model. + */ + public this() { + fRevisions= new ArrayList(); + fRORevisions= Collections.unmodifiableList(fRevisions); + } + + /** + * Adds a revision. + * + * @param revision a revision + */ + public void addRevision(Revision revision) { + Assert.isLegal(revision !is null); + fRevisions.add(revision); + } + + /** + * Returns the contained revisions. + * + * @return an unmodifiable view of the contained revisions (element type: {@link Revision}) + */ + public List getRevisions() { + return fRORevisions; + } + + /** + * Returns the line ranges of this revision information. The returned information is only valid + * at the moment it is returned, and may change as the annotated document is modified. See + * {@link IRevisionListener} for a way to be informed when the revision information changes. The + * returned list is sorted by document offset. + * + * @return an unmodifiable view of the line ranges (element type: {@link RevisionRange}) + * @see IRevisionListener + * @since 3.3 + */ + public List getRanges() { + if (fRanges is null) { + List ranges= new ArrayList(fRevisions.size() * 2); // wild size guess + for (Iterator it= fRevisions.iterator(); it.hasNext();) { + Revision revision= cast(Revision) it.next(); + ranges.addAll(revision.getRegions()); + } + + // sort by start line + Collections.sort(ranges, new class() Comparator { + public int compare(Object o1, Object o2) { + RevisionRange r1= cast(RevisionRange) o1; + RevisionRange r2= cast(RevisionRange) o2; + + return r1.getStartLine() - r2.getStartLine(); + } + }); + + fRanges= Collections.unmodifiableList(ranges); + } + return fRanges; + } + + /** + * Adjusts the revision information to the given diff information. Any previous diff information is discarded. Note: This is an internal framework method and must not be called by clients. + * + * @param hunks the diff hunks to adjust the revision information to + * @since 3.3 + * @noreference This method is not intended to be referenced by clients. + */ + public void applyDiff(Hunk[] hunks) { + fRanges= null; // mark for recomputation + for (Iterator revisions= getRevisions().iterator(); revisions.hasNext();) + (cast(Revision) revisions.next()).applyDiff(hunks); + } + + /* + * @see dwtx.jface.text.ITextHoverExtension#getHoverControlCreator() + * @since 3.3 + */ + public IInformationControlCreator getHoverControlCreator() { + return fHoverControlCreator; + } + + /** + * {@inheritDoc} + * @return the information control creator or null + * @since 3.3 + */ + public IInformationControlCreator getInformationPresenterControlCreator() { + return fInformationPresenterControlCreator; + } + + /** + * Sets the hover control creator. + *

                    + * Note: The created information control must be able to display the object + * returned by the concrete implementation of {@link Revision#getHoverInfo()}. + *

                    + * + * @param creator the control creator + * @since 3.3 + */ + public void setHoverControlCreator(IInformationControlCreator creator) { + fHoverControlCreator= creator; + } + + /** + * Sets the information presenter control creator. + * + * @param creator the control creator + * @since 3.3 + */ + public void setInformationPresenterControlCreator(IInformationControlCreator creator) { + fInformationPresenterControlCreator= creator; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/revisions/RevisionRange.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/revisions/RevisionRange.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,77 @@ +/******************************************************************************* + * 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 + * 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.text.revisions.RevisionRange; + +import dwtx.jface.text.revisions.IRevisionListener; // packageimport +import dwtx.jface.text.revisions.IRevisionRulerColumnExtension; // packageimport +import dwtx.jface.text.revisions.IRevisionRulerColumn; // packageimport +import dwtx.jface.text.revisions.RevisionEvent; // packageimport +import dwtx.jface.text.revisions.RevisionInformation; // packageimport +import dwtx.jface.text.revisions.Revision; // packageimport + + +import dwt.dwthelper.utils; +import tango.text.convert.Format; + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.source.ILineRange; + + +/** + * An unmodifiable line range that belongs to a {@link Revision}. + * + * @since 3.3 + * @noinstantiate This class is not intended to be instantiated by clients. + */ +public final class RevisionRange : ILineRange { + private const Revision fRevision; + private const int fStartLine; + private const int fNumberOfLines; + + this(Revision revision, ILineRange range) { + Assert.isLegal(revision !is null); + fRevision= revision; + fStartLine= range.getStartLine(); + fNumberOfLines= range.getNumberOfLines(); + } + + /** + * Returns the revision that this range belongs to. + * + * @return the revision that this range belongs to + */ + public Revision getRevision() { + return fRevision; + } + + /* + * @see dwtx.jface.text.source.ILineRange#getStartLine() + */ + public int getStartLine() { + return fStartLine; + } + + /* + * @see dwtx.jface.text.source.ILineRange#getNumberOfLines() + */ + public int getNumberOfLines() { + return fNumberOfLines; + } + + /* + * @see java.lang.Object#toString() + */ + public override String toString() { + return Format("RevisionRange [{}, [{}+{})]", fRevision.toString(), getStartLine(), getNumberOfLines()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/BufferedRuleBasedScanner.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/BufferedRuleBasedScanner.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,170 @@ +/******************************************************************************* + * 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 + * 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.text.rules.BufferedRuleBasedScanner; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + +import dwt.dwthelper.utils; + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; + +/** + * A buffered rule based scanner. The buffer always contains a section + * of a fixed size of the document to be scanned. Completely adheres to + * the contract of RuleBasedScanner. + */ +public class BufferedRuleBasedScanner : RuleBasedScanner { + + /** The default buffer size. Value = 500 */ + private const static int DEFAULT_BUFFER_SIZE= 500; + /** The actual size of the buffer. Initially set to DEFAULT_BUFFER_SIZE */ + private int fBufferSize= DEFAULT_BUFFER_SIZE; + /** The buffer */ + private char[] fBuffer; + /** The offset of the document at which the buffer starts */ + private int fStart; + /** The offset of the document at which the buffer ends */ + private int fEnd; + /** The cached length of the document */ + private int fDocumentLength; + + + /** + * Creates a new buffered rule based scanner which does + * not have any rule and a default buffer size of 500 characters. + */ + protected this() { + super(); + fBuffer= new char[DEFAULT_BUFFER_SIZE]; + fBuffer[] = 0; + } + + /** + * Creates a new buffered rule based scanner which does + * not have any rule. The buffer size is set to the given + * number of characters. + * + * @param size the buffer size + */ + public this(int size) { + super(); + fBuffer= new char[DEFAULT_BUFFER_SIZE]; + fBuffer[] = 0; + setBufferSize(size); + } + + /** + * Sets the buffer to the given number of characters. + * + * @param size the buffer size + */ + protected void setBufferSize(int size) { + Assert.isTrue(size > 0); + fBufferSize= size; + fBuffer= new char[size]; + fBuffer[] = 0; + } + + /** + * Shifts the buffer so that the buffer starts at the + * given document offset. + * + * @param offset the document offset at which the buffer starts + */ + private void shiftBuffer(int offset) { + + fStart= offset; + fEnd= fStart + fBufferSize; + if (fEnd > fDocumentLength) + fEnd= fDocumentLength; + + try { + + String content= fDocument.get(fStart, fEnd - fStart); + content.getChars(0, fEnd - fStart, fBuffer, 0); + + } catch (BadLocationException x) { + } + } + + /* + * @see RuleBasedScanner#setRange(IDocument, int, int) + */ + public void setRange(IDocument document, int offset, int length) { + + super.setRange(document, offset, length); + + fDocumentLength= document.getLength(); + shiftBuffer(offset); + } + + /* + * @see RuleBasedScanner#read() + */ + public int read() { + fColumn= UNDEFINED; + if (fOffset >= fRangeEnd) { + ++ fOffset; + return EOF; + } + + if (fOffset is fEnd) + shiftBuffer(fEnd); + else if (fOffset < fStart || fEnd < fOffset) + shiftBuffer(fOffset); + + return fBuffer[fOffset++ - fStart]; + } + + /* + * @see RuleBasedScanner#unread() + */ + public void unread() { + + if (fOffset is fStart) + shiftBuffer(Math.max(0, fStart - (fBufferSize / 2))); + + --fOffset; + fColumn= UNDEFINED; + } +} + + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/DefaultDamagerRepairer.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/DefaultDamagerRepairer.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,259 @@ +/******************************************************************************* + * 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 + * 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.text.rules.DefaultDamagerRepairer; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + +import dwt.dwthelper.utils; + + + + + +import dwt.DWT; +import dwt.custom.StyleRange; +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITypedRegion; +import dwtx.jface.text.Region; +import dwtx.jface.text.TextAttribute; +import dwtx.jface.text.TextPresentation; +import dwtx.jface.text.presentation.IPresentationDamager; +import dwtx.jface.text.presentation.IPresentationRepairer; + + +/** + * A standard implementation of a syntax driven presentation damager + * and presentation repairer. It uses a token scanner to scan + * the document and to determine its damage and new text presentation. + * The tokens returned by the scanner are supposed to return text attributes + * as their data. + * + * @see ITokenScanner + * @since 2.0 + */ +public class DefaultDamagerRepairer : IPresentationDamager, IPresentationRepairer { + + + /** The document this object works on */ + protected IDocument fDocument; + /** The scanner it uses */ + protected ITokenScanner fScanner; + /** The default text attribute if non is returned as data by the current token */ + protected TextAttribute fDefaultTextAttribute; + + /** + * Creates a damager/repairer that uses the given scanner and returns the given default + * text attribute if the current token does not carry a text attribute. + * + * @param scanner the token scanner to be used + * @param defaultTextAttribute the text attribute to be returned if non is specified by the current token, + * may not be null + * + * @deprecated use DefaultDamagerRepairer(ITokenScanner) instead + */ + public this(ITokenScanner scanner, TextAttribute defaultTextAttribute) { + + Assert.isNotNull(defaultTextAttribute); + + fScanner= scanner; + fDefaultTextAttribute= defaultTextAttribute; + } + + /** + * Creates a damager/repairer that uses the given scanner. The scanner may not be null + * and is assumed to return only token that carry text attributes. + * + * @param scanner the token scanner to be used, may not be null + */ + public this(ITokenScanner scanner) { + + Assert.isNotNull(cast(Object)scanner); + + fScanner= scanner; + fDefaultTextAttribute= new TextAttribute(null); + } + + /* + * @see IPresentationDamager#setDocument(IDocument) + * @see IPresentationRepairer#setDocument(IDocument) + */ + public void setDocument(IDocument document) { + fDocument= document; + } + + + //---- IPresentationDamager + + /** + * Returns the end offset of the line that contains the specified offset or + * if the offset is inside a line delimiter, the end offset of the next line. + * + * @param offset the offset whose line end offset must be computed + * @return the line end offset for the given offset + * @exception BadLocationException if offset is invalid in the current document + */ + protected int endOfLineOf(int offset) { + + IRegion info= fDocument.getLineInformationOfOffset(offset); + if (offset <= info.getOffset() + info.getLength()) + return info.getOffset() + info.getLength(); + + int line= fDocument.getLineOfOffset(offset); + try { + info= fDocument.getLineInformation(line + 1); + return info.getOffset() + info.getLength(); + } catch (BadLocationException x) { + return fDocument.getLength(); + } + } + + /* + * @see IPresentationDamager#getDamageRegion(ITypedRegion, DocumentEvent, bool) + */ + public IRegion getDamageRegion(ITypedRegion partition, DocumentEvent e, bool documentPartitioningChanged) { + + if (!documentPartitioningChanged) { + try { + + IRegion info= fDocument.getLineInformationOfOffset(e.getOffset()); + int start= Math.max(partition.getOffset(), info.getOffset()); + + int end= e.getOffset() + (e.getText() is null ? e.getLength() : e.getText().length()); + + if (info.getOffset() <= end && end <= info.getOffset() + info.getLength()) { + // optimize the case of the same line + end= info.getOffset() + info.getLength(); + } else + end= endOfLineOf(end); + + end= Math.min(partition.getOffset() + partition.getLength(), end); + return new Region(start, end - start); + + } catch (BadLocationException x) { + } + } + + return partition; + } + + //---- IPresentationRepairer + + /* + * @see IPresentationRepairer#createPresentation(TextPresentation, ITypedRegion) + */ + public void createPresentation(TextPresentation presentation, ITypedRegion region) { + + if (fScanner is null) { + // will be removed if deprecated constructor will be removed + addRange(presentation, region.getOffset(), region.getLength(), fDefaultTextAttribute); + return; + } + + int lastStart= region.getOffset(); + int length= 0; + bool firstToken= true; + IToken lastToken= Token.UNDEFINED; + TextAttribute lastAttribute= getTokenTextAttribute(lastToken); + + fScanner.setRange(fDocument, lastStart, region.getLength()); + + while (true) { + IToken token= fScanner.nextToken(); + if (token.isEOF()) + break; + + TextAttribute attribute= getTokenTextAttribute(token); + if (lastAttribute !is null && lastAttribute.equals(attribute)) { + length += fScanner.getTokenLength(); + firstToken= false; + } else { + if (!firstToken) + addRange(presentation, lastStart, length, lastAttribute); + firstToken= false; + lastToken= token; + lastAttribute= attribute; + lastStart= fScanner.getTokenOffset(); + length= fScanner.getTokenLength(); + } + } + + addRange(presentation, lastStart, length, lastAttribute); + } + + /** + * Returns a text attribute encoded in the given token. If the token's + * data is not null and a text attribute it is assumed that + * it is the encoded text attribute. It returns the default text attribute + * if there is no encoded text attribute found. + * + * @param token the token whose text attribute is to be determined + * @return the token's text attribute + */ + protected TextAttribute getTokenTextAttribute(IToken token) { + Object data= token.getData(); + if ( cast(TextAttribute)data ) + return cast(TextAttribute) data; + return fDefaultTextAttribute; + } + + /** + * Adds style information to the given text presentation. + * + * @param presentation the text presentation to be extended + * @param offset the offset of the range to be styled + * @param length the length of the range to be styled + * @param attr the attribute describing the style of the range to be styled + */ + protected void addRange(TextPresentation presentation, int offset, int length, TextAttribute attr) { + if (attr !is null) { + int style= attr.getStyle(); + int fontStyle= style & (DWT.ITALIC | DWT.BOLD | DWT.NORMAL); + StyleRange styleRange= new StyleRange(offset, length, attr.getForeground(), attr.getBackground(), fontStyle); + styleRange.strikeout= (style & TextAttribute.STRIKETHROUGH) !is 0; + styleRange.underline= (style & TextAttribute.UNDERLINE) !is 0; + styleRange.font= attr.getFont(); + presentation.addStyleRange(styleRange); + } + } +} + + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/DefaultPartitioner.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/DefaultPartitioner.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,760 @@ +/******************************************************************************* + * 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 + * 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.text.rules.DefaultPartitioner; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.dwtxhelper.Collection; + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.BadPositionCategoryException; +import dwtx.jface.text.DefaultPositionUpdater; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.DocumentRewriteSession; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentPartitioner; +import dwtx.jface.text.IDocumentPartitionerExtension; +import dwtx.jface.text.IDocumentPartitionerExtension2; +import dwtx.jface.text.IDocumentPartitionerExtension3; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITypedRegion; +import dwtx.jface.text.Position; +import dwtx.jface.text.Region; +import dwtx.jface.text.TextUtilities; +import dwtx.jface.text.TypedPosition; +import dwtx.jface.text.TypedRegion; + + + +/** + * A standard implementation of a document partitioner. It uses a partition + * token scanner to scan the document and to determine the document's + * partitioning. The tokens returned by the scanner are supposed to return the + * partition type as their data. The partitioner remembers the document's + * partitions in the document itself rather than maintaining its own data + * structure. + * + * @see IPartitionTokenScanner + * @since 2.0 + * @deprecated As of 3.1, replaced by {@link dwtx.jface.text.rules.FastPartitioner} instead + */ +public class DefaultPartitioner : IDocumentPartitioner, IDocumentPartitionerExtension, IDocumentPartitionerExtension2, IDocumentPartitionerExtension3 { + + /** + * The position category this partitioner uses to store the document's partitioning information. + * @deprecated As of 3.0, use getManagingPositionCategories() instead. + */ + public const static String CONTENT_TYPES_CATEGORY= "__content_types_category"; //$NON-NLS-1$ + + + /** The partitioner's scanner */ + protected IPartitionTokenScanner fScanner; + /** The legal content types of this partitioner */ + protected String[] fLegalContentTypes; + /** The partitioner's document */ + protected IDocument fDocument; + /** The document length before a document change occurred */ + protected int fPreviousDocumentLength; + /** The position updater used to for the default updating of partitions */ + protected DefaultPositionUpdater fPositionUpdater; + /** The offset at which the first changed partition starts */ + protected int fStartOffset; + /** The offset at which the last changed partition ends */ + protected int fEndOffset; + /**The offset at which a partition has been deleted */ + protected int fDeleteOffset; + /** + * The position category this partitioner uses to store the document's partitioning information. + * @since 3.0 + */ + private String fPositionCategory; + /** + * The active document rewrite session. + * @since 3.1 + */ + private DocumentRewriteSession fActiveRewriteSession; + /** + * Flag indicating whether this partitioner has been initialized. + * @since 3.1 + */ + private bool fIsInitialized= false; + + /** + * Creates a new partitioner that uses the given scanner and may return + * partitions of the given legal content types. + * + * @param scanner the scanner this partitioner is supposed to use + * @param legalContentTypes the legal content types of this partitioner + */ + public this(IPartitionTokenScanner scanner, String[] legalContentTypes) { + fScanner= scanner; + fLegalContentTypes= TextUtilities.copy(legalContentTypes); + fPositionCategory= CONTENT_TYPES_CATEGORY ~ Integer.toString(toHash()); + fPositionUpdater= new DefaultPositionUpdater(fPositionCategory); + } + + /* + * @see dwtx.jface.text.IDocumentPartitionerExtension2#getManagingPositionCategories() + * @since 3.0 + */ + public String[] getManagingPositionCategories() { + return [ fPositionCategory ]; + } + + /* + * @see dwtx.jface.text.IDocumentPartitioner#connect(dwtx.jface.text.IDocument) + */ + public void connect(IDocument document) { + connect(document, false); + } + + /* + * @see dwtx.jface.text.IDocumentPartitionerExtension3#connect(dwtx.jface.text.IDocument, bool) + * @since 3.1 + */ + public void connect(IDocument document, bool delayInitialization) { + Assert.isNotNull(cast(Object)document); + Assert.isTrue(!document.containsPositionCategory(fPositionCategory)); + + fDocument= document; + fDocument.addPositionCategory(fPositionCategory); + + fIsInitialized= false; + if (!delayInitialization) + checkInitialization(); + } + + /* + * @since 3.1 + */ + protected final void checkInitialization() { + if (!fIsInitialized) + initialize(); + } + + /** + * Performs the initial partitioning of the partitioner's document. + */ + protected void initialize() { + fIsInitialized= true; + fScanner.setRange(fDocument, 0, fDocument.getLength()); + + try { + IToken token= fScanner.nextToken(); + while (!token.isEOF()) { + + String contentType= getTokenContentType(token); + + if (isSupportedContentType(contentType)) { + TypedPosition p= new TypedPosition(fScanner.getTokenOffset(), fScanner.getTokenLength(), contentType); + fDocument.addPosition(fPositionCategory, p); + } + + token= fScanner.nextToken(); + } + } catch (BadLocationException x) { + // cannot happen as offsets come from scanner + } catch (BadPositionCategoryException x) { + // cannot happen if document has been connected before + } + } + + /* + * @see IDocumentPartitioner#disconnect() + */ + public void disconnect() { + + Assert.isTrue(fDocument.containsPositionCategory(fPositionCategory)); + + try { + fDocument.removePositionCategory(fPositionCategory); + } catch (BadPositionCategoryException x) { + // can not happen because of Assert + } + } + + /* + * @see IDocumentPartitioner#documentAboutToBeChanged(DocumentEvent) + */ + public void documentAboutToBeChanged(DocumentEvent e) { + if (fIsInitialized) { + + Assert.isTrue(e.getDocument() is fDocument); + + fPreviousDocumentLength= e.getDocument().getLength(); + fStartOffset= -1; + fEndOffset= -1; + fDeleteOffset= -1; + } + } + + /* + * @see IDocumentPartitioner#documentChanged(DocumentEvent) + */ + public bool documentChanged(DocumentEvent e) { + if (fIsInitialized) { + IRegion region= documentChanged2(e); + return (region !is null); + } + return false; + } + + /** + * Helper method for tracking the minimal region containing all partition changes. + * If offset is smaller than the remembered offset, offset + * will from now on be remembered. If offset + length is greater than + * the remembered end offset, it will be remembered from now on. + * + * @param offset the offset + * @param length the length + */ + private void rememberRegion(int offset, int length) { + // remember start offset + if (fStartOffset is -1) + fStartOffset= offset; + else if (offset < fStartOffset) + fStartOffset= offset; + + // remember end offset + int endOffset= offset + length; + if (fEndOffset is -1) + fEndOffset= endOffset; + else if (endOffset > fEndOffset) + fEndOffset= endOffset; + } + + /** + * Remembers the given offset as the deletion offset. + * + * @param offset the offset + */ + private void rememberDeletedOffset(int offset) { + fDeleteOffset= offset; + } + + /** + * Creates the minimal region containing all partition changes using the + * remembered offset, end offset, and deletion offset. + * + * @return the minimal region containing all the partition changes + */ + private IRegion createRegion() { + if (fDeleteOffset is -1) { + if (fStartOffset is -1 || fEndOffset is -1) + return null; + return new Region(fStartOffset, fEndOffset - fStartOffset); + } else if (fStartOffset is -1 || fEndOffset is -1) { + return new Region(fDeleteOffset, 0); + } else { + int offset= Math.min(fDeleteOffset, fStartOffset); + int endOffset= Math.max(fDeleteOffset, fEndOffset); + return new Region(offset, endOffset - offset); + } + } + + /* + * @see IDocumentPartitionerExtension#documentChanged2(DocumentEvent) + * @since 2.0 + */ + public IRegion documentChanged2(DocumentEvent e) { + + if (!fIsInitialized) + return null; + + try { + + IDocument d= e.getDocument(); + Position[] category= d.getPositions(fPositionCategory); + IRegion line= d.getLineInformationOfOffset(e.getOffset()); + int reparseStart= line.getOffset(); + int partitionStart= -1; + String contentType= null; + int newLength= e.getText() is null ? 0 : e.getText().length(); + + int first= d.computeIndexInCategory(fPositionCategory, reparseStart); + if (first > 0) { + TypedPosition partition= cast(TypedPosition) category[first - 1]; + if (partition.includes(reparseStart)) { + partitionStart= partition.getOffset(); + contentType= partition.getType(); + if (e.getOffset() is partition.getOffset() + partition.getLength()) + reparseStart= partitionStart; + -- first; + } else if (reparseStart is e.getOffset() && reparseStart is partition.getOffset() + partition.getLength()) { + partitionStart= partition.getOffset(); + contentType= partition.getType(); + reparseStart= partitionStart; + -- first; + } else { + partitionStart= partition.getOffset() + partition.getLength(); + contentType= IDocument.DEFAULT_CONTENT_TYPE; + } + } + + fPositionUpdater.update(e); + for (int i= first; i < category.length; i++) { + Position p= category[i]; + if (p.isDeleted) { + rememberDeletedOffset(e.getOffset()); + break; + } + } + category= d.getPositions(fPositionCategory); + + fScanner.setPartialRange(d, reparseStart, d.getLength() - reparseStart, contentType, partitionStart); + + int lastScannedPosition= reparseStart; + IToken token= fScanner.nextToken(); + + while (!token.isEOF()) { + + contentType= getTokenContentType(token); + + if (!isSupportedContentType(contentType)) { + token= fScanner.nextToken(); + continue; + } + + int start= fScanner.getTokenOffset(); + int length= fScanner.getTokenLength(); + + lastScannedPosition= start + length - 1; + + // remove all affected positions + while (first < category.length) { + TypedPosition p= cast(TypedPosition) category[first]; + if (lastScannedPosition >= p.offset + p.length || + (p.overlapsWith(start, length) && + (!d.containsPosition(fPositionCategory, start, length) || + !contentType.equals(p.getType())))) { + + rememberRegion(p.offset, p.length); + d.removePosition(fPositionCategory, p); + ++ first; + + } else + break; + } + + // if position already exists and we have scanned at least the + // area covered by the event, we are done + if (d.containsPosition(fPositionCategory, start, length)) { + if (lastScannedPosition >= e.getOffset() + newLength) + return createRegion(); + ++ first; + } else { + // insert the new type position + try { + d.addPosition(fPositionCategory, new TypedPosition(start, length, contentType)); + rememberRegion(start, length); + } catch (BadPositionCategoryException x) { + } catch (BadLocationException x) { + } + } + + token= fScanner.nextToken(); + } + + + // remove all positions behind lastScannedPosition since there aren't any further types + if (lastScannedPosition !is reparseStart) { + // if this condition is not met, nothing has been scanned because of a deletion + ++ lastScannedPosition; + } + first= d.computeIndexInCategory(fPositionCategory, lastScannedPosition); + category= d.getPositions(fPositionCategory); + + TypedPosition p; + while (first < category.length) { + p= cast(TypedPosition) category[first++]; + d.removePosition(fPositionCategory, p); + rememberRegion(p.offset, p.length); + } + + } catch (BadPositionCategoryException x) { + // should never happen on connected documents + } catch (BadLocationException x) { + } + + return createRegion(); + } + + + /** + * Returns the position in the partitoner's position category which is + * close to the given offset. This is, the position has either an offset which + * is the same as the given offset or an offset which is smaller than the given + * offset. This method profits from the knowledge that a partitioning is + * a ordered set of disjoint position. + * + * @param offset the offset for which to search the closest position + * @return the closest position in the partitioner's category + */ + protected TypedPosition findClosestPosition(int offset) { + + try { + + int index= fDocument.computeIndexInCategory(fPositionCategory, offset); + Position[] category= fDocument.getPositions(fPositionCategory); + + if (category.length is 0) + return null; + + if (index < category.length) { + if (offset is category[index].offset) + return cast(TypedPosition) category[index]; + } + + if (index > 0) + index--; + + return cast(TypedPosition) category[index]; + + } catch (BadPositionCategoryException x) { + } catch (BadLocationException x) { + } + + return null; + } + + + /* + * @see IDocumentPartitioner#getContentType(int) + */ + public String getContentType(int offset) { + checkInitialization(); + + TypedPosition p= findClosestPosition(offset); + if (p !is null && p.includes(offset)) + return p.getType(); + + return IDocument.DEFAULT_CONTENT_TYPE; + } + + /* + * @see IDocumentPartitioner#getPartition(int) + */ + public ITypedRegion getPartition(int offset) { + checkInitialization(); + + try { + + Position[] category = fDocument.getPositions(fPositionCategory); + + if (category is null || category.length is 0) + return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE); + + int index= fDocument.computeIndexInCategory(fPositionCategory, offset); + + if (index < category.length) { + + TypedPosition next= cast(TypedPosition) category[index]; + + if (offset is next.offset) + return new TypedRegion(next.getOffset(), next.getLength(), next.getType()); + + if (index is 0) + return new TypedRegion(0, next.offset, IDocument.DEFAULT_CONTENT_TYPE); + + TypedPosition previous= cast(TypedPosition) category[index - 1]; + if (previous.includes(offset)) + return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType()); + + int endOffset= previous.getOffset() + previous.getLength(); + return new TypedRegion(endOffset, next.getOffset() - endOffset, IDocument.DEFAULT_CONTENT_TYPE); + } + + TypedPosition previous= cast(TypedPosition) category[category.length - 1]; + if (previous.includes(offset)) + return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType()); + + int endOffset= previous.getOffset() + previous.getLength(); + return new TypedRegion(endOffset, fDocument.getLength() - endOffset, IDocument.DEFAULT_CONTENT_TYPE); + + } catch (BadPositionCategoryException x) { + } catch (BadLocationException x) { + } + + return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE); + } + + /* + * @see IDocumentPartitioner#computePartitioning(int, int) + */ + public ITypedRegion[] computePartitioning(int offset, int length) { + return computePartitioning(offset, length, false); + } + + /* + * @see IDocumentPartitioner#getLegalContentTypes() + */ + public String[] getLegalContentTypes() { + return TextUtilities.copy(fLegalContentTypes); + } + + /** + * Returns whether the given type is one of the legal content types. + * + * @param contentType the content type to check + * @return true if the content type is a legal content type + */ + protected bool isSupportedContentType(String contentType) { + if (contentType !is null) { + for (int i= 0; i < fLegalContentTypes.length; i++) { + if (fLegalContentTypes[i].equals(contentType)) + return true; + } + } + + return false; + } + + /** + * Returns a content type encoded in the given token. If the token's + * data is not null and a string it is assumed that + * it is the encoded content type. + * + * @param token the token whose content type is to be determined + * @return the token's content type + */ + protected String getTokenContentType(IToken token) { + Object data= token.getData(); + if ( auto str = cast(ArrayWrapperString)data ) + return str.array; + return null; + } + + /* zero-length partition support */ + + /* + * @see dwtx.jface.text.IDocumentPartitionerExtension2#getContentType(int) + * @since 3.0 + */ + public String getContentType(int offset, bool preferOpenPartitions) { + return getPartition(offset, preferOpenPartitions).getType(); + } + + /* + * @see dwtx.jface.text.IDocumentPartitionerExtension2#getPartition(int) + * @since 3.0 + */ + public ITypedRegion getPartition(int offset, bool preferOpenPartitions) { + ITypedRegion region= getPartition(offset); + if (preferOpenPartitions) { + if (region.getOffset() is offset && !region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE)) { + if (offset > 0) { + region= getPartition(offset - 1); + if (region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE)) + return region; + } + return new TypedRegion(offset, 0, IDocument.DEFAULT_CONTENT_TYPE); + } + } + return region; + } + + /* + * @see dwtx.jface.text.IDocumentPartitionerExtension2#computePartitioning(int, int, bool) + * @since 3.0 + */ + public ITypedRegion[] computePartitioning(int offset, int length, bool includeZeroLengthPartitions) { + checkInitialization(); + List list= new ArrayList(); + + try { + + int endOffset= offset + length; + + Position[] category= fDocument.getPositions(fPositionCategory); + + TypedPosition previous= null, current= null; + int start, end, gapOffset; + Position gap= new Position(0); + + int startIndex= getFirstIndexEndingAfterOffset(category, offset); + int endIndex= getFirstIndexStartingAfterOffset(category, endOffset); + for (int i= startIndex; i < endIndex; i++) { + + current= cast(TypedPosition) category[i]; + + gapOffset= (previous !is null) ? previous.getOffset() + previous.getLength() : 0; + gap.setOffset(gapOffset); + gap.setLength(current.getOffset() - gapOffset); + if ((includeZeroLengthPartitions && overlapsOrTouches(gap, offset, length)) || + (gap.getLength() > 0 && gap.overlapsWith(offset, length))) { + start= Math.max(offset, gapOffset); + end= Math.min(endOffset, gap.getOffset() + gap.getLength()); + list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE)); + } + + if (current.overlapsWith(offset, length)) { + start= Math.max(offset, current.getOffset()); + end= Math.min(endOffset, current.getOffset() + current.getLength()); + list.add(new TypedRegion(start, end - start, current.getType())); + } + + previous= current; + } + + if (previous !is null) { + gapOffset= previous.getOffset() + previous.getLength(); + gap.setOffset(gapOffset); + gap.setLength(fDocument.getLength() - gapOffset); + if ((includeZeroLengthPartitions && overlapsOrTouches(gap, offset, length)) || + (gap.getLength() > 0 && gap.overlapsWith(offset, length))) { + start= Math.max(offset, gapOffset); + end= Math.min(endOffset, fDocument.getLength()); + list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE)); + } + } + + if (list.isEmpty()) + list.add(new TypedRegion(offset, length, IDocument.DEFAULT_CONTENT_TYPE)); + + } catch (BadPositionCategoryException x) { + } + + return arraycast!(ITypedRegion)(list.toArray()); + } + + /** + * Returns true if the given ranges overlap with or touch each other. + * + * @param gap the first range + * @param offset the offset of the second range + * @param length the length of the second range + * @return true if the given ranges overlap with or touch each other + * @since 3.0 + */ + private bool overlapsOrTouches(Position gap, int offset, int length) { + return gap.getOffset() <= offset + length && offset <= gap.getOffset() + gap.getLength(); + } + + /** + * Returns the index of the first position which ends after the given offset. + * + * @param positions the positions in linear order + * @param offset the offset + * @return the index of the first position which ends after the offset + * + * @since 3.0 + */ + private int getFirstIndexEndingAfterOffset(Position[] positions, int offset) { + int i= -1, j= positions.length; + while (j - i > 1) { + int k= (i + j) >> 1; + Position p= positions[k]; + if (p.getOffset() + p.getLength() > offset) + j= k; + else + i= k; + } + return j; + } + + /** + * Returns the index of the first position which starts at or after the given offset. + * + * @param positions the positions in linear order + * @param offset the offset + * @return the index of the first position which starts after the offset + * + * @since 3.0 + */ + private int getFirstIndexStartingAfterOffset(Position[] positions, int offset) { + int i= -1, j= positions.length; + while (j - i > 1) { + int k= (i + j) >> 1; + Position p= positions[k]; + if (p.getOffset() >= offset) + j= k; + else + i= k; + } + return j; + } + + /* + * @see dwtx.jface.text.IDocumentPartitionerExtension3#startRewriteSession(dwtx.jface.text.DocumentRewriteSession) + * @since 3.1 + */ + public void startRewriteSession(DocumentRewriteSession session) { + if (fActiveRewriteSession !is null) + throw new IllegalStateException(); + fActiveRewriteSession= session; + } + + /* + * @see dwtx.jface.text.IDocumentPartitionerExtension3#stopRewriteSession(dwtx.jface.text.DocumentRewriteSession) + * @since 3.1 + */ + public void stopRewriteSession(DocumentRewriteSession session) { + if (fActiveRewriteSession is session) + flushRewriteSession(); + } + + /* + * @see dwtx.jface.text.IDocumentPartitionerExtension3#getActiveRewriteSession() + * @since 3.1 + */ + public DocumentRewriteSession getActiveRewriteSession() { + return fActiveRewriteSession; + } + + /** + * Flushes the active rewrite session. + * + * @since 3.1 + */ + protected final void flushRewriteSession() { + fActiveRewriteSession= null; + + // remove all position belonging to the partitioner position category + try { + fDocument.removePositionCategory(fPositionCategory); + } catch (BadPositionCategoryException x) { + } + fDocument.addPositionCategory(fPositionCategory); + + fIsInitialized= false; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/EndOfLineRule.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/EndOfLineRule.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2000, 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 + * Christopher Lenz (cmlenz@gmx.de) - support for line continuation + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.text.rules.EndOfLineRule; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * A specific configuration of a single line rule + * whereby the pattern begins with a specific sequence but + * is only ended by a line delimiter. + */ +public class EndOfLineRule : SingleLineRule { + + /** + * Creates a rule for the given starting sequence + * which, if detected, will return the specified token. + * + * @param startSequence the pattern's start sequence + * @param token the token to be returned on success + */ + public this(String startSequence, IToken token) { + this(startSequence, token, cast(wchar) 0); + } + + /** + * Creates a rule for the given starting sequence + * which, if detected, will return the specified token. + * Any character which follows the given escape character + * will be ignored. + * + * @param startSequence the pattern's start sequence + * @param token the token to be returned on success + * @param escapeCharacter the escape character + */ + public this(String startSequence, IToken token, char escapeCharacter) { + super(startSequence, null, token, escapeCharacter, true); + } + + /** + * Creates a rule for the given starting sequence + * which, if detected, will return the specified token. + * Any character which follows the given escape character + * will be ignored. In addition, an escape character + * immediately before an end of line can be set to continue + * the line. + * + * @param startSequence the pattern's start sequence + * @param token the token to be returned on success + * @param escapeCharacter the escape character + * @param escapeContinuesLine indicates whether the specified escape + * character is used for line continuation, so that an end of + * line immediately after the escape character does not + * terminate the line, even if breakOnEOL is true + * @since 3.0 + */ + public this(String startSequence, IToken token, char escapeCharacter, bool escapeContinuesLine) { + super(startSequence, null, token, escapeCharacter, true, escapeContinuesLine); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/FastPartitioner.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/FastPartitioner.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,858 @@ +/******************************************************************************* + * 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 + * 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.text.rules.FastPartitioner; + +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; +import tango.text.convert.Format; + +import dwtx.core.runtime.Assert; +import dwtx.core.runtime.Platform; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.BadPositionCategoryException; +import dwtx.jface.text.DefaultPositionUpdater; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.DocumentRewriteSession; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentPartitioner; +import dwtx.jface.text.IDocumentPartitionerExtension; +import dwtx.jface.text.IDocumentPartitionerExtension2; +import dwtx.jface.text.IDocumentPartitionerExtension3; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITypedRegion; +import dwtx.jface.text.Position; +import dwtx.jface.text.Region; +import dwtx.jface.text.TextUtilities; +import dwtx.jface.text.TypedPosition; +import dwtx.jface.text.TypedRegion; + + + +/** + * A standard implementation of a document partitioner. It uses an + * {@link IPartitionTokenScanner} to scan the document and to determine the + * document's partitioning. The tokens returned by the scanner must return the + * partition type as their data. The partitioner remembers the document's + * partitions in the document itself rather than maintaining its own data + * structure. + *

                    + * To reduce array creations in {@link IDocument#getPositions(String)}, the + * positions get cached. The cache is cleared after updating the positions in + * {@link #documentChanged2(DocumentEvent)}. Subclasses need to call + * {@link #clearPositionCache()} after modifying the partitioner's positions. + * The cached positions may be accessed through {@link #getPositions()}. + *

                    + * + * @see IPartitionTokenScanner + * @since 3.1 + */ +public class FastPartitioner : IDocumentPartitioner, IDocumentPartitionerExtension, IDocumentPartitionerExtension2, IDocumentPartitionerExtension3 { + + /** + * The position category this partitioner uses to store the document's partitioning information. + */ + private static const String CONTENT_TYPES_CATEGORY= "__content_types_category"; //$NON-NLS-1$ + /** The partitioner's scanner */ + protected final IPartitionTokenScanner fScanner; + /** The legal content types of this partitioner */ + protected final String[] fLegalContentTypes; + /** The partitioner's document */ + protected IDocument fDocument; + /** The document length before a document change occurred */ + protected int fPreviousDocumentLength; + /** The position updater used to for the default updating of partitions */ + protected final DefaultPositionUpdater fPositionUpdater; + /** The offset at which the first changed partition starts */ + protected int fStartOffset; + /** The offset at which the last changed partition ends */ + protected int fEndOffset; + /**The offset at which a partition has been deleted */ + protected int fDeleteOffset; + /** + * The position category this partitioner uses to store the document's partitioning information. + */ + private const String fPositionCategory; + /** + * The active document rewrite session. + */ + private DocumentRewriteSession fActiveRewriteSession; + /** + * Flag indicating whether this partitioner has been initialized. + */ + private bool fIsInitialized= false; + /** + * The cached positions from our document, so we don't create a new array every time + * someone requests partition information. + */ + private Position[] fCachedPositions= null; + /** Debug option for cache consistency checking. */ + private static bool CHECK_CACHE_CONSISTENCY_; + private static bool CHECK_CACHE_CONSISTENCY_init; + private static bool CHECK_CACHE_CONSISTENCY(){ + if( !CHECK_CACHE_CONSISTENCY_init ){ + synchronized(FastPartitioner.classinfo ){ + if( !CHECK_CACHE_CONSISTENCY_init ){ + CHECK_CACHE_CONSISTENCY_init = true; + CHECK_CACHE_CONSISTENCY_ = "true".equalsIgnoreCase(Platform.getDebugOption("dwtx.jface.text/debug/FastPartitioner/PositionCache")); //$NON-NLS-1$//$NON-NLS-2$; + } + } + } + return CHECK_CACHE_CONSISTENCY_; + } + + /** + * Creates a new partitioner that uses the given scanner and may return + * partitions of the given legal content types. + * + * @param scanner the scanner this partitioner is supposed to use + * @param legalContentTypes the legal content types of this partitioner + */ + public this(IPartitionTokenScanner scanner, String[] legalContentTypes) { + fScanner= scanner; + fLegalContentTypes= TextUtilities.copy(legalContentTypes); + fPositionCategory= CONTENT_TYPES_CATEGORY ~ Integer.toString(toHash()); + fPositionUpdater= new DefaultPositionUpdater(fPositionCategory); + } + + /* + * @see dwtx.jface.text.IDocumentPartitionerExtension2#getManagingPositionCategories() + */ + public String[] getManagingPositionCategories() { + return [ fPositionCategory ]; + } + + /* + * @see dwtx.jface.text.IDocumentPartitioner#connect(dwtx.jface.text.IDocument) + */ + public final void connect(IDocument document) { + connect(document, false); + } + + /** + * {@inheritDoc} + *

                    + * May be extended by subclasses. + *

                    + */ + public void connect(IDocument document, bool delayInitialization) { + Assert.isNotNull(cast(Object)document); + Assert.isTrue(!document.containsPositionCategory(fPositionCategory)); + + fDocument= document; + fDocument.addPositionCategory(fPositionCategory); + + fIsInitialized= false; + if (!delayInitialization) + checkInitialization(); + } + + /** + * Calls {@link #initialize()} if the receiver is not yet initialized. + */ + protected final void checkInitialization() { + if (!fIsInitialized) + initialize(); + } + + /** + * Performs the initial partitioning of the partitioner's document. + *

                    + * May be extended by subclasses. + *

                    + */ + protected void initialize() { + fIsInitialized= true; + clearPositionCache(); + fScanner.setRange(fDocument, 0, fDocument.getLength()); + + try { + IToken token= fScanner.nextToken(); + while (!token.isEOF()) { + + String contentType= getTokenContentType(token); + + if (isSupportedContentType(contentType)) { + TypedPosition p= new TypedPosition(fScanner.getTokenOffset(), fScanner.getTokenLength(), contentType); + fDocument.addPosition(fPositionCategory, p); + } + + token= fScanner.nextToken(); + } + } catch (BadLocationException x) { + // cannot happen as offsets come from scanner + } catch (BadPositionCategoryException x) { + // cannot happen if document has been connected before + } + } + + /** + * {@inheritDoc} + *

                    + * May be extended by subclasses. + *

                    + */ + public void disconnect() { + + Assert.isTrue(fDocument.containsPositionCategory(fPositionCategory)); + + try { + fDocument.removePositionCategory(fPositionCategory); + } catch (BadPositionCategoryException x) { + // can not happen because of Assert + } + } + + /** + * {@inheritDoc} + *

                    + * May be extended by subclasses. + *

                    + */ + public void documentAboutToBeChanged(DocumentEvent e) { + if (fIsInitialized) { + + Assert.isTrue(e.getDocument() is fDocument); + + fPreviousDocumentLength= e.getDocument().getLength(); + fStartOffset= -1; + fEndOffset= -1; + fDeleteOffset= -1; + } + } + + /* + * @see IDocumentPartitioner#documentChanged(DocumentEvent) + */ + public final bool documentChanged(DocumentEvent e) { + if (fIsInitialized) { + IRegion region= documentChanged2(e); + return (region !is null); + } + return false; + } + + /** + * Helper method for tracking the minimal region containing all partition changes. + * If offset is smaller than the remembered offset, offset + * will from now on be remembered. If offset + length is greater than + * the remembered end offset, it will be remembered from now on. + * + * @param offset the offset + * @param length the length + */ + private void rememberRegion(int offset, int length) { + // remember start offset + if (fStartOffset is -1) + fStartOffset= offset; + else if (offset < fStartOffset) + fStartOffset= offset; + + // remember end offset + int endOffset= offset + length; + if (fEndOffset is -1) + fEndOffset= endOffset; + else if (endOffset > fEndOffset) + fEndOffset= endOffset; + } + + /** + * Remembers the given offset as the deletion offset. + * + * @param offset the offset + */ + private void rememberDeletedOffset(int offset) { + fDeleteOffset= offset; + } + + /** + * Creates the minimal region containing all partition changes using the + * remembered offset, end offset, and deletion offset. + * + * @return the minimal region containing all the partition changes + */ + private IRegion createRegion() { + if (fDeleteOffset is -1) { + if (fStartOffset is -1 || fEndOffset is -1) + return null; + return new Region(fStartOffset, fEndOffset - fStartOffset); + } else if (fStartOffset is -1 || fEndOffset is -1) { + return new Region(fDeleteOffset, 0); + } else { + int offset= Math.min(fDeleteOffset, fStartOffset); + int endOffset= Math.max(fDeleteOffset, fEndOffset); + return new Region(offset, endOffset - offset); + } + } + + /** + * {@inheritDoc} + *

                    + * May be extended by subclasses. + *

                    + */ + public IRegion documentChanged2(DocumentEvent e) { + + if (!fIsInitialized) + return null; + + try { + Assert.isTrue(e.getDocument() is fDocument); + + Position[] category= getPositions(); + IRegion line= fDocument.getLineInformationOfOffset(e.getOffset()); + int reparseStart= line.getOffset(); + int partitionStart= -1; + String contentType= null; + int newLength= e.getText() is null ? 0 : e.getText().length(); + + int first= fDocument.computeIndexInCategory(fPositionCategory, reparseStart); + if (first > 0) { + TypedPosition partition= cast(TypedPosition) category[first - 1]; + if (partition.includes(reparseStart)) { + partitionStart= partition.getOffset(); + contentType= partition.getType(); + if (e.getOffset() is partition.getOffset() + partition.getLength()) + reparseStart= partitionStart; + -- first; + } else if (reparseStart is e.getOffset() && reparseStart is partition.getOffset() + partition.getLength()) { + partitionStart= partition.getOffset(); + contentType= partition.getType(); + reparseStart= partitionStart; + -- first; + } else { + partitionStart= partition.getOffset() + partition.getLength(); + contentType= IDocument.DEFAULT_CONTENT_TYPE; + } + } + + fPositionUpdater.update(e); + for (int i= first; i < category.length; i++) { + Position p= category[i]; + if (p.isDeleted) { + rememberDeletedOffset(e.getOffset()); + break; + } + } + clearPositionCache(); + category= getPositions(); + + fScanner.setPartialRange(fDocument, reparseStart, fDocument.getLength() - reparseStart, contentType, partitionStart); + + int behindLastScannedPosition= reparseStart; + IToken token= fScanner.nextToken(); + + while (!token.isEOF()) { + + contentType= getTokenContentType(token); + + if (!isSupportedContentType(contentType)) { + token= fScanner.nextToken(); + continue; + } + + int start= fScanner.getTokenOffset(); + int length= fScanner.getTokenLength(); + + behindLastScannedPosition= start + length; + int lastScannedPosition= behindLastScannedPosition - 1; + + // remove all affected positions + while (first < category.length) { + TypedPosition p= cast(TypedPosition) category[first]; + if (lastScannedPosition >= p.offset + p.length || + (p.overlapsWith(start, length) && + (!fDocument.containsPosition(fPositionCategory, start, length) || + !contentType.equals(p.getType())))) { + + rememberRegion(p.offset, p.length); + fDocument.removePosition(fPositionCategory, p); + ++ first; + + } else + break; + } + + // if position already exists and we have scanned at least the + // area covered by the event, we are done + if (fDocument.containsPosition(fPositionCategory, start, length)) { + if (lastScannedPosition >= e.getOffset() + newLength) + return createRegion(); + ++ first; + } else { + // insert the new type position + try { + fDocument.addPosition(fPositionCategory, new TypedPosition(start, length, contentType)); + rememberRegion(start, length); + } catch (BadPositionCategoryException x) { + } catch (BadLocationException x) { + } + } + + token= fScanner.nextToken(); + } + + first= fDocument.computeIndexInCategory(fPositionCategory, behindLastScannedPosition); + + clearPositionCache(); + category= getPositions(); + TypedPosition p; + while (first < category.length) { + p= cast(TypedPosition) category[first++]; + fDocument.removePosition(fPositionCategory, p); + rememberRegion(p.offset, p.length); + } + + } catch (BadPositionCategoryException x) { + // should never happen on connected documents + } catch (BadLocationException x) { + } finally { + clearPositionCache(); + } + + return createRegion(); + } + + /** + * Returns the position in the partitoner's position category which is + * close to the given offset. This is, the position has either an offset which + * is the same as the given offset or an offset which is smaller than the given + * offset. This method profits from the knowledge that a partitioning is + * a ordered set of disjoint position. + *

                    + * May be extended or replaced by subclasses. + *

                    + * @param offset the offset for which to search the closest position + * @return the closest position in the partitioner's category + */ + protected TypedPosition findClosestPosition(int offset) { + + try { + + int index= fDocument.computeIndexInCategory(fPositionCategory, offset); + Position[] category= getPositions(); + + if (category.length is 0) + return null; + + if (index < category.length) { + if (offset is category[index].offset) + return cast(TypedPosition) category[index]; + } + + if (index > 0) + index--; + + return cast(TypedPosition) category[index]; + + } catch (BadPositionCategoryException x) { + } catch (BadLocationException x) { + } + + return null; + } + + + /** + * {@inheritDoc} + *

                    + * May be replaced or extended by subclasses. + *

                    + */ + public String getContentType(int offset) { + checkInitialization(); + + TypedPosition p= findClosestPosition(offset); + if (p !is null && p.includes(offset)) + return p.getType(); + + return IDocument.DEFAULT_CONTENT_TYPE; + } + + /** + * {@inheritDoc} + *

                    + * May be replaced or extended by subclasses. + *

                    + */ + public ITypedRegion getPartition(int offset) { + checkInitialization(); + + try { + + Position[] category = getPositions(); + + if (category is null || category.length is 0) + return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE); + + int index= fDocument.computeIndexInCategory(fPositionCategory, offset); + + if (index < category.length) { + + TypedPosition next= cast(TypedPosition) category[index]; + + if (offset is next.offset) + return new TypedRegion(next.getOffset(), next.getLength(), next.getType()); + + if (index is 0) + return new TypedRegion(0, next.offset, IDocument.DEFAULT_CONTENT_TYPE); + + TypedPosition previous= cast(TypedPosition) category[index - 1]; + if (previous.includes(offset)) + return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType()); + + int endOffset= previous.getOffset() + previous.getLength(); + return new TypedRegion(endOffset, next.getOffset() - endOffset, IDocument.DEFAULT_CONTENT_TYPE); + } + + TypedPosition previous= cast(TypedPosition) category[category.length - 1]; + if (previous.includes(offset)) + return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType()); + + int endOffset= previous.getOffset() + previous.getLength(); + return new TypedRegion(endOffset, fDocument.getLength() - endOffset, IDocument.DEFAULT_CONTENT_TYPE); + + } catch (BadPositionCategoryException x) { + } catch (BadLocationException x) { + } + + return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE); + } + + /* + * @see IDocumentPartitioner#computePartitioning(int, int) + */ + public final ITypedRegion[] computePartitioning(int offset, int length) { + return computePartitioning(offset, length, false); + } + + /** + * {@inheritDoc} + *

                    + * May be replaced or extended by subclasses. + *

                    + */ + public String[] getLegalContentTypes() { + return TextUtilities.copy(fLegalContentTypes); + } + + /** + * Returns whether the given type is one of the legal content types. + *

                    + * May be extended by subclasses. + *

                    + * + * @param contentType the content type to check + * @return true if the content type is a legal content type + */ + protected bool isSupportedContentType(String contentType) { + if (contentType !is null) { + for (int i= 0; i < fLegalContentTypes.length; i++) { + if (fLegalContentTypes[i].equals(contentType)) + return true; + } + } + + return false; + } + + /** + * Returns a content type encoded in the given token. If the token's + * data is not null and a string it is assumed that + * it is the encoded content type. + *

                    + * May be replaced or extended by subclasses. + *

                    + * + * @param token the token whose content type is to be determined + * @return the token's content type + */ + protected String getTokenContentType(IToken token) { + Object data= token.getData(); + if ( auto str = cast(ArrayWrapperString)data ) + return str.array; + return null; + } + + /* zero-length partition support */ + + /** + * {@inheritDoc} + *

                    + * May be replaced or extended by subclasses. + *

                    + */ + public String getContentType(int offset, bool preferOpenPartitions) { + return getPartition(offset, preferOpenPartitions).getType(); + } + + /** + * {@inheritDoc} + *

                    + * May be replaced or extended by subclasses. + *

                    + */ + public ITypedRegion getPartition(int offset, bool preferOpenPartitions) { + ITypedRegion region= getPartition(offset); + if (preferOpenPartitions) { + if (region.getOffset() is offset && !region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE)) { + if (offset > 0) { + region= getPartition(offset - 1); + if (region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE)) + return region; + } + return new TypedRegion(offset, 0, IDocument.DEFAULT_CONTENT_TYPE); + } + } + return region; + } + + /** + * {@inheritDoc} + *

                    + * May be replaced or extended by subclasses. + *

                    + */ + public ITypedRegion[] computePartitioning(int offset, int length, bool includeZeroLengthPartitions) { + checkInitialization(); + List list= new ArrayList(); + + try { + + int endOffset= offset + length; + + Position[] category= getPositions(); + + TypedPosition previous= null, current= null; + int start, end, gapOffset; + Position gap= new Position(0); + + int startIndex= getFirstIndexEndingAfterOffset(category, offset); + int endIndex= getFirstIndexStartingAfterOffset(category, endOffset); + for (int i= startIndex; i < endIndex; i++) { + + current= cast(TypedPosition) category[i]; + + gapOffset= (previous !is null) ? previous.getOffset() + previous.getLength() : 0; + gap.setOffset(gapOffset); + gap.setLength(current.getOffset() - gapOffset); + if ((includeZeroLengthPartitions && overlapsOrTouches(gap, offset, length)) || + (gap.getLength() > 0 && gap.overlapsWith(offset, length))) { + start= Math.max(offset, gapOffset); + end= Math.min(endOffset, gap.getOffset() + gap.getLength()); + list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE)); + } + + if (current.overlapsWith(offset, length)) { + start= Math.max(offset, current.getOffset()); + end= Math.min(endOffset, current.getOffset() + current.getLength()); + list.add(new TypedRegion(start, end - start, current.getType())); + } + + previous= current; + } + + if (previous !is null) { + gapOffset= previous.getOffset() + previous.getLength(); + gap.setOffset(gapOffset); + gap.setLength(fDocument.getLength() - gapOffset); + if ((includeZeroLengthPartitions && overlapsOrTouches(gap, offset, length)) || + (gap.getLength() > 0 && gap.overlapsWith(offset, length))) { + start= Math.max(offset, gapOffset); + end= Math.min(endOffset, fDocument.getLength()); + list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE)); + } + } + + if (list.isEmpty()) + list.add(new TypedRegion(offset, length, IDocument.DEFAULT_CONTENT_TYPE)); + + } catch (BadPositionCategoryException ex) { + // Make sure we clear the cache + clearPositionCache(); + } catch (RuntimeException ex) { + // Make sure we clear the cache + clearPositionCache(); + throw ex; + } + + return arraycast!(ITypedRegion)(list.toArray()); + } + + /** + * Returns true if the given ranges overlap with or touch each other. + * + * @param gap the first range + * @param offset the offset of the second range + * @param length the length of the second range + * @return true if the given ranges overlap with or touch each other + */ + private bool overlapsOrTouches(Position gap, int offset, int length) { + return gap.getOffset() <= offset + length && offset <= gap.getOffset() + gap.getLength(); + } + + /** + * Returns the index of the first position which ends after the given offset. + * + * @param positions the positions in linear order + * @param offset the offset + * @return the index of the first position which ends after the offset + */ + private int getFirstIndexEndingAfterOffset(Position[] positions, int offset) { + int i= -1, j= positions.length; + while (j - i > 1) { + int k= (i + j) >> 1; + Position p= positions[k]; + if (p.getOffset() + p.getLength() > offset) + j= k; + else + i= k; + } + return j; + } + + /** + * Returns the index of the first position which starts at or after the given offset. + * + * @param positions the positions in linear order + * @param offset the offset + * @return the index of the first position which starts after the offset + */ + private int getFirstIndexStartingAfterOffset(Position[] positions, int offset) { + int i= -1, j= positions.length; + while (j - i > 1) { + int k= (i + j) >> 1; + Position p= positions[k]; + if (p.getOffset() >= offset) + j= k; + else + i= k; + } + return j; + } + + /* + * @see dwtx.jface.text.IDocumentPartitionerExtension3#startRewriteSession(dwtx.jface.text.DocumentRewriteSession) + */ + public void startRewriteSession(DocumentRewriteSession session) { + if (fActiveRewriteSession !is null) + throw new IllegalStateException(); + fActiveRewriteSession= session; + } + + /** + * {@inheritDoc} + *

                    + * May be extended by subclasses. + *

                    + */ + public void stopRewriteSession(DocumentRewriteSession session) { + if (fActiveRewriteSession is session) + flushRewriteSession(); + } + + /** + * {@inheritDoc} + *

                    + * May be extended by subclasses. + *

                    + */ + public DocumentRewriteSession getActiveRewriteSession() { + return fActiveRewriteSession; + } + + /** + * Flushes the active rewrite session. + */ + protected final void flushRewriteSession() { + fActiveRewriteSession= null; + + // remove all position belonging to the partitioner position category + try { + fDocument.removePositionCategory(fPositionCategory); + } catch (BadPositionCategoryException x) { + } + fDocument.addPositionCategory(fPositionCategory); + + fIsInitialized= false; + } + + /** + * Clears the position cache. Needs to be called whenever the positions have + * been updated. + */ + protected final void clearPositionCache() { + if (fCachedPositions !is null) { + fCachedPositions= null; + } + } + + /** + * Returns the partitioners positions. + * + * @return the partitioners positions + * @throws BadPositionCategoryException if getting the positions from the + * document fails + */ + protected final Position[] getPositions() { + if (fCachedPositions is null) { + fCachedPositions= fDocument.getPositions(fPositionCategory); + } else if (CHECK_CACHE_CONSISTENCY) { + Position[] positions= fDocument.getPositions(fPositionCategory); + int len= Math.min(positions.length, fCachedPositions.length); + for (int i= 0; i < len; i++) { + if (!positions[i].opEquals(fCachedPositions[i])) + System.err.println(Format("FastPartitioner.getPositions(): cached position is not up to date: from document: {} in cache: {}", toString(positions[i]), toString(fCachedPositions[i]))); //$NON-NLS-1$ //$NON-NLS-2$ + } + for (int i= len; i < positions.length; i++) + System.err.println(Format("FastPartitioner.getPositions(): new position in document: {}", toString(positions[i]))); //$NON-NLS-1$ + for (int i= len; i < fCachedPositions.length; i++) + System.err.println(Format("FastPartitioner.getPositions(): stale position in cache: {}", toString(fCachedPositions[i]))); //$NON-NLS-1$ + } + return fCachedPositions; + } + + /** + * Pretty print a Position. + * + * @param position the position to format + * @return a formatted string + */ + private override String toString(Position position) { + return Format("P[{}+{}]", position.getOffset(), position.getLength() ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/ICharacterScanner.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/ICharacterScanner.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.rules.ICharacterScanner; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Defines the interface of a character scanner used by rules. + * Rules may request the next character or ask the character + * scanner to unread the last read character. + */ +public interface ICharacterScanner { + + /** + * The value returned when this scanner has read EOF. + */ + public static const int EOF= -1; + + /** + * Provides rules access to the legal line delimiters. The returned + * object may not be modified by clients. + * + * @return the legal line delimiters + */ + char[][] getLegalLineDelimiters(); + + /** + * Returns the column of the character scanner. + * + * @return the column of the character scanner + */ + int getColumn(); + + /** + * Returns the next character or EOF if end of file has been reached + * + * @return the next character or EOF + */ + int read(); + + /** + * Rewinds the scanner before the last read character. + */ + void unread(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/IPartitionTokenScanner.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/IPartitionTokenScanner.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.rules.IPartitionTokenScanner; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + +import dwt.dwthelper.utils; + + +import dwtx.jface.text.IDocument; + + +/** + * A partition token scanner returns tokens that represent partitions. For that reason, + * a partition token scanner is vulnerable in respect to the document offset it starts + * scanning. In a simple case, a partition token scanner must always start at a partition + * boundary. A partition token scanner can also start in the middle of a partition, + * if it knows the type of the partition. + * + * @since 2.0 + */ +public interface IPartitionTokenScanner : ITokenScanner { + + /** + * Configures the scanner by providing access to the document range that should be scanned. + * The range may no only contain complete partitions but starts at the beginning of a line in the + * middle of a partition of the given content type. This requires that a partition delimiter can not + * contain a line delimiter. + * + * @param document the document to scan + * @param offset the offset of the document range to scan + * @param length the length of the document range to scan + * @param contentType the content type at the given offset + * @param partitionOffset the offset at which the partition of the given offset starts + */ + void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/IPredicateRule.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/IPredicateRule.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,77 @@ +/******************************************************************************* + * 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 + * 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.text.rules.IPredicateRule; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + +import dwt.dwthelper.utils; + +/** + * Defines the interface for a rule used in the scanning of text for the purpose of + * document partitioning or text styling. A predicate rule can only return one single + * token after having successfully detected content. This token is called success token. + * Also, it also returns a token indicating that this rule has not been successful. + * + * @see ICharacterScanner + * @since 2.0 + */ +public interface IPredicateRule : IRule { + + /** + * Returns the success token of this predicate rule. + * + * @return the success token of this rule + */ + IToken getSuccessToken(); + + /** + * Evaluates the rule by examining the characters available from + * the provided character scanner. The token returned by this rule + * returns true when calling isUndefined, + * if the text that the rule investigated does not match the rule's requirements. Otherwise, + * this method returns this rule's success token. If this rules relies on a text pattern + * comprising a opening and a closing character sequence this method can also be called + * when the scanner is positioned already between the opening and the closing sequence. + * In this case, resume must be set to true. + * + * @param scanner the character scanner to be used by this rule + * @param resume indicates that the rule starts working between the opening and the closing character sequence + * @return the token computed by the rule + */ + IToken evaluate(ICharacterScanner scanner, bool resume); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/IRule.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/IRule.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,63 @@ +/******************************************************************************* + * 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 + * 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.text.rules.IRule; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Defines the interface for a rule used in the + * scanning of text for the purpose of document + * partitioning or text styling. + * + * @see ICharacterScanner + */ +public interface IRule { + + /** + * Evaluates the rule by examining the characters available from + * the provided character scanner. The token returned by this rule + * returns true when calling isUndefined, + * if the text that the rule investigated does not match the rule's requirements + * + * @param scanner the character scanner to be used by this rule + * @return the token computed by the rule + */ + IToken evaluate(ICharacterScanner scanner); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/IToken.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/IToken.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.rules.IToken; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * A token to be returned by a rule. + */ +public interface IToken { + + /** + * Return whether this token is undefined. + * + * @return trueif this token is undefined + */ + bool isUndefined(); + + /** + * Return whether this token represents a whitespace. + * + * @return trueif this token represents a whitespace + */ + bool isWhitespace(); + + /** + * Return whether this token represents End Of File. + * + * @return trueif this token represents EOF + */ + bool isEOF(); + + /** + * Return whether this token is neither undefined, nor whitespace, nor EOF. + * + * @return trueif this token is not undefined, not a whitespace, and not EOF + */ + bool isOther(); + + /** + * Return a data attached to this token. The semantics of this data kept undefined by this interface. + * + * @return the data attached to this token. + */ + Object getData(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/ITokenScanner.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/ITokenScanner.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.rules.ITokenScanner; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + +import dwt.dwthelper.utils; + + +import dwtx.jface.text.IDocument; + + +/** + * A token scanner scans a range of a document and reports about the token it finds. + * A scanner has state. When asked, the scanner returns the offset and the length of the + * last found token. + * + * @see dwtx.jface.text.rules.IToken + * @since 2.0 + */ +public interface ITokenScanner { + + /** + * Configures the scanner by providing access to the document range that should + * be scanned. + * + * @param document the document to scan + * @param offset the offset of the document range to scan + * @param length the length of the document range to scan + */ + void setRange(IDocument document, int offset, int length); + + /** + * Returns the next token in the document. + * + * @return the next token in the document + */ + IToken nextToken(); + + /** + * Returns the offset of the last token read by this scanner. + * + * @return the offset of the last token read by this scanner + */ + int getTokenOffset(); + + /** + * Returns the length of the last token read by this scanner. + * + * @return the length of the last token read by this scanner + */ + int getTokenLength(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/IWhitespaceDetector.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/IWhitespaceDetector.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.rules.IWhitespaceDetector; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Defines the interface by which WhitespaceRule + * determines whether a given character is to be considered + * whitespace in the current context. + */ +public interface IWhitespaceDetector { + + /** + * Returns whether the specified character is whitespace. + * + * @param c the character to be checked + * @return true if the specified character is a whitespace char + */ + bool isWhitespace(char c); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/IWordDetector.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/IWordDetector.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.rules.IWordDetector; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Defines the interface by which WordRule + * determines whether a given character is valid as part + * of a word in the current context. + */ +public interface IWordDetector { + + /** + * Returns whether the specified character is + * valid as the first character in a word. + * + * @param c the character to be checked + * @return true is a valid first character in a word, false otherwise + */ + bool isWordStart(char c); + + /** + * Returns whether the specified character is + * valid as a subsequent character in a word. + * + * @param c the character to be checked + * @return true if the character is a valid word part, false otherwise + */ + bool isWordPart(char c); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/MultiLineRule.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/MultiLineRule.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.rules.MultiLineRule; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * A rule for detecting patterns which begin with a given + * sequence and may end with a given sequence thereby spanning + * multiple lines. + */ +public class MultiLineRule : PatternRule { + + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specified token. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence + * @param token the token to be returned on success + */ + public this(String startSequence, String endSequence, IToken token) { + this(startSequence, endSequence, token, cast(wchar) 0); + } + + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specific token. + * Any character which follows the given escape character will be ignored. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence + * @param token the token to be returned on success + * @param escapeCharacter the escape character + */ + public this(String startSequence, String endSequence, IToken token, char escapeCharacter) { + this(startSequence, endSequence, token, escapeCharacter, false); + } + + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specific token. Any character that follows the + * given escape character will be ignored. breakOnEOF indicates whether + * EOF is equivalent to detecting the endSequence. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence + * @param token the token to be returned on success + * @param escapeCharacter the escape character + * @param breaksOnEOF indicates whether the end of the file terminates this rule successfully + * @since 2.1 + */ + public this(String startSequence, String endSequence, IToken token, char escapeCharacter, bool breaksOnEOF) { + super(startSequence, endSequence, token, escapeCharacter, false, breaksOnEOF); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/NumberRule.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/NumberRule.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,102 @@ +/******************************************************************************* + * 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 + * 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.text.rules.NumberRule; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + +import dwt.dwthelper.utils; + +import dwtx.core.runtime.Assert; + + +/** + * An implementation of IRule detecting a numerical value. + */ +public class NumberRule : IRule { + + /** Internal setting for the un-initialized column constraint */ + protected static const int UNDEFINED= -1; + /** The token to be returned when this rule is successful */ + protected IToken fToken; + /** The column constraint */ + protected int fColumn= UNDEFINED; + + /** + * Creates a rule which will return the specified + * token when a numerical sequence is detected. + * + * @param token the token to be returned + */ + public this(IToken token) { + Assert.isNotNull(cast(Object)token); + fToken= token; + } + + /** + * Sets a column constraint for this rule. If set, the rule's token + * will only be returned if the pattern is detected starting at the + * specified column. If the column is smaller then 0, the column + * constraint is considered removed. + * + * @param column the column in which the pattern starts + */ + public void setColumnConstraint(int column) { + if (column < 0) + column= UNDEFINED; + fColumn= column; + } + + /* + * @see IRule#evaluate(ICharacterScanner) + */ + public IToken evaluate(ICharacterScanner scanner) { + int c= scanner.read(); + if (Character.isDigit(cast(char)c)) { + if (fColumn is UNDEFINED || (fColumn is scanner.getColumn() - 1)) { + do { + c= scanner.read(); + } while (Character.isDigit(cast(char) c)); + scanner.unread(); + return fToken; + } + } + + scanner.unread(); + return Token.UNDEFINED; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/PatternRule.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/PatternRule.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,361 @@ +/******************************************************************************* + * 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 + * Christopher Lenz (cmlenz@gmx.de) - support for line continuation + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ + + +module dwtx.jface.text.rules.PatternRule; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + +import dwtx.core.runtime.Assert; + + + + + +/** + * Standard implementation of IPredicateRule. + * Is is capable of detecting a pattern which begins with a given start + * sequence and ends with a given end sequence. If the end sequence is + * not specified, it can be either end of line, end or file, or both. Additionally, + * the pattern can be constrained to begin in a certain column. The rule can also + * be used to check whether the text to scan covers half of the pattern, i.e. contains + * the end sequence required by the rule. + */ +public class PatternRule : IPredicateRule { + + /** + * Comparator that orders char[] in decreasing array lengths. + * + * @since 3.1 + */ + private static class DecreasingCharArrayLengthComparator : Comparator { + public int compare(Object o1, Object o2) { + return stringcast( o2).length - stringcast( o1).length; + } + } + + /** Internal setting for the un-initialized column constraint */ + protected static final int UNDEFINED= -1; + + /** The token to be returned on success */ + protected IToken fToken; + /** The pattern's start sequence */ + protected char[] fStartSequence; + /** The pattern's end sequence */ + protected char[] fEndSequence; + /** The pattern's column constrain */ + protected int fColumn; + /** The pattern's escape character */ + protected char fEscapeCharacter; + /** + * Indicates whether the escape character continues a line + * @since 3.0 + */ + protected bool fEscapeContinuesLine; + /** Indicates whether end of line terminates the pattern */ + protected bool fBreaksOnEOL; + /** Indicates whether end of file terminates the pattern */ + protected bool fBreaksOnEOF; + + /** + * Line delimiter comparator which orders according to decreasing delimiter length. + * @since 3.1 + */ + private Comparator fLineDelimiterComparator; + /** + * Cached line delimiters. + * @since 3.1 + */ + private char[][] fLineDelimiters; + /** + * Cached sorted {@linkplain #fLineDelimiters}. + * @since 3.1 + */ + private char[][] fSortedLineDelimiters; + + /** + * Creates a rule for the given starting and ending sequence. + * When these sequences are detected the rule will return the specified token. + * Alternatively, the sequence can also be ended by the end of the line. + * Any character which follows the given escapeCharacter will be ignored. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence, null is a legal value + * @param token the token which will be returned on success + * @param escapeCharacter any character following this one will be ignored + * @param breaksOnEOL indicates whether the end of the line also terminates the pattern + */ + public this(String startSequence, String endSequence, IToken token, char escapeCharacter, bool breaksOnEOL) { + fColumn= UNDEFINED; + fLineDelimiterComparator= new DecreasingCharArrayLengthComparator(); + + Assert.isTrue(startSequence !is null && startSequence.length() > 0); + Assert.isTrue(endSequence !is null || breaksOnEOL); + Assert.isNotNull(cast(Object)token); + + fStartSequence= startSequence.toCharArray(); + fEndSequence= (endSequence is null ? new char[0] : endSequence.toCharArray()); + fToken= token; + fEscapeCharacter= escapeCharacter; + fBreaksOnEOL= breaksOnEOL; + } + + /** + * Creates a rule for the given starting and ending sequence. + * When these sequences are detected the rule will return the specified token. + * Alternatively, the sequence can also be ended by the end of the line or the end of the file. + * Any character which follows the given escapeCharacter will be ignored. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence, null is a legal value + * @param token the token which will be returned on success + * @param escapeCharacter any character following this one will be ignored + * @param breaksOnEOL indicates whether the end of the line also terminates the pattern + * @param breaksOnEOF indicates whether the end of the file also terminates the pattern + * @since 2.1 + */ + public this(String startSequence, String endSequence, IToken token, char escapeCharacter, bool breaksOnEOL, bool breaksOnEOF) { + this(startSequence, endSequence, token, escapeCharacter, breaksOnEOL); + fBreaksOnEOF= breaksOnEOF; + } + + /** + * Creates a rule for the given starting and ending sequence. + * When these sequences are detected the rule will return the specified token. + * Alternatively, the sequence can also be ended by the end of the line or the end of the file. + * Any character which follows the given escapeCharacter will be ignored. An end of line + * immediately after the given lineContinuationCharacter will not cause the + * pattern to terminate even if breakOnEOL is set to true. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence, null is a legal value + * @param token the token which will be returned on success + * @param escapeCharacter any character following this one will be ignored + * @param breaksOnEOL indicates whether the end of the line also terminates the pattern + * @param breaksOnEOF indicates whether the end of the file also terminates the pattern + * @param escapeContinuesLine indicates whether the specified escape character is used for line + * continuation, so that an end of line immediately after the escape character does not + * terminate the pattern, even if breakOnEOL is set + * @since 3.0 + */ + public this(String startSequence, String endSequence, IToken token, char escapeCharacter, bool breaksOnEOL, bool breaksOnEOF, bool escapeContinuesLine) { + this(startSequence, endSequence, token, escapeCharacter, breaksOnEOL, breaksOnEOF); + fEscapeContinuesLine= escapeContinuesLine; + } + + /** + * Sets a column constraint for this rule. If set, the rule's token + * will only be returned if the pattern is detected starting at the + * specified column. If the column is smaller then 0, the column + * constraint is considered removed. + * + * @param column the column in which the pattern starts + */ + public void setColumnConstraint(int column) { + if (column < 0) + column= UNDEFINED; + fColumn= column; + } + + + /** + * Evaluates this rules without considering any column constraints. + * + * @param scanner the character scanner to be used + * @return the token resulting from this evaluation + */ + protected IToken doEvaluate(ICharacterScanner scanner) { + return doEvaluate(scanner, false); + } + + /** + * Evaluates this rules without considering any column constraints. Resumes + * detection, i.e. look sonly for the end sequence required by this rule if the + * resume flag is set. + * + * @param scanner the character scanner to be used + * @param resume true if detection should be resumed, false otherwise + * @return the token resulting from this evaluation + * @since 2.0 + */ + protected IToken doEvaluate(ICharacterScanner scanner, bool resume) { + + if (resume) { + + if (endSequenceDetected(scanner)) + return fToken; + + } else { + + int c= scanner.read(); + if (c is fStartSequence[0]) { + if (sequenceDetected(scanner, fStartSequence, false)) { + if (endSequenceDetected(scanner)) + return fToken; + } + } + } + + scanner.unread(); + return Token.UNDEFINED; + } + + /* + * @see IRule#evaluate(ICharacterScanner) + */ + public IToken evaluate(ICharacterScanner scanner) { + return evaluate(scanner, false); + } + + /** + * Returns whether the end sequence was detected. As the pattern can be considered + * ended by a line delimiter, the result of this method is true if the + * rule breaks on the end of the line, or if the EOF character is read. + * + * @param scanner the character scanner to be used + * @return true if the end sequence has been detected + */ + protected bool endSequenceDetected(ICharacterScanner scanner) { + + char[][] originalDelimiters= scanner.getLegalLineDelimiters(); + int count= originalDelimiters.length; + if (fLineDelimiters is null || originalDelimiters.length !is count) { + fSortedLineDelimiters= new char[][](count); + } else { + while (count > 0 && fLineDelimiters[count-1] is originalDelimiters[count-1]) + count--; + } + if (count !is 0) { + fLineDelimiters= originalDelimiters; + System.arraycopy(fLineDelimiters, 0, fSortedLineDelimiters, 0, fLineDelimiters.length); + Arrays.sort(fSortedLineDelimiters, fLineDelimiterComparator); + } + + int readCount= 1; + int c; + while ((c= scanner.read()) !is ICharacterScanner.EOF) { + if (c is fEscapeCharacter) { + // Skip escaped character(s) + if (fEscapeContinuesLine) { + c= scanner.read(); + for (int i= 0; i < fSortedLineDelimiters.length; i++) { + if (c is fSortedLineDelimiters[i][0] && sequenceDetected(scanner, fSortedLineDelimiters[i], true)) + break; + } + } else + scanner.read(); + + } else if (fEndSequence.length > 0 && c is fEndSequence[0]) { + // Check if the specified end sequence has been found. + if (sequenceDetected(scanner, fEndSequence, true)) + return true; + } else if (fBreaksOnEOL) { + // Check for end of line since it can be used to terminate the pattern. + for (int i= 0; i < fSortedLineDelimiters.length; i++) { + if (c is fSortedLineDelimiters[i][0] && sequenceDetected(scanner, fSortedLineDelimiters[i], true)) + return true; + } + } + readCount++; + } + + if (fBreaksOnEOF) + return true; + + for (; readCount > 0; readCount--) + scanner.unread(); + + return false; + } + + /** + * Returns whether the next characters to be read by the character scanner + * are an exact match with the given sequence. No escape characters are allowed + * within the sequence. If specified the sequence is considered to be found + * when reading the EOF character. + * + * @param scanner the character scanner to be used + * @param sequence the sequence to be detected + * @param eofAllowed indicated whether EOF terminates the pattern + * @return true if the given sequence has been detected + */ + protected bool sequenceDetected(ICharacterScanner scanner, char[] sequence, bool eofAllowed) { + for (int i= 1; i < sequence.length; i++) { + int c= scanner.read(); + if (c is ICharacterScanner.EOF && eofAllowed) { + return true; + } else if (c !is sequence[i]) { + // Non-matching character detected, rewind the scanner back to the start. + // Do not unread the first character. + scanner.unread(); + for (int j= i-1; j > 0; j--) + scanner.unread(); + return false; + } + } + + return true; + } + + /* + * @see IPredicateRule#evaluate(ICharacterScanner, bool) + * @since 2.0 + */ + public IToken evaluate(ICharacterScanner scanner, bool resume) { + if (fColumn is UNDEFINED) + return doEvaluate(scanner, resume); + + int c= scanner.read(); + scanner.unread(); + if (c is fStartSequence[0]) + return (fColumn is scanner.getColumn() ? doEvaluate(scanner, resume) : Token.UNDEFINED); + return Token.UNDEFINED; + } + + /* + * @see IPredicateRule#getSuccessToken() + * @since 2.0 + */ + public IToken getSuccessToken() { + return fToken; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/RuleBasedDamagerRepairer.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/RuleBasedDamagerRepairer.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.rules.RuleBasedDamagerRepairer; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + +import dwt.dwthelper.utils; + + +import dwtx.jface.text.TextAttribute; + + +/** + * @deprecated use DefaultDamagerRepairer + */ +public class RuleBasedDamagerRepairer : DefaultDamagerRepairer { + + /** + * Creates a damager/repairer that uses the given scanner and returns the given default + * text attribute if the current token does not carry a text attribute. + * + * @param scanner the rule based scanner to be used + * @param defaultTextAttribute the text attribute to be returned if none is specified by the current token, + * may not be null + * + * @deprecated use RuleBasedDamagerRepairer(RuleBasedScanner) instead + */ + public this(RuleBasedScanner scanner, TextAttribute defaultTextAttribute) { + super(scanner, defaultTextAttribute); + } + + /** + * Creates a damager/repairer that uses the given scanner. The scanner may not be null + * and is assumed to return only token that carry text attributes. + * + * @param scanner the rule based scanner to be used, may not be null + * @since 2.0 + */ + public this(RuleBasedScanner scanner) { + super(scanner); + } +} + + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/RuleBasedPartitionScanner.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/RuleBasedPartitionScanner.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,139 @@ +/******************************************************************************* + * 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 + * 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.text.rules.RuleBasedPartitionScanner; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + +import dwt.dwthelper.utils; + + +import dwtx.jface.text.IDocument; + + +/** + * Scanner that exclusively uses predicate rules. + * @since 2.0 + */ +public class RuleBasedPartitionScanner : BufferedRuleBasedScanner , IPartitionTokenScanner { + + /** The content type of the partition in which to resume scanning. */ + protected String fContentType; + /** The offset of the partition inside which to resume. */ + protected int fPartitionOffset; + + + /** + * Disallow setting the rules since this scanner + * exclusively uses predicate rules. + * + * @param rules the sequence of rules controlling this scanner + */ + public void setRules(IRule[] rules) { + throw new UnsupportedOperationException(); + } + + /* + * @see RuleBasedScanner#setRules(IRule[]) + */ + public void setPredicateRules(IPredicateRule[] rules) { + super.setRules(rules); + } + + /* + * @see ITokenScanner#setRange(IDocument, int, int) + */ + public void setRange(IDocument document, int offset, int length) { + setPartialRange(document, offset, length, null, -1); + } + + /* + * @see IPartitionTokenScanner#setPartialRange(IDocument, int, int, String, int) + */ + public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) { + fContentType= contentType; + fPartitionOffset= partitionOffset; + if (partitionOffset > -1) { + int delta= offset - partitionOffset; + if (delta > 0) { + super.setRange(document, partitionOffset, length + delta); + fOffset= offset; + return; + } + } + super.setRange(document, offset, length); + } + + /* + * @see ITokenScanner#nextToken() + */ + public IToken nextToken() { + + + if (fContentType is null || fRules is null) { + //don't try to resume + return super.nextToken(); + } + + // inside a partition + + fColumn= UNDEFINED; + bool resume= (fPartitionOffset > -1 && fPartitionOffset < fOffset); + fTokenOffset= resume ? fPartitionOffset : fOffset; + + IPredicateRule rule; + IToken token; + + for (int i= 0; i < fRules.length; i++) { + rule= cast(IPredicateRule) fRules[i]; + token= rule.getSuccessToken(); + if (fContentType.equals(stringcast(token.getData()))) { + token= rule.evaluate(this, resume); + if (!token.isUndefined()) { + fContentType= null; + return token; + } + } + } + + // haven't found any rule for this type of partition + fContentType= null; + if (resume) + fOffset= fPartitionOffset; + return super.nextToken(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/RuleBasedPartitioner.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/RuleBasedPartitioner.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,616 @@ +/******************************************************************************* + * 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 + * 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.text.rules.RuleBasedPartitioner; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + +import dwt.dwthelper.utils; + + +import dwtx.dwtxhelper.Collection; + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.BadPositionCategoryException; +import dwtx.jface.text.DefaultPositionUpdater; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentPartitioner; +import dwtx.jface.text.IDocumentPartitionerExtension; +import dwtx.jface.text.IDocumentPartitionerExtension2; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITypedRegion; +import dwtx.jface.text.Position; +import dwtx.jface.text.Region; +import dwtx.jface.text.TextUtilities; +import dwtx.jface.text.TypedPosition; +import dwtx.jface.text.TypedRegion; + + + +/** + * A standard implementation of a syntax driven document partitioner. + * It uses a rule based scanner to scan the document and to determine + * the document's partitioning. The tokens returned by the rules the + * scanner is configured with are supposed to return the partition type + * as their data. The partitioner remembers the document's partitions + * in the document itself rather than maintaining its own data structure. + * + * @see IRule + * @see RuleBasedScanner + * + * @deprecated use FastPartitioner instead + */ +public class RuleBasedPartitioner : IDocumentPartitioner, IDocumentPartitionerExtension, IDocumentPartitionerExtension2 { + + /** + * The position category this partitioner uses to store the document's partitioning information + * @deprecated As of 3.0, use getManagingPositionCategories(). + */ + public const static String CONTENT_TYPES_CATEGORY= "__content_types_category"; //$NON-NLS-1$ + + + /** The partitioner's scanner */ + protected RuleBasedScanner fScanner; + /** The legal content types of this partitioner */ + protected String[] fLegalContentTypes; + /** The partitioner's document */ + protected IDocument fDocument; + /** The document length before a document change occurred */ + protected int fPreviousDocumentLength; + /** The position updater used to for the default updating of partitions */ + protected DefaultPositionUpdater fPositionUpdater; + /** The offset at which the first changed partition starts */ + protected int fStartOffset; + /** The offset at which the last changed partition ends */ + protected int fEndOffset; + /**The offset at which a partition has been deleted */ + protected int fDeleteOffset; + /** + * The position category for managing partitioning information. + * @since 3.0 + */ + private String fPositionCategory; + + + /** + * Creates a new partitioner that uses the given scanner and may return + * partitions of the given legal content types. + * + * @param scanner the scanner this partitioner is supposed to use + * @param legalContentTypes the legal content types of this partitioner + */ + public this(RuleBasedScanner scanner, String[] legalContentTypes) { + fScanner= scanner; + fLegalContentTypes= TextUtilities.copy(legalContentTypes); + fPositionCategory= CONTENT_TYPES_CATEGORY ~ Integer.toString(toHash()); + fPositionUpdater= new DefaultPositionUpdater(fPositionCategory); + } + + /* + * @see dwtx.jface.text.IDocumentPartitionerExtension2#getManagingPositionCategories() + * @since 3.0 + */ + public String[] getManagingPositionCategories() { + return [ fPositionCategory ]; + } + + /* + * @see IDocumentPartitioner#connect + */ + public void connect(IDocument document) { + Assert.isNotNull(cast(Object)document); + Assert.isTrue(!document.containsPositionCategory(fPositionCategory)); + + fDocument= document; + fDocument.addPositionCategory(fPositionCategory); + + initialize(); + } + + /** + * Performs the initial partitioning of the partitioner's document. + */ + protected void initialize() { + + fScanner.setRange(fDocument, 0, fDocument.getLength()); + + try { + IToken token= fScanner.nextToken(); + while (!token.isEOF()) { + + String contentType= getTokenContentType(token); + + if (isSupportedContentType(contentType)) { + TypedPosition p= new TypedPosition(fScanner.getTokenOffset(), fScanner.getTokenLength(), contentType); + fDocument.addPosition(fPositionCategory, p); + } + + token= fScanner.nextToken(); + } + } catch (BadLocationException x) { + // cannot happen as offsets come from scanner + } catch (BadPositionCategoryException x) { + // cannot happen if document has been connected before + } + } + + /* + * @see IDocumentPartitioner#disconnect + */ + public void disconnect() { + + Assert.isTrue(fDocument.containsPositionCategory(fPositionCategory)); + + try { + fDocument.removePositionCategory(fPositionCategory); + } catch (BadPositionCategoryException x) { + // can not happen because of Assert + } + } + + /* + * @see IDocumentPartitioner#documentAboutToBeChanged + */ + public void documentAboutToBeChanged(DocumentEvent e) { + + Assert.isTrue(e.getDocument() is fDocument); + + fPreviousDocumentLength= e.getDocument().getLength(); + fStartOffset= -1; + fEndOffset= -1; + fDeleteOffset= -1; + } + + /* + * @see IDocumentPartitioner#documentChanged + */ + public bool documentChanged(DocumentEvent e) { + IRegion region= documentChanged2(e); + return (region !is null); + } + + /** + * Helper method for tracking the minimal region containing all partition changes. + * If offset is smaller than the remembered offset, offset + * will from now on be remembered. If offset + length is greater than + * the remembered end offset, it will be remembered from now on. + * + * @param offset the offset + * @param length the length + */ + private void rememberRegion(int offset, int length) { + // remember start offset + if (fStartOffset is -1) + fStartOffset= offset; + else if (offset < fStartOffset) + fStartOffset= offset; + + // remember end offset + int endOffset= offset + length; + if (fEndOffset is -1) + fEndOffset= endOffset; + else if (endOffset > fEndOffset) + fEndOffset= endOffset; + } + + /** + * Remembers the given offset as the deletion offset. + * + * @param offset the offset + */ + private void rememberDeletedOffset(int offset) { + fDeleteOffset= offset; + } + + /** + * Creates the minimal region containing all partition changes using the + * remembered offset, end offset, and deletion offset. + * @return the minimal region containing all the partition changes + */ + private IRegion createRegion() { + if (fDeleteOffset is -1) { + if (fStartOffset is -1 || fEndOffset is -1) + return null; + return new Region(fStartOffset, fEndOffset - fStartOffset); + } else if (fStartOffset is -1 || fEndOffset is -1) { + return new Region(fDeleteOffset, 0); + } else { + int offset= Math.min(fDeleteOffset, fStartOffset); + int endOffset= Math.max(fDeleteOffset, fEndOffset); + return new Region(offset, endOffset - offset); + } + } + + /* + * @see IDocumentPartitionerExtension#documentChanged2(DocumentEvent) + * @since 2.0 + */ + public IRegion documentChanged2(DocumentEvent e) { + + try { + + IDocument d= e.getDocument(); + Position[] category= d.getPositions(fPositionCategory); + int first= 0; + int reparseStart= 0; + int originalSize= category.length; + + if (originalSize > 0) { + + /* + * determine character position at which the scanner starts: + * first position behind the last non-default partition the actual position is not involved with + */ + + first= d.computeIndexInCategory(fPositionCategory, e.getOffset()); + + Position p= null; + do { + --first; + if (first < 0) + break; + + p= category[first]; + + } while (p.overlapsWith(e.getOffset(), e.getLength()) || + (e.getOffset() is fPreviousDocumentLength && + (p.getOffset() + p.getLength() is fPreviousDocumentLength))); + + fPositionUpdater.update(e); + for (int i= 0; i < category.length; i++) { + p= category[i]; + if (p.isDeleted) { + rememberDeletedOffset(e.getOffset()); + break; + } + } + category= d.getPositions(fPositionCategory); + + if (first >= 0) { + p= category[first]; + reparseStart= p.getOffset() + p.getLength(); + } + + ++first; + } + + fScanner.setRange(d, reparseStart, d.getLength() - reparseStart); + + int lastScannedPosition= reparseStart; + IToken token= fScanner.nextToken(); + + while (!token.isEOF()) { + + + String contentType= getTokenContentType(token); + + if (!isSupportedContentType(contentType)) { + token= fScanner.nextToken(); + continue; + } + + int start= fScanner.getTokenOffset(); + int length= fScanner.getTokenLength(); + + lastScannedPosition= start + length - 1; + + // remove all affected positions + while (first < category.length) { + TypedPosition p= cast(TypedPosition) category[first]; + if (lastScannedPosition >= p.offset + p.length || + (p.overlapsWith(start, length) && + (!d.containsPosition(fPositionCategory, start, length) || + !contentType.equals(p.getType())))) { + + rememberRegion(p.offset, p.length); + d.removePosition(fPositionCategory, p); + ++ first; + + } else + break; + } + + // if position already exists we are done + if (d.containsPosition(fPositionCategory, start, length)) + return createRegion(); + + // insert the new type position + try { + d.addPosition(fPositionCategory, new TypedPosition(start, length, contentType)); + rememberRegion(start, length); + } catch (BadPositionCategoryException x) { + } catch (BadLocationException x) { + } + + token= fScanner.nextToken(); + } + + + // remove all positions behind lastScannedPosition since there aren't any further types + if (lastScannedPosition !is reparseStart) { + // if this condition is not met, nothing has been scanned because of a delete + ++ lastScannedPosition; + } + first= d.computeIndexInCategory(fPositionCategory, lastScannedPosition); + + TypedPosition p; + while (first < category.length) { + p= cast(TypedPosition) category[first++]; + d.removePosition(fPositionCategory, p); + rememberRegion(p.offset, p.length); + } + + } catch (BadPositionCategoryException x) { + // should never happen on connected documents + } catch (BadLocationException x) { + } + + return createRegion(); + } + + + /** + * Returns the position in the partitoner's position category which is + * close to the given offset. This is, the position has either an offset which + * is the same as the given offset or an offset which is smaller than the given + * offset. This method profits from the knowledge that a partitioning is + * a ordered set of disjoint position. + * + * @param offset the offset for which to search the closest position + * @return the closest position in the partitioner's category + */ + protected TypedPosition findClosestPosition(int offset) { + + try { + + int index= fDocument.computeIndexInCategory(fPositionCategory, offset); + Position[] category= fDocument.getPositions(fPositionCategory); + + if (category.length is 0) + return null; + + if (index < category.length) { + if (offset is category[index].offset) + return cast(TypedPosition) category[index]; + } + + if (index > 0) + index--; + + return cast(TypedPosition) category[index]; + + } catch (BadPositionCategoryException x) { + } catch (BadLocationException x) { + } + + return null; + } + + + /* + * @see IDocumentPartitioner#getContentType + */ + public String getContentType(int offset) { + + TypedPosition p= findClosestPosition(offset); + if (p !is null && p.includes(offset)) + return p.getType(); + + return IDocument.DEFAULT_CONTENT_TYPE; + } + + /* + * @see IDocumentPartitioner#getPartition + */ + public ITypedRegion getPartition(int offset) { + + try { + + Position[] category = fDocument.getPositions(fPositionCategory); + + if (category is null || category.length is 0) + return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE); + + int index= fDocument.computeIndexInCategory(fPositionCategory, offset); + + if (index < category.length) { + + TypedPosition next= cast(TypedPosition) category[index]; + + if (offset is next.offset) + return new TypedRegion(next.getOffset(), next.getLength(), next.getType()); + + if (index is 0) + return new TypedRegion(0, next.offset, IDocument.DEFAULT_CONTENT_TYPE); + + TypedPosition previous= cast(TypedPosition) category[index - 1]; + if (previous.includes(offset)) + return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType()); + + int endOffset= previous.getOffset() + previous.getLength(); + return new TypedRegion(endOffset, next.getOffset() - endOffset, IDocument.DEFAULT_CONTENT_TYPE); + } + + TypedPosition previous= cast(TypedPosition) category[category.length - 1]; + if (previous.includes(offset)) + return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType()); + + int endOffset= previous.getOffset() + previous.getLength(); + return new TypedRegion(endOffset, fDocument.getLength() - endOffset, IDocument.DEFAULT_CONTENT_TYPE); + + } catch (BadPositionCategoryException x) { + } catch (BadLocationException x) { + } + + return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE); + } + + /* + * @see IDocumentPartitioner#computePartitioning + */ + public ITypedRegion[] computePartitioning(int offset, int length) { + return computePartitioning(offset, length, false); + } + + /* + * @see IDocumentPartitioner#getLegalContentTypes + */ + public String[] getLegalContentTypes() { + return TextUtilities.copy(fLegalContentTypes); + } + + /** + * Returns whether the given type is one of the legal content types. + * + * @param contentType the content type to check + * @return true if the content type is a legal content type + */ + protected bool isSupportedContentType(String contentType) { + if (contentType !is null) { + for (int i= 0; i < fLegalContentTypes.length; i++) { + if (fLegalContentTypes[i].equals(contentType)) + return true; + } + } + + return false; + } + + /** + * Returns a content type encoded in the given token. If the token's + * data is not null and a string it is assumed that + * it is the encoded content type. + * + * @param token the token whose content type is to be determined + * @return the token's content type + */ + protected String getTokenContentType(IToken token) { + Object data= token.getData(); + if ( auto str = cast(ArrayWrapperString)data ) + return str.array; + return null; + } + + /* zero-length partition support */ + + /* + * @see dwtx.jface.text.IDocumentPartitionerExtension2#getContentType(int) + * @since 3.0 + */ + public String getContentType(int offset, bool preferOpenPartitions) { + return getPartition(offset, preferOpenPartitions).getType(); + } + + /* + * @see dwtx.jface.text.IDocumentPartitionerExtension2#getPartition(int) + * @since 3.0 + */ + public ITypedRegion getPartition(int offset, bool preferOpenPartitions) { + ITypedRegion region= getPartition(offset); + if (preferOpenPartitions) { + if (region.getOffset() is offset && !region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE)) { + if (offset > 0) { + region= getPartition(offset - 1); + if (region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE)) + return region; + } + return new TypedRegion(offset, 0, IDocument.DEFAULT_CONTENT_TYPE); + } + } + return region; + } + + /* + * @see dwtx.jface.text.IDocumentPartitionerExtension2#computePartitioning(int, int) + * @since 3.0 + */ + public ITypedRegion[] computePartitioning(int offset, int length, bool includeZeroLengthPartitions) { + List list= new ArrayList(); + + try { + + int endOffset= offset + length; + + Position[] category= fDocument.getPositions(fPositionCategory); + + TypedPosition previous= null, current= null; + int start, end, gapOffset; + Position gap= null; + + for (int i= 0; i < category.length; i++) { + + current= cast(TypedPosition) category[i]; + + gapOffset= (previous !is null) ? previous.getOffset() + previous.getLength() : 0; + gap= new Position(gapOffset, current.getOffset() - gapOffset); + if ((includeZeroLengthPartitions || gap.getLength() > 0) && gap.overlapsWith(offset, length)) { + start= Math.max(offset, gapOffset); + end= Math.min(endOffset, gap.getOffset() + gap.getLength()); + list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE)); + } + + if (current.overlapsWith(offset, length)) { + start= Math.max(offset, current.getOffset()); + end= Math.min(endOffset, current.getOffset() + current.getLength()); + list.add(new TypedRegion(start, end - start, current.getType())); + } + + previous= current; + } + + if (previous !is null) { + gapOffset= previous.getOffset() + previous.getLength(); + gap= new Position(gapOffset, fDocument.getLength() - gapOffset); + if ((includeZeroLengthPartitions || gap.getLength() > 0) && ((includeZeroLengthPartitions && offset + length is gapOffset && gap.length is 0) || gap.overlapsWith(offset, length))) { + start= Math.max(offset, gapOffset); + end= Math.min(endOffset, fDocument.getLength()); + list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE)); + } + } + + if (list.isEmpty()) + list.add(new TypedRegion(offset, length, IDocument.DEFAULT_CONTENT_TYPE)); + + } catch (BadPositionCategoryException x) { + } + + return arraycast!(ITypedRegion)(list.toArray()); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/RuleBasedScanner.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/RuleBasedScanner.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,246 @@ +/******************************************************************************* + * 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 + * 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.text.rules.RuleBasedScanner; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + +import dwt.dwthelper.utils; + + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; + + +/** + * A generic scanner which can be "programmed" with a sequence of rules. + * The scanner is used to get the next token by evaluating its rule in sequence until + * one is successful. If a rule returns a token which is undefined, the scanner will proceed to + * the next rule. Otherwise the token provided by the rule will be returned by + * the scanner. If no rule returned a defined token, this scanner returns a token + * which returns true when calling isOther, unless the end + * of the file is reached. In this case the token returns true when calling + * isEOF. + * + * @see IRule + */ +public class RuleBasedScanner : ICharacterScanner, ITokenScanner { + + /** The list of rules of this scanner */ + protected IRule[] fRules; + /** The token to be returned by default if no rule fires */ + protected IToken fDefaultReturnToken; + /** The document to be scanned */ + protected IDocument fDocument; + /** The cached legal line delimiters of the document */ + protected char[][] fDelimiters; + /** The offset of the next character to be read */ + protected int fOffset; + /** The end offset of the range to be scanned */ + protected int fRangeEnd; + /** The offset of the last read token */ + protected int fTokenOffset; + /** The cached column of the current scanner position */ + protected int fColumn; + /** Internal setting for the un-initialized column cache. */ + protected static final int UNDEFINED= -1; + + /** + * Creates a new rule based scanner which does not have any rule. + */ + public this() { + } + + /** + * Configures the scanner with the given sequence of rules. + * + * @param rules the sequence of rules controlling this scanner + */ + public void setRules(IRule[] rules) { + if (rules !is null) { + fRules= new IRule[rules.length]; + SimpleType!(IRule).arraycopy(rules, 0, fRules, 0, rules.length); + } else + fRules= null; + } + + /** + * Configures the scanner's default return token. This is the token + * which is returned when none of the rules fired and EOF has not been + * reached. + * + * @param defaultReturnToken the default return token + * @since 2.0 + */ + public void setDefaultReturnToken(IToken defaultReturnToken) { + Assert.isNotNull(defaultReturnToken.getData()); + fDefaultReturnToken= defaultReturnToken; + } + + /* + * @see ITokenScanner#setRange(IDocument, int, int) + */ + public void setRange(IDocument document, int offset, int length) { + Assert.isLegal(document !is null); + final int documentLength= document.getLength(); + checkRange(offset, length, documentLength); + + fDocument= document; + fOffset= offset; + fColumn= UNDEFINED; + fRangeEnd= offset + length; + + String[] delimiters= fDocument.getLegalLineDelimiters(); + fDelimiters= new char[][](delimiters.length); + for (int i= 0; i < delimiters.length; i++) + fDelimiters[i]= delimiters[i].toCharArray(); + + if (fDefaultReturnToken is null) + fDefaultReturnToken= new Token(null); + } + + /** + * Checks that the given range is valid. + * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=69292 + * + * @param offset the offset of the document range to scan + * @param length the length of the document range to scan + * @param documentLength the document's length + * @since 3.3 + */ + private void checkRange(int offset, int length, int documentLength) { + Assert.isLegal(offset > -1); + Assert.isLegal(length > -1); + Assert.isLegal(offset + length <= documentLength); + } + + /* + * @see ITokenScanner#getTokenOffset() + */ + public int getTokenOffset() { + return fTokenOffset; + } + + /* + * @see ITokenScanner#getTokenLength() + */ + public int getTokenLength() { + if (fOffset < fRangeEnd) + return fOffset - getTokenOffset(); + return fRangeEnd - getTokenOffset(); + } + + + /* + * @see ICharacterScanner#getColumn() + */ + public int getColumn() { + if (fColumn is UNDEFINED) { + try { + int line= fDocument.getLineOfOffset(fOffset); + int start= fDocument.getLineOffset(line); + + fColumn= fOffset - start; + + } catch (BadLocationException ex) { + } + } + return fColumn; + } + + /* + * @see ICharacterScanner#getLegalLineDelimiters() + */ + public char[][] getLegalLineDelimiters() { + return fDelimiters; + } + + /* + * @see ITokenScanner#nextToken() + */ + public IToken nextToken() { + + fTokenOffset= fOffset; + fColumn= UNDEFINED; + + if (fRules !is null) { + for (int i= 0; i < fRules.length; i++) { + IToken token= (fRules[i].evaluate(this)); + if (!token.isUndefined()) + return token; + } + } + + if (read() is EOF) + return Token.EOF; + return fDefaultReturnToken; + } + + /* + * @see ICharacterScanner#read() + */ + public int read() { + + try { + + if (fOffset < fRangeEnd) { + try { + return fDocument.getChar(fOffset); + } catch (BadLocationException e) { + } + } + + return EOF; + + } finally { + ++ fOffset; + fColumn= UNDEFINED; + } + } + + /* + * @see ICharacterScanner#unread() + */ + public void unread() { + --fOffset; + fColumn= UNDEFINED; + } +} + + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/SingleLineRule.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/SingleLineRule.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2000, 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 + * Christopher Lenz (cmlenz@gmx.de) - support for line continuation + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.text.rules.SingleLineRule; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * A specific configuration of pattern rule whereby + * the pattern begins with a specific sequence and may + * end with a specific sequence, but will not span more + * than a single line. + */ +public class SingleLineRule : PatternRule { + + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specified token. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence + * @param token the token to be returned on success + */ + public this(String startSequence, String endSequence, IToken token) { + this(startSequence, endSequence, token, cast(wchar) 0); + } + + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specified token. + * Any character which follows the given escape character + * will be ignored. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence + * @param token the token to be returned on success + * @param escapeCharacter the escape character + */ + public this(String startSequence, String endSequence, IToken token, char escapeCharacter) { + this(startSequence, endSequence, token, escapeCharacter, false); + } + + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specified token. Alternatively, the + * line can also be ended with the end of the file. + * Any character which follows the given escape character + * will be ignored. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence + * @param token the token to be returned on success + * @param escapeCharacter the escape character + * @param breaksOnEOF indicates whether the end of the file successfully terminates this rule + * @since 2.1 + */ + public this(String startSequence, String endSequence, IToken token, char escapeCharacter, bool breaksOnEOF) { + super(startSequence, endSequence, token, escapeCharacter, true, breaksOnEOF); + } + + /** + * Creates a rule for the given starting and ending sequence + * which, if detected, will return the specified token. Alternatively, the + * line can also be ended with the end of the file. + * Any character which follows the given escape character + * will be ignored. In addition, an escape character immediately before an + * end of line can be set to continue the line. + * + * @param startSequence the pattern's start sequence + * @param endSequence the pattern's end sequence + * @param token the token to be returned on success + * @param escapeCharacter the escape character + * @param breaksOnEOF indicates whether the end of the file successfully terminates this rule + * @param escapeContinuesLine indicates whether the specified escape character is used for line + * continuation, so that an end of line immediately after the escape character does not + * terminate the line, even if breakOnEOL is true + * @since 3.0 + */ + public this(String startSequence, String endSequence, IToken token, char escapeCharacter, bool breaksOnEOF, bool escapeContinuesLine) { + super(startSequence, endSequence, token, escapeCharacter, true, breaksOnEOF, escapeContinuesLine); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/Token.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/Token.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,195 @@ +/******************************************************************************* + * 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 + * 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.text.rules.Token; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + +import dwt.dwthelper.utils; + +import dwtx.core.runtime.Assert; + + +/** + * Standard implementation of IToken. + */ +public class Token : IToken { + + /** Internal token type: Undefined */ + private static const int T_UNDEFINED= 0; + /** Internal token type: EOF */ + private static const int T_EOF= 1; + /** Internal token type: Whitespace */ + private static const int T_WHITESPACE= 2; + /** Internal token type: Others */ + private static const int T_OTHER= 3; + + + /** + * Standard token: Undefined. + */ + public static IToken UNDEFINED_; + public static IToken UNDEFINED(){ + if( UNDEFINED_ is null ){ + synchronized( Token.classinfo ){ + if( UNDEFINED_ is null ){ + UNDEFINED_ = new Token(T_UNDEFINED); + } + } + } + return UNDEFINED_; + } + /** + * Standard token: End Of File. + */ + public static IToken EOF_; + public static IToken EOF(){ + if( EOF_ is null ){ + synchronized( Token.classinfo ){ + if( EOF_ is null ){ + EOF_ = new Token(T_EOF); + } + } + } + return EOF_; + } + /** + * Standard token: Whitespace. + */ + public static IToken WHITESPACE_; + public static IToken WHITESPACE(){ + if( WHITESPACE_ is null ){ + synchronized( Token.classinfo ){ + if( WHITESPACE_ is null ){ + WHITESPACE_ = new Token(T_WHITESPACE); + } + } + } + return WHITESPACE_; + } + + /** + * Standard token: Neither {@link #UNDEFINED}, {@link #WHITESPACE}, nor {@link #EOF}. + * @deprecated will be removed + */ + public static IToken OTHER_; + public static IToken OTHER(){ + if( OTHER_ is null ){ + synchronized( Token.classinfo ){ + if( OTHER_ is null ){ + OTHER_ = new Token(T_OTHER); + } + } + } + return OTHER_; + } + + /** The type of this token */ + private int fType; + /** The data associated with this token */ + private Object fData; + + /** + * Creates a new token according to the given specification which does not + * have any data attached to it. + * + * @param type the type of the token + * @since 2.0 + */ + private this(int type) { + fType= type; + fData= null; + } + + /** + * Creates a new token which represents neither undefined, whitespace, nor EOF. + * The newly created token has the given data attached to it. + * + * @param data the data attached to the newly created token + */ + public this(Object data) { + fType= T_OTHER; + fData= data; + } + + /** + * Re-initializes the data of this token. The token may not represent + * undefined, whitespace, or EOF. + * + * @param data to be attached to the token + * @since 2.0 + */ + public void setData(Object data) { + Assert.isTrue(isOther()); + fData= data; + } + + /* + * @see IToken#getData() + */ + public Object getData() { + return fData; + } + + /* + * @see IToken#isOther() + */ + public bool isOther() { + return (fType is T_OTHER); + } + + /* + * @see IToken#isEOF() + */ + public bool isEOF() { + return (fType is T_EOF); + } + + /* + * @see IToken#isWhitespace() + */ + public bool isWhitespace() { + return (fType is T_WHITESPACE); + } + + /* + * @see IToken#isUndefined() + */ + public bool isUndefined() { + return (fType is T_UNDEFINED); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/WhitespaceRule.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/WhitespaceRule.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,88 @@ +/******************************************************************************* + * 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 + * 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.text.rules.WhitespaceRule; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + +import dwt.dwthelper.utils; + + +import dwtx.core.runtime.Assert; + + +/** + * An implementation of IRule capable of detecting whitespace. + * A whitespace rule uses a whitespace detector in order to find out which + * characters are whitespace characters. + * + * @see IWhitespaceDetector + */ +public class WhitespaceRule : IRule { + + /** The whitespace detector used by this rule */ + protected IWhitespaceDetector fDetector; + + /** + * Creates a rule which, with the help of an + * whitespace detector, will return a whitespace + * token when a whitespace is detected. + * + * @param detector the rule's whitespace detector, may not be null + */ + public this(IWhitespaceDetector detector) { + Assert.isNotNull(cast(Object)detector); + fDetector= detector; + } + + /* + * @see IRule#evaluate(ICharacterScanner) + */ + public IToken evaluate(ICharacterScanner scanner) { + int c= scanner.read(); + if (fDetector.isWhitespace(cast(char) c)) { + do { + c= scanner.read(); + } while (fDetector.isWhitespace(cast(char) c)); + scanner.unread(); + return Token.WHITESPACE; + } + + scanner.unread(); + return Token.UNDEFINED; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/WordPatternRule.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/WordPatternRule.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,140 @@ +/******************************************************************************* + * 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 + * 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.text.rules.WordPatternRule; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WordRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.core.runtime.Assert; + + + +/** + * A specific single line rule which stipulates that the start + * and end sequence occur within a single word, as defined by a word detector. + * + * @see IWordDetector + */ +public class WordPatternRule : SingleLineRule { + + /** The word detector used by this rule */ + protected IWordDetector fDetector; + /** The internal buffer used for pattern detection */ + private StringBuffer fBuffer; + + /** + * Creates a rule for the given starting and ending word + * pattern which, if detected, will return the specified token. + * A word detector is used to identify words. + * + * @param detector the word detector to be used + * @param startSequence the start sequence of the word pattern + * @param endSequence the end sequence of the word pattern + * @param token the token to be returned on success + */ + public this(IWordDetector detector, String startSequence, String endSequence, IToken token) { + this(detector, startSequence, endSequence, token, cast(wchar)0); + } + + /** + /** + * Creates a rule for the given starting and ending word + * pattern which, if detected, will return the specified token. + * A word detector is used to identify words. + * Any character which follows the given escapeCharacter will be ignored. + * + * @param detector the word detector to be used + * @param startSequence the start sequence of the word pattern + * @param endSequence the end sequence of the word pattern + * @param token the token to be returned on success + * @param escapeCharacter the escape character + */ + public this(IWordDetector detector, String startSequence, String endSequence, IToken token, char escapeCharacter) { + fBuffer= new StringBuffer(); + super(startSequence, endSequence, token, escapeCharacter); + Assert.isNotNull(cast(Object)detector); + fDetector= detector; + } + + /** + * Returns whether the end sequence was detected. + * The rule acquires the rest of the word, using the + * provided word detector, and tests to determine if + * it ends with the end sequence. + * + * @param scanner the scanner to be used + * @return true if the word ends on the given end sequence + */ + protected bool endSequenceDetected(ICharacterScanner scanner) { + fBuffer.truncate(0); + int c= scanner.read(); + while (fDetector.isWordPart(cast(char) c)) { + fBuffer.append(cast(char) c); + c= scanner.read(); + } + scanner.unread(); + + if (fBuffer.length() >= fEndSequence.length) { + for (int i=fEndSequence.length - 1, j= fBuffer.length() - 1; i >= 0; i--, j--) { + if (fEndSequence[i] !is fBuffer.slice()[j]) { + unreadBuffer(scanner); + return false; + } + } + return true; + } + + unreadBuffer(scanner); + return false; + } + + /** + * Returns the characters in the buffer to the scanner. + * Note that the rule must also return the characters + * read in as part of the start sequence expect the first one. + * + * @param scanner the scanner to be used + */ + protected void unreadBuffer(ICharacterScanner scanner) { + fBuffer.select(0, 0 ); + fBuffer.replace(fStartSequence); + for (int i= fBuffer.length() - 1; i > 0; i--) + scanner.unread(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/rules/WordRule.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/rules/WordRule.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,214 @@ +/******************************************************************************* + * 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 + * 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.text.rules.WordRule; + +import dwtx.jface.text.rules.FastPartitioner; // packageimport +import dwtx.jface.text.rules.ITokenScanner; // packageimport +import dwtx.jface.text.rules.Token; // packageimport +import dwtx.jface.text.rules.RuleBasedScanner; // packageimport +import dwtx.jface.text.rules.EndOfLineRule; // packageimport +import dwtx.jface.text.rules.WhitespaceRule; // packageimport +import dwtx.jface.text.rules.WordPatternRule; // packageimport +import dwtx.jface.text.rules.IPredicateRule; // packageimport +import dwtx.jface.text.rules.DefaultPartitioner; // packageimport +import dwtx.jface.text.rules.NumberRule; // packageimport +import dwtx.jface.text.rules.SingleLineRule; // packageimport +import dwtx.jface.text.rules.PatternRule; // packageimport +import dwtx.jface.text.rules.IWordDetector; // packageimport +import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport +import dwtx.jface.text.rules.ICharacterScanner; // packageimport +import dwtx.jface.text.rules.IRule; // packageimport +import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport +import dwtx.jface.text.rules.IToken; // packageimport +import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport +import dwtx.jface.text.rules.MultiLineRule; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport +import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport +import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport +import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.dwtxhelper.Collection; + + + +import dwtx.core.runtime.Assert; + + + +/** + * An implementation of IRule capable of detecting words + * Word rules also allow for the association of tokens with specific words. + * That is, not only can the rule be used to provide tokens for exact matches, + * but also for the generalized notion of a word in the context in which it is used. + * A word rules uses a word detector to determine what a word is. + * + * @see IWordDetector + */ +public class WordRule : IRule { + + /** Internal setting for the un-initialized column constraint. */ + protected static const int UNDEFINED= -1; + + /** The word detector used by this rule. */ + protected IWordDetector fDetector; + /** The default token to be returned on success and if nothing else has been specified. */ + protected IToken fDefaultToken; + /** The column constraint. */ + protected int fColumn= UNDEFINED; + /** The table of predefined words and token for this rule. */ + protected Map fWords; + /** Buffer used for pattern detection. */ + private StringBuffer fBuffer; + /** + * Tells whether this rule is case sensitive. + * @since 3.3 + */ + private bool fIgnoreCase= false; + + /** + * Creates a rule which, with the help of an word detector, will return the token + * associated with the detected word. If no token has been associated, the scanner + * will be rolled back and an undefined token will be returned in order to allow + * any subsequent rules to analyze the characters. + * + * @param detector the word detector to be used by this rule, may not be null + * @see #addWord(String, IToken) + */ + public this(IWordDetector detector) { + this(detector, Token.UNDEFINED, false); + } + + /** + * Creates a rule which, with the help of a word detector, will return the token + * associated with the detected word. If no token has been associated, the + * specified default token will be returned. + * + * @param detector the word detector to be used by this rule, may not be null + * @param defaultToken the default token to be returned on success + * if nothing else is specified, may not be null + * @see #addWord(String, IToken) + */ + public this(IWordDetector detector, IToken defaultToken) { + this(detector, defaultToken, false); + } + + /** + * Creates a rule which, with the help of a word detector, will return the token + * associated with the detected word. If no token has been associated, the + * specified default token will be returned. + * + * @param detector the word detector to be used by this rule, may not be null + * @param defaultToken the default token to be returned on success + * if nothing else is specified, may not be null + * @param ignoreCase the case sensitivity associated with this rule + * @see #addWord(String, IToken) + * @since 3.3 + */ + public this(IWordDetector detector, IToken defaultToken, bool ignoreCase) { + fWords= new HashMap(); + fBuffer= new StringBuffer(); + + Assert.isNotNull(cast(Object)detector); + Assert.isNotNull(cast(Object)defaultToken); + + fDetector= detector; + fDefaultToken= defaultToken; + fIgnoreCase= ignoreCase; + } + + /** + * Adds a word and the token to be returned if it is detected. + * + * @param word the word this rule will search for, may not be null + * @param token the token to be returned if the word has been found, may not be null + */ + public void addWord(String word, IToken token) { + //Assert.isNotNull(word); + Assert.isNotNull(cast(Object)token); + + fWords.put(word, cast(Object)token); + } + + /** + * Sets a column constraint for this rule. If set, the rule's token + * will only be returned if the pattern is detected starting at the + * specified column. If the column is smaller then 0, the column + * constraint is considered removed. + * + * @param column the column in which the pattern starts + */ + public void setColumnConstraint(int column) { + if (column < 0) + column= UNDEFINED; + fColumn= column; + } + + /* + * @see IRule#evaluate(ICharacterScanner) + */ + public IToken evaluate(ICharacterScanner scanner) { + int c= scanner.read(); + if (c !is ICharacterScanner.EOF && fDetector.isWordStart(cast(char) c)) { + if (fColumn is UNDEFINED || (fColumn is scanner.getColumn() - 1)) { + + fBuffer.truncate(0); + do { + fBuffer.append(cast(char) c); + c= scanner.read(); + } while (c !is ICharacterScanner.EOF && fDetector.isWordPart(cast(char) c)); + scanner.unread(); + + String buffer= fBuffer.toString(); + IToken token= cast(IToken)fWords.get(buffer); + + if(fIgnoreCase) { + Iterator iter= fWords.keySet().iterator(); + while (iter.hasNext()) { + String key= stringcast(iter.next()); + if(buffer.equalsIgnoreCase(key)) { + token= cast(IToken)fWords.get(key); + break; + } + } + } else + token= cast(IToken)fWords.get(buffer); + + if (token !is null) + return token; + + if (fDefaultToken.isUndefined()) + unreadBuffer(scanner); + + return fDefaultToken; + } + } + + scanner.unread(); + return Token.UNDEFINED; + } + + /** + * Returns the characters in the buffer to the scanner. + * + * @param scanner the scanner to be used + */ + protected void unreadBuffer(ICharacterScanner scanner) { + for (int i= fBuffer.length() - 1; i >= 0; i--) + scanner.unread(); + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/AbstractRulerColumn.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/AbstractRulerColumn.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,725 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.text.source.AbstractRulerColumn; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + + + + +import dwt.DWT; +import dwt.custom.StyledText; +import dwt.events.MouseEvent; +import dwt.events.MouseListener; +import dwt.events.MouseMoveListener; +import dwt.events.PaintEvent; +import dwt.events.PaintListener; +import dwt.graphics.Color; +import dwt.graphics.Font; +import dwt.graphics.GC; +import dwt.widgets.Canvas; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwtx.core.runtime.Assert; +import dwtx.jface.resource.JFaceResources; +import dwtx.jface.text.ITextListener; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.IViewportListener; +import dwtx.jface.text.JFaceTextUtil; +import dwtx.jface.text.TextEvent; + + +/** + * Abstract implementation of a {@link IVerticalRulerColumn} that + * uses a {@link Canvas} to draw the ruler contents and which + * handles scrolling and mouse selection. + * + *

                    Painting

                    + * Subclasses can hook into the paint loop at three levels: + *
                      + *
                    • Override {@link #paint(GC, ILineRange)} to control the entire painting of + * the ruler.
                    • + *
                    • Override {@link #paintLine(GC, int, int, int, int)} to control the + * painting of a line.
                    • + *
                    • Leave the painting to the default implementation, but override {@link #computeBackground(int)}, + * {@link #computeForeground(int)} and {@link #computeText(int)} + * to specify the ruler appearance for a line.
                    • + *
                    + * + *

                    Invalidation

                    + * Subclasses may call {@link #redraw()} to mark the entire ruler as needing to be redrawn. + * Alternatively, use {@link #redraw(ILineRange)} to only invalidate a certain line range, for + * example due to changes to the display model. + * + *

                    Configuration

                    + * Subclasses can set the following properties. Setting them may trigger redrawing. + *
                      + *
                    • The {@link #setFont(Font) font} used to draw text in {@link #paintLine(GC, int, int, int, int)}.
                    • + *
                    • The horizontal {@link #setTextInset(int) text inset} for text drawn.
                    • + *
                    • The {@link #setDefaultBackground(Color) default background color} of the ruler.
                    • + *
                    • The {@link #setWidth(int) width} of the ruler.
                    • + *
                    + * + * @since 3.3 + */ +public abstract class AbstractRulerColumn : IVerticalRulerColumn, IVerticalRulerInfo, IVerticalRulerInfoExtension { + private static const int DEFAULT_WIDTH= 12; + private static const int DEFAULT_TEXT_INSET= 2; + + /** + * Handles all the mouse interaction in this line number ruler column. + */ + private final class MouseHandler : MouseListener, MouseMoveListener { + + /* + * @see dwt.events.MouseListener#mouseUp(dwt.events.MouseEvent) + */ + public void mouseUp(MouseEvent event) { + } + + /* + * @see dwt.events.MouseListener#mouseDown(dwt.events.MouseEvent) + */ + public void mouseDown(MouseEvent event) { + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + } + + /* + * @see dwt.events.MouseListener#mouseDoubleClick(dwt.events.MouseEvent) + */ + public void mouseDoubleClick(MouseEvent event) { + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + } + + /* + * @see dwt.events.MouseMoveListener#mouseMove(dwt.events.MouseEvent) + */ + public void mouseMove(MouseEvent event) { + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + } + } + + /** + * Internal listener class that updates the ruler upon scrolling and text modifications. + */ + private final class InternalListener : IViewportListener, ITextListener { + + /* + * @see IViewportListener#viewportChanged(int) + */ + public void viewportChanged(int topPixel) { + int delta= topPixel - fLastTopPixel; + if (scrollVertical(delta)) + fCanvas.update(); // force update the invalidated regions + } + + /* + * @see ITextListener#textChanged(TextEvent) + */ + public void textChanged(TextEvent event) { + /* + * Redraw: - when the viewer is drawing, and any of the following - the widget was not + * full before the change - the widget is not full after the change - the document event + * was a visual modification (no document event attached) - for example when the + * projection changes. + */ + if (!event.getViewerRedrawState()) + return; + + if (fWasShowingEntireContents || event.getDocumentEvent() is null || JFaceTextUtil.isShowingEntireContents(fStyledText)) + redraw(); + } + } + + /* Listeners */ + + /** The viewport listener. */ + private const InternalListener fInternalListener; + /** The mouse handler. */ + private const MouseHandler fMouseHandler; + + /* + * Implementation and context of this ruler - created and set in createControl(), disposed of in + * columnRemoved(). + */ + + /** The parent ruler, possibly null. */ + private CompositeRuler fParentRuler; + /** The canvas, the only widget used to draw this ruler, possibly null. */ + private Canvas fCanvas; + /** The text viewer, possibly null. */ + private ITextViewer fTextViewer; + /** The text viewer's widget, possibly null. */ + private StyledText fStyledText; + + /* State when the canvas was last painted. */ + + /** The text widget's top pixel when the ruler was last painted. */ + private int fLastTopPixel= -1; + /** Whether the text widget was showing the entire contents when the ruler was last painted. */ + private bool fWasShowingEntireContents= false; + + /* Configuration */ + + /** The width of this ruler. */ + private int fWidth= DEFAULT_WIDTH; + /** The text inset. */ + private int fTextInset= DEFAULT_TEXT_INSET; + /** The default background color, null to use the text viewer's background color. */ + private Color fBackground; + /** The font, null to use the default font. */ + private Font fFont; + /** The annotation model, possibly null. */ + private IAnnotationModel fModel; + /** The annotation hover, possibly null. */ + private IAnnotationHover fHover; + + /** + * Creates a new ruler. + */ + protected this() { + fMouseHandler= new MouseHandler(); + fInternalListener= new InternalListener(); + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerColumn#createControl(dwtx.jface.text.source.CompositeRuler, + * dwt.widgets.Composite) + */ + public Control createControl(CompositeRuler parentRuler, Composite parentControl) { + Assert.isLegal(parentControl !is null); + Assert.isLegal(parentRuler !is null); + Assert.isLegal(fParentRuler is null); // only call when not yet initialized! + + fParentRuler= parentRuler; + + fTextViewer= getParentRuler().getTextViewer(); + fTextViewer.addViewportListener(fInternalListener); + fTextViewer.addTextListener(fInternalListener); + + fStyledText= fTextViewer.getTextWidget(); + + fCanvas= new Canvas(parentControl, getCanvasStyle()); + + fCanvas.setBackground(getDefaultBackground()); + fCanvas.setFont(getFont()); + + fCanvas.addPaintListener(new class() PaintListener { + public void paintControl(PaintEvent event) { + this.outer.paintControl(event); + } + }); + + fCanvas.addMouseListener(fMouseHandler); + fCanvas.addMouseMoveListener(fMouseHandler); + + return fCanvas; + } + + /** + * Returns the DWT style bits used when creating the ruler canvas. + *

                    + * The default implementation returns DWT.NO_BACKGROUND.

                    + *

                    + * Clients may reimplement this method to create a canvas with their + * desired style bits.

                    + * + * @return the DWT style bits, or DWT.NONE if none + */ + protected int getCanvasStyle() { + return DWT.NO_BACKGROUND; + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerColumn#getControl() + */ + public final Control getControl() { + return fCanvas; + } + + /** + * The new width in pixels. The DEFAULT_WIDTH constant + * specifies the default width. + * + * @param width the new width + */ + protected final void setWidth(int width) { + Assert.isLegal(width >= 0); + if (fWidth !is width) { + fWidth= width; + CompositeRuler composite= getParentRuler(); + if (composite !is null) + composite.relayout(); + } + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerColumn#getWidth() + */ + public final int getWidth() { + return fWidth; + } + + /** + * Returns the parent ruler, null before + * {@link #createControl(CompositeRuler, Composite)} has been called. + * + * @return the parent ruler or null + */ + protected final CompositeRuler getParentRuler() { + return fParentRuler; + } + + /** + * {@inheritDoc} + * + * @param font the font or null to use the default font + */ + public final void setFont(Font font) { + if (fFont !is font) { + fFont= font; + redraw(); + } + } + + /** + * Returns the current font. If a font has not been explicitly set, the widget's font is + * returned. + * + * @return the font used to render text on the ruler. + */ + protected final Font getFont() { + if (fFont !is null) + return fFont; + if (fStyledText !is null && !fStyledText.isDisposed()) + return fStyledText.getFont(); + return JFaceResources.getTextFont(); + } + + /** + * Sets the text inset (padding) used to draw text in {@link #paintLine(GC, int, int, int, int)}. + * + * @param textInset the new text inset + */ + protected final void setTextInset(int textInset) { + if (textInset !is fTextInset) { + fTextInset= textInset; + redraw(); + } + } + + /** + * Returns the text inset for text drawn by {@link #paintLine(GC, int, int, int, int)}. The + * DEFAULT_TEXT_INSET constant specifies the default inset in pixels. + * + * @return the text inset for text + */ + protected final int getTextInset() { + return fTextInset; + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerColumn#setModel(dwtx.jface.text.source.IAnnotationModel) + */ + public void setModel(IAnnotationModel model) { + if (fModel !is model) { + fModel= model; + redraw(); + } + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getModel() + */ + public final IAnnotationModel getModel() { + return fModel; + } + + /** + * Sets the default background color for this column. The default background is used as default + * implementation of {@link #computeBackground(int)} and also to paint the area of the ruler + * that does not correspond to any lines (when the viewport is not entirely filled with lines). + * + * @param background the default background color, null to use the text widget's + * background + */ + protected final void setDefaultBackground(Color background) { + if (fBackground !is background) { + fBackground= background; + if (fCanvas !is null && !fCanvas.isDisposed()) + fCanvas.setBackground(getDefaultBackground()); + redraw(); + } + } + + /** + * Returns the background color. May return null if the system is shutting down. + * + * @return the background color + */ + protected final Color getDefaultBackground() { + if (fBackground !is null) + return fBackground; + if (fStyledText !is null && !fStyledText.isDisposed()) + return fStyledText.getBackground(); + Display display; + if (fCanvas !is null && !fCanvas.isDisposed()) + display= fCanvas.getDisplay(); + else + display= Display.getCurrent(); + if (display !is null) + return display.getSystemColor(DWT.COLOR_LIST_BACKGROUND); + return null; + } + + /** + * Sets the annotation hover. + * + * @param hover the annotation hover, null for no hover + */ + protected final void setHover(IAnnotationHover hover) { + if (fHover !is hover) + fHover= hover; + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getHover() + */ + public IAnnotationHover getHover() { + return fHover; + } + + /** + * Disposes this ruler column. + *

                    + * Subclasses may extend this method.

                    + *

                    + * Clients who created this column are responsible to call this method + * once the column is no longer used.

                    + */ + public void dispose() { + if (fTextViewer !is null) { + fTextViewer.removeViewportListener(fInternalListener); + fTextViewer.removeTextListener(fInternalListener); + fTextViewer= null; + } + + if (fStyledText !is null) + fStyledText= null; + + if (fCanvas !is null) { + fCanvas.dispose(); + fCanvas= null; + } + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerColumn#redraw() + */ + public final void redraw() { + if (fCanvas !is null && !fCanvas.isDisposed()) + fCanvas.redraw(); + } + + /** + * Marks the region covered by lines as needing to be redrawn. + * + * @param lines the lines to be redrawn in document coordinates + */ + protected final void redraw(ILineRange lines) { + if (fCanvas is null || fCanvas.isDisposed()) + return; + int firstModelLine= lines.getStartLine(); + int lastModelLine= firstModelLine + lines.getNumberOfLines(); + int firstWidgetLine= JFaceTextUtil.modelLineToWidgetLine(fTextViewer, firstModelLine); + int lastWidgetLine= JFaceTextUtil.modelLineToWidgetLine(fTextViewer, lastModelLine); + + int from= Math.max(0, fStyledText.getLinePixel(firstWidgetLine)); + // getLinePixel will return the last pixel of the last line if line is lineCount + int to= Math.min(fCanvas.getSize().y, fStyledText.getLinePixel(lastWidgetLine + 1)); + fCanvas.redraw(0, from, fWidth, to - from, false); + } + + /** + * Paints the ruler column. + * + * @param event the paint event + */ + private void paintControl(PaintEvent event) { + if (fTextViewer is null) + return; + fWasShowingEntireContents= JFaceTextUtil.isShowingEntireContents(fStyledText); + fLastTopPixel= fStyledText.getTopPixel(); + + ILineRange lines= computeDirtyWidgetLines(event); + GC gc= event.gc; + paint(gc, lines); + + if ((fCanvas.getStyle() & DWT.NO_BACKGROUND) !is 0) { + // fill empty area below any lines + int firstEmpty= Math.max(event.y, fStyledText.getLinePixel(fStyledText.getLineCount())); + int lastEmpty= event.y + event.height; + if (lastEmpty > firstEmpty) { + gc.setBackground(getDefaultBackground()); + gc.fillRectangle(0, firstEmpty, getWidth(), lastEmpty - firstEmpty); + } + } + } + + /** + * Computes the widget lines that need repainting given the clipping region of a paint event. + * + * @param event the paint event + * @return the lines in widget coordinates that need repainting + */ + private ILineRange computeDirtyWidgetLines(PaintEvent event) { + int firstLine= fStyledText.getLineIndex(event.y); + int lastLine= fStyledText.getLineIndex(event.y + event.height - 1); + return new LineRange(firstLine, lastLine - firstLine + 1); + } + + /** + * Paints the ruler. Note that lines reference widget line indices, and that + * lines may not cover the entire viewport, but only the lines that need to be + * painted. The lines may not be entirely visible. + *

                    + * Subclasses may replace or extend. The default implementation calls + * {@link #paintLine(GC, int, int, int, int)} for every visible line. + *

                    + * + * @param gc the graphics context to paint on + * @param lines the lines to paint in widget coordinates + */ + protected void paint(GC gc, ILineRange lines) { + final int firstLine= lines.getStartLine(); + final int lastLine= firstLine + lines.getNumberOfLines(); + for (int line= firstLine; line < lastLine; line++) { + int modelLine= JFaceTextUtil.widgetLine2ModelLine(fTextViewer, line); + if (modelLine is -1) + continue; + int linePixel= fStyledText.getLinePixel(line); + int lineHeight= fStyledText.getLineHeight(fStyledText.getOffsetAtLine(line)); + paintLine(gc, modelLine, line, linePixel, lineHeight); + } + } + + /** + * Paints the ruler representation of a single line. + *

                    + * Subclasses may replace or extend. The default implementation draws the text obtained by + * {@link #computeText(int)} in the {@link #computeForeground(int) foreground color} and fills + * the entire width using the {@link #computeBackground(int) background color}. The text is + * drawn {@link #getTextInset()} pixels to the right of the left border. + *

                    + * + * @param gc the graphics context to paint on + * @param modelLine the model line (based on document coordinates) + * @param widgetLine the line in the text widget corresponding to modelLine + * @param linePixel the first y-pixel of the widget line + * @param lineHeight the line height in pixels + */ + protected void paintLine(GC gc, int modelLine, int widgetLine, int linePixel, int lineHeight) { + gc.setBackground(computeBackground(modelLine)); + gc.fillRectangle(0, linePixel, getWidth(), lineHeight); + String text= computeText(modelLine); + if (text !is null) { + gc.setForeground(computeForeground(modelLine)); + gc.drawString(text, getTextInset(), linePixel, true); + } + } + + /** + * Returns the text to be drawn for a certain line by {@link #paintLine(GC, int, int, int, int)}, + * null for no text. The default implementation returns null. + *

                    + * Subclasses may replace or extend. + *

                    + * + * @param line the document line number + * @return the text to be drawn for the given line, null for no text + */ + protected String computeText(int line) { + return null; + } + + /** + * Returns the background color drawn for a certain line by + * {@link #paintLine(GC, int, int, int, int)}. The default implementation returns + * {@link #getDefaultBackground()}. + *

                    + * Subclasses may replace or extend. + *

                    + * + * @param line the document line number + * @return the background color for drawn for the given line + */ + protected Color computeBackground(int line) { + return getDefaultBackground(); + } + + /** + * Returns the foreground color drawn for a certain line by + * {@link #paintLine(GC, int, int, int, int)}. The default implementation returns a + * {@link DWT#COLOR_DARK_GRAY} color. + *

                    + * Subclasses may replace or extend. + *

                    + * + * @param line the document line number + * @return the foreground color for drawn for the given line + */ + protected Color computeForeground(int line) { + return fStyledText.getDisplay().getSystemColor(DWT.COLOR_DARK_GRAY); + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfo#getLineOfLastMouseButtonActivity() + */ + public final int getLineOfLastMouseButtonActivity() { + return getParentRuler().getLineOfLastMouseButtonActivity(); + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfo#toDocumentLineNumber(int) + */ + public final int toDocumentLineNumber(int y_coordinate) { + return getParentRuler().toDocumentLineNumber(y_coordinate); + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#addVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener) + */ + public void addVerticalRulerListener(IVerticalRulerListener listener) { + throw new UnsupportedOperationException(); + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#removeVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener) + */ + public void removeVerticalRulerListener(IVerticalRulerListener listener) { + throw new UnsupportedOperationException(); + } + + /** + * Scrolls the canvas vertically (adapted from + * {@linkplain StyledText StyledText.scrollVertical()}). + * + * @param pixels the number of pixels to scroll (negative to scroll upwards) + * @return true if the widget was scrolled, false if the widget + * was not scrolled + */ + private bool scrollVertical(int pixels) { + if (pixels is 0 || fCanvas is null || fCanvas.isDisposed()) + return false; + + final int width= getWidth(); + final int clientAreaHeight= fStyledText.getClientArea().height; + final int topMargin= 0; + final int leftMargin= 0; + final int bottomMargin= 0; + + if (pixels > 0) { + // downwards scrolling - content moves upwards + int sourceY= topMargin + pixels; + int scrollHeight= clientAreaHeight - sourceY - bottomMargin; + if (scrollHeight > 0) + // scroll recycled area + fCanvas.scroll(leftMargin, topMargin, leftMargin, sourceY, width, scrollHeight, true); + if (sourceY > scrollHeight) { + // redraw in-between area + int redrawY= Math.max(0, topMargin + scrollHeight); + int redrawHeight= Math.min(clientAreaHeight, pixels - scrollHeight); + fCanvas.redraw(leftMargin, redrawY, width, redrawHeight, true); + } + } else { + // upwards scrolling - content moves downwards + int destinationY= topMargin - pixels; + int scrollHeight= clientAreaHeight - destinationY - bottomMargin; + if (scrollHeight > 0) + // scroll recycled area + fCanvas.scroll(leftMargin, destinationY, leftMargin, topMargin, width, scrollHeight, true); + if (destinationY > scrollHeight) { + // redraw in-between area + int redrawY= Math.max(0, topMargin + scrollHeight); + int redrawHeight= Math.min(clientAreaHeight, -pixels - scrollHeight); + fCanvas.redraw(leftMargin, redrawY, width, redrawHeight, true); + } + } + return true; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/Annotation.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/Annotation.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,225 @@ +/******************************************************************************* + * 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.text.source.Annotation; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Annotation managed by an + * {@link dwtx.jface.text.source.IAnnotationModel}. + *

                    + * Annotations are typed, can have an associated text and can be marked as persistent and + * deleted. Annotations which are not explicitly initialized with an annotation + * type are of type "dwtx.text.annotation.unknown". + */ +public class Annotation { + + /** + * Constant for unknown annotation types.

                    + * Value: "dwtx.text.annotation.unknown" + * @since 3.0 + */ + public const static String TYPE_UNKNOWN= "dwtx.text.annotation.unknown"; //$NON-NLS-1$ + + + /** + * The type of this annotation. + * @since 3.0 + */ + private String fType; + /** + * Indicates whether this annotation is persistent or not. + * @since 3.0 + */ + private bool fIsPersistent= false; + /** + * Indicates whether this annotation is marked as deleted or not. + * @since 3.0 + */ + private bool fMarkedAsDeleted= false; + /** + * The text associated with this annotation. + * @since 3.0 + */ + private String fText; + + + /** + * Creates a new annotation that is not persistent and type less. + */ + protected this() { + this(null, false, null); + } + + /** + * Creates a new annotation with the given properties. + * + * @param type the unique name of this annotation type + * @param isPersistent true if this annotation is + * persistent, false otherwise + * @param text the text associated with this annotation + * @since 3.0 + */ + public this(String type, bool isPersistent, String text) { + fType= type; + fIsPersistent= isPersistent; + fText= text; + } + + /** + * Creates a new annotation with the given persistence state. + * + * @param isPersistent true if persistent, false otherwise + * @since 3.0 + */ + public this(bool isPersistent) { + this(null, isPersistent, null); + } + + /** + * Returns whether this annotation is persistent. + * + * @return true if this annotation is persistent, false + * otherwise + * @since 3.0 + */ + public bool isPersistent() { + return fIsPersistent; + } + + /** + * Sets the type of this annotation. + * + * @param type the annotation type + * @since 3.0 + */ + public void setType(String type) { + fType= type; + } + + /** + * Returns the type of the annotation. + * + * @return the type of the annotation + * @since 3.0 + */ + public String getType() { + return fType is null ? TYPE_UNKNOWN : fType; + } + + /** + * Marks this annotation deleted according to the value of the + * deleted parameter. + * + * @param deleted true if annotation should be marked as deleted + * @since 3.0 + */ + public void markDeleted(bool deleted) { + fMarkedAsDeleted= deleted; + } + + /** + * Returns whether this annotation is marked as deleted. + * + * @return true if annotation is marked as deleted, false + * otherwise + * @since 3.0 + */ + public bool isMarkedDeleted() { + return fMarkedAsDeleted; + } + + /** + * Sets the text associated with this annotation. + * + * @param text the text associated with this annotation + * @since 3.0 + */ + public void setText(String text) { + fText= text; + } + + /** + * Returns the text associated with this annotation. + * + * @return the text associated with this annotation or null + * @since 3.0 + */ + public String getText() { + return fText; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/AnnotationBarHoverManager.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/AnnotationBarHoverManager.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,858 @@ +/******************************************************************************* + * 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 + * 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.text.source.AnnotationBarHoverManager; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; + +import dwt.DWT; +import dwt.custom.StyledText; +import dwt.events.ControlEvent; +import dwt.events.ControlListener; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.events.KeyEvent; +import dwt.events.KeyListener; +import dwt.events.MouseEvent; +import dwt.events.MouseListener; +import dwt.events.MouseMoveListener; +import dwt.events.MouseTrackAdapter; +import dwt.events.ShellEvent; +import dwt.events.ShellListener; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Listener; +import dwtx.core.runtime.Assert; +import dwtx.jface.internal.text.InformationControlReplacer; +import dwtx.jface.internal.text.InternalAccessor; +import dwtx.jface.text.AbstractHoverInformationControlManager; +import dwtx.jface.text.AbstractInformationControlManager; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IInformationControl; +import dwtx.jface.text.IInformationControlCreator; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextViewerExtension5; +import dwtx.jface.text.JFaceTextUtil; +import dwtx.jface.text.Region; +import dwtx.jface.text.TextUtilities; +import dwtx.jface.text.ITextViewerExtension8; + + +/** + * This manager controls the layout, content, and visibility of an information + * control in reaction to mouse hover events issued by the vertical ruler of a + * source viewer. + * @since 2.0 + */ +public class AnnotationBarHoverManager : AbstractHoverInformationControlManager { + + /** + * The information control closer for the hover information. Closes the information control as soon as the mouse pointer leaves the subject area, a mouse button is pressed, the user presses a key, or the subject control is resized or moved. + * + * @since 3.0 + * @deprecated As of 3.4, no longer used as closer from super class is used + */ + protected class Closer : MouseTrackAdapter , IInformationControlCloser, MouseListener, MouseMoveListener, ControlListener, KeyListener, DisposeListener, ShellListener, Listener { + + /** The closer's subject control */ + private Control fSubjectControl; + /** The subject area */ + private Rectangle fSubjectArea; + /** Indicates whether this closer is active */ + private bool fIsActive= false; + /** The information control. */ + private IInformationControl fInformationControlToClose; + /** + * true if a wheel handler is installed. + * @since 3.2 + */ + private bool fHasWheelFilter= false; + /** + * The cached display. + * @since 3.2 + */ + private Display fDisplay; + + + /** + * Creates a new information control closer. + */ + public this() { + } + + /* + * @see IInformationControlCloser#setSubjectControl(Control) + */ + public void setSubjectControl(Control control) { + fSubjectControl= control; + } + + /* + * @see IInformationControlCloser#setHoverControl(IHoverControl) + */ + public void setInformationControl(IInformationControl control) { + fInformationControlToClose= control; + } + + /* + * @see IInformationControlCloser#start(Rectangle) + */ + public void start(Rectangle subjectArea) { + + if (fIsActive) return; + fIsActive= true; + + fSubjectArea= subjectArea; + + fInformationControlToClose.addDisposeListener(this); + if (fSubjectControl !is null && !fSubjectControl.isDisposed()) { + fSubjectControl.addMouseListener(this); + fSubjectControl.addMouseMoveListener(this); + fSubjectControl.addMouseTrackListener(this); + fSubjectControl.getShell().addShellListener(this); + fSubjectControl.addControlListener(this); + fSubjectControl.addKeyListener(this); + + fDisplay= fSubjectControl.getDisplay(); + if (!fDisplay.isDisposed() && fHideOnMouseWheel) { + fHasWheelFilter= true; + fDisplay.addFilter(DWT.MouseWheel, this); + } + } + } + + /* + * @see IInformationControlCloser#stop() + */ + public void stop() { + + if (!fIsActive) + return; + fIsActive= false; + + if (fSubjectControl !is null && !fSubjectControl.isDisposed()) { + fSubjectControl.removeMouseListener(this); + fSubjectControl.removeMouseMoveListener(this); + fSubjectControl.removeMouseTrackListener(this); + fSubjectControl.getShell().removeShellListener(this); + fSubjectControl.removeControlListener(this); + fSubjectControl.removeKeyListener(this); + } + + if (fDisplay !is null && !fDisplay.isDisposed() && fHasWheelFilter) + fDisplay.removeFilter(DWT.MouseWheel, this); + fHasWheelFilter= false; + + fDisplay= null; + + } + + /** + * Stops the information control and if delayRestart is set allows restart only after a certain delay. + * + * @param delayRestart true if restart should be delayed + * @deprecated As of 3.4, replaced by {@link #stop()}. Note that delayRestart was never honored. + */ + protected void stop(bool delayRestart) { + stop(); + } + + /* + * @see dwt.events.MouseMoveListener#mouseMove(dwt.events.MouseEvent) + */ + public void mouseMove(MouseEvent event) { + if (!fSubjectArea.contains(event.x, event.y)) + hideInformationControl(); + } + + /* + * @see dwt.events.MouseListener#mouseUp(dwt.events.MouseEvent) + */ + public void mouseUp(MouseEvent event) { + } + + /* + * @see MouseListener#mouseDown(MouseEvent) + */ + public void mouseDown(MouseEvent event) { + hideInformationControl(); + } + + /* + * @see MouseListener#mouseDoubleClick(MouseEvent) + */ + public void mouseDoubleClick(MouseEvent event) { + hideInformationControl(); + } + + /* + * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event) + * @since 3.2 + */ + public void handleEvent(Event event) { + if (event.type is DWT.MouseWheel) + hideInformationControl(); + } + + /* + * @see MouseTrackAdapter#mouseExit(MouseEvent) + */ + public void mouseExit(MouseEvent event) { + if (!fAllowMouseExit) + hideInformationControl(); + } + + /* + * @see ControlListener#controlResized(ControlEvent) + */ + public void controlResized(ControlEvent event) { + hideInformationControl(); + } + + /* + * @see ControlListener#controlMoved(ControlEvent) + */ + public void controlMoved(ControlEvent event) { + hideInformationControl(); + } + + /* + * @see KeyListener#keyReleased(KeyEvent) + */ + public void keyReleased(KeyEvent event) { + } + + /* + * @see KeyListener#keyPressed(KeyEvent) + */ + public void keyPressed(KeyEvent event) { + hideInformationControl(); + } + + /* + * @see dwt.events.ShellListener#shellActivated(dwt.events.ShellEvent) + * @since 3.1 + */ + public void shellActivated(ShellEvent e) { + } + + /* + * @see dwt.events.ShellListener#shellClosed(dwt.events.ShellEvent) + * @since 3.1 + */ + public void shellClosed(ShellEvent e) { + } + + /* + * @see dwt.events.ShellListener#shellDeactivated(dwt.events.ShellEvent) + * @since 3.1 + */ + public void shellDeactivated(ShellEvent e) { + hideInformationControl(); + } + + /* + * @see dwt.events.ShellListener#shellDeiconified(dwt.events.ShellEvent) + * @since 3.1 + */ + public void shellDeiconified(ShellEvent e) { + } + + /* + * @see dwt.events.ShellListener#shellIconified(dwt.events.ShellEvent) + * @since 3.1 + */ + public void shellIconified(ShellEvent e) { + } + + /* + * @see dwt.events.DisposeListener#widgetDisposed(dwt.events.DisposeEvent) + */ + public void widgetDisposed(DisposeEvent e) { + hideInformationControl(); + } + } + + /** The source viewer the manager is connected to */ + private ISourceViewer fSourceViewer; + /** The vertical ruler the manager is registered with */ + private IVerticalRulerInfo fVerticalRulerInfo; + /** The annotation hover the manager uses to retrieve the information to display. Can be null. */ + private IAnnotationHover fAnnotationHover; + /** + * Indicates whether the mouse cursor is allowed to leave the subject area without closing the hover. + * @since 3.0 + */ + protected bool fAllowMouseExit= false; + /** + * Whether we should hide the over on mouse wheel action. + * + * @since 3.2 + */ + private bool fHideOnMouseWheel= true; + + /** + * The current annotation hover. + * @since 3.2 + */ + private IAnnotationHover fCurrentHover; + + /** + * Creates an annotation hover manager with the given parameters. In addition, + * the hovers anchor is RIGHT and the margin is 5 points to the right. + * + * @param sourceViewer the source viewer this manager connects to + * @param ruler the vertical ruler this manager connects to + * @param annotationHover the annotation hover providing the information to be displayed + * @param creator the information control creator + * @deprecated As of 2.1, replaced by {@link AnnotationBarHoverManager#AnnotationBarHoverManager(IVerticalRulerInfo, ISourceViewer, IAnnotationHover, IInformationControlCreator)} + */ + public this(ISourceViewer sourceViewer, IVerticalRuler ruler, IAnnotationHover annotationHover, IInformationControlCreator creator) { + this(ruler, sourceViewer, annotationHover, creator); + } + + /** + * Creates an annotation hover manager with the given parameters. In addition, + * the hovers anchor is RIGHT and the margin is 5 points to the right. + * + * @param rulerInfo the vertical ruler this manager connects to + * @param sourceViewer the source viewer this manager connects to + * @param annotationHover the annotation hover providing the information to be displayed or null if none + * @param creator the information control creator + * @since 2.1 + */ + public this(IVerticalRulerInfo rulerInfo, ISourceViewer sourceViewer, IAnnotationHover annotationHover, IInformationControlCreator creator) { + super(creator); + + Assert.isNotNull(cast(Object)sourceViewer); + + fSourceViewer= sourceViewer; + fVerticalRulerInfo= rulerInfo; + fAnnotationHover= annotationHover; + + setAnchor(ANCHOR_RIGHT); + setMargins(5, 0); + // use closer from super class + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#computeInformation() + */ + protected void computeInformation() { + fAllowMouseExit= false; + MouseEvent event= getHoverEvent(); + IAnnotationHover hover= getHover(event); + if (hover is null) { + setInformation(cast(Object)null, null); + return; + } + + int line= getHoverLine(event); + + if ( cast(IAnnotationHoverExtension)hover ) { + IAnnotationHoverExtension extension= cast(IAnnotationHoverExtension) hover; + ILineRange range= extension.getHoverLineRange(fSourceViewer, line); + setCustomInformationControlCreator(extension.getHoverControlCreator()); + range= adaptLineRange(range, line); + if (range !is null) + setInformation(extension.getHoverInfo(fSourceViewer, range, computeNumberOfVisibleLines()), computeArea(range)); + else + setInformation(cast(Object)null, null); + + } else { + setCustomInformationControlCreator(null); + setInformation(hover.getHoverInfo(fSourceViewer, line), computeArea(line)); + } + + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#showInformationControl(dwt.graphics.Rectangle) + * @since 3.2 + */ + protected void showInformationControl(Rectangle subjectArea) { + super.showInformationControl(subjectArea); + fCurrentHover= getHover(getHoverEvent()); + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#hideInformationControl() + * @since 3.2 + */ + protected void hideInformationControl() { + fCurrentHover= null; + super.hideInformationControl(); + } + + /** + * Adapts a given line range so that the result is a line range that does + * not overlap with any collapsed region and fits into the view port of the + * attached viewer. + * + * @param lineRange the original line range + * @param line the anchor line + * @return the adapted line range + * @since 3.0 + */ + private ILineRange adaptLineRange(ILineRange lineRange, int line) { + if (lineRange !is null) { + lineRange= adaptLineRangeToFolding(lineRange, line); + if (lineRange !is null) + return adaptLineRangeToViewport(lineRange); + } + return null; + } + + /** + * Adapts a given line range so that the result is a line range that does + * not overlap with any collapsed region of the attached viewer. + * + * @param lineRange the original line range + * @param line the anchor line + * @return the adapted line range + * @since 3.0 + */ + private ILineRange adaptLineRangeToFolding(ILineRange lineRange, int line) { + + if ( cast(ITextViewerExtension5)fSourceViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) fSourceViewer; + + try { + IRegion region= convertToRegion(lineRange); + IRegion[] coverage= extension.getCoveredModelRanges(region); + if (coverage !is null && coverage.length > 0) { + IRegion container= findRegionContainingLine(coverage, line); + if (container !is null) + return convertToLineRange(container); + } + + } catch (BadLocationException x) { + } + + return null; + } + + return lineRange; + } + + /** + * Adapts a given line range so that the result is a line range that fits + * into the view port of the attached viewer. + * + * @param lineRange the original line range + * @return the adapted line range + * @since 3.0 + */ + private ILineRange adaptLineRangeToViewport(ILineRange lineRange) { + + try { + StyledText text= fSourceViewer.getTextWidget(); + + int topLine= text.getTopIndex(); + int rangeTopLine= getWidgetLineNumber(lineRange.getStartLine()); + int topDelta= Math.max(topLine - rangeTopLine, 0); + + Rectangle size= text.getClientArea(); + Rectangle trim= text.computeTrim(0, 0, 0, 0); + int height= size.height - trim.height; + + int lines= JFaceTextUtil.getLineIndex(text, height) - text.getTopIndex(); + + int bottomLine= topLine + lines; + + int rangeBottomLine= getWidgetLineNumber(lineRange.getStartLine() + lineRange.getNumberOfLines() - 1); + int bottomDelta= Math.max(rangeBottomLine - bottomLine, 0); + + return new LineRange(lineRange.getStartLine() + topDelta, lineRange.getNumberOfLines() - bottomDelta - topDelta); + + } catch (BadLocationException ex) { + } + + return null; + } + + /** + * Converts a line range into a character range. + * + * @param lineRange the line range + * @return the corresponding character range + * @throws BadLocationException in case the given line range is invalid + */ + private IRegion convertToRegion(ILineRange lineRange) { + IDocument document= fSourceViewer.getDocument(); + int startOffset= document.getLineOffset(lineRange.getStartLine()); + int endLine= lineRange.getStartLine() + Math.max(0, lineRange.getNumberOfLines() - 1); + IRegion lineInfo= document.getLineInformation(endLine); + int endOffset= lineInfo.getOffset() + lineInfo.getLength(); + return new Region(startOffset, endOffset - startOffset); + } + + /** + * Returns the region out of the given set that contains the given line or + * null. + * + * @param regions the set of regions + * @param line the line + * @return the region of the set that contains the line + * @throws BadLocationException in case line is invalid + */ + private IRegion findRegionContainingLine(IRegion[] regions, int line) { + IDocument document= fSourceViewer.getDocument(); + IRegion lineInfo= document.getLineInformation(line); + for (int i= 0; i < regions.length; i++) { + if (TextUtilities.overlaps(regions[i], lineInfo)) + return regions[i]; + } + return null; + } + + /** + * Converts a given character region into a line range. + * + * @param region the character region + * @return the corresponding line range + * @throws BadLocationException in case the given region in invalid + */ + private ILineRange convertToLineRange(IRegion region) { + IDocument document= fSourceViewer.getDocument(); + int startLine= document.getLineOfOffset(region.getOffset()); + int endLine= document.getLineOfOffset(region.getOffset() + region.getLength()); + return new LineRange(startLine, endLine - startLine + 1); + } + + /** + * Returns the visible area of the vertical ruler covered by the given line + * range. + * + * @param lineRange the line range + * @return the visible area + */ + private Rectangle computeArea(ILineRange lineRange) { + try { + StyledText text= fSourceViewer.getTextWidget(); + final int startLine= getWidgetLineNumber(lineRange.getStartLine()); + int y= JFaceTextUtil.computeLineHeight(text, 0, startLine, startLine) - text.getTopPixel(); + int height= JFaceTextUtil.computeLineHeight(text, startLine, startLine + lineRange.getNumberOfLines(), lineRange.getNumberOfLines()); + Point size= fVerticalRulerInfo.getControl().getSize(); + return new Rectangle(0, y, size.x, height); + } catch (BadLocationException x) { + } + return null; + } + + /** + * Returns the number of the currently visible lines. + * + * @return the number of the currently visible lines + * @deprecated to avoid deprecation warning + */ + private int computeNumberOfVisibleLines() { + // Hack to reduce amount of copied code. + return LineNumberRulerColumn.getVisibleLinesInViewport(fSourceViewer.getTextWidget()); + } + + /** + * Determines the hover to be used to display information based on the source of the + * mouse hover event. If fVerticalRulerInfo is not a composite ruler, the + * standard hover is returned. + * + * @param event the source of the mouse hover event + * @return the hover depending on source, or fAnnotationHover if none can be found. + * @since 3.0 + */ + private IAnnotationHover getHover(MouseEvent event) { + if (event is null || event.getSource() is null) + return fAnnotationHover; + + if ( cast(CompositeRuler)fVerticalRulerInfo ) { + CompositeRuler comp= cast(CompositeRuler) fVerticalRulerInfo; + for (Iterator it= comp.getDecoratorIterator(); it.hasNext();) { + Object o= it.next(); + if ( cast(IVerticalRulerInfoExtension)o && cast(IVerticalRulerInfo)o ) { + if ((cast(IVerticalRulerInfo) o).getControl() is event.getSource()) { + IAnnotationHover hover= (cast(IVerticalRulerInfoExtension) o).getHover(); + if (hover !is null) + return hover; + } + } + } + } + return fAnnotationHover; + } + + /** + * Returns the line of interest deduced from the mouse hover event. + * + * @param event a mouse hover event that triggered hovering + * @return the document model line number on which the hover event occurred or -1 if there is no event + * @since 3.0 + */ + private int getHoverLine(MouseEvent event) { + return event is null ? -1 : fVerticalRulerInfo.toDocumentLineNumber(event.y); + } + + /** + * Returns for the widget line number for the given document line number. + * + * @param line the absolute line number + * @return the line number relative to the viewer's visible region + * @throws BadLocationException if line is not valid in the viewer's document + */ + private int getWidgetLineNumber(int line) { + if ( cast(ITextViewerExtension5)fSourceViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) fSourceViewer; + return extension.modelLine2WidgetLine(line); + } + + IRegion region= fSourceViewer.getVisibleRegion(); + int firstLine= fSourceViewer.getDocument().getLineOfOffset(region.getOffset()); + return line - firstLine; + } + + /** + * Determines graphical area covered by the given line. + * + * @param line the number of the line in the viewer whose graphical extend in the vertical ruler must be computed + * @return the graphical extend of the given line + */ + private Rectangle computeArea(int line) { + try { + StyledText text= fSourceViewer.getTextWidget(); + int widgetLine= getWidgetLineNumber(line); + int y= JFaceTextUtil.computeLineHeight(text, 0, widgetLine, widgetLine) - text.getTopPixel(); + Point size= fVerticalRulerInfo.getControl().getSize(); + return new Rectangle(0, y, size.x, text.getLineHeight(text.getOffsetAtLine(widgetLine))); + } catch (IllegalArgumentException ex) { + } catch (BadLocationException ex) { + } + return null; + } + + /** + * Returns the annotation hover for this hover manager. + * + * @return the annotation hover for this hover manager or null if none + * @since 2.1 + */ + protected IAnnotationHover getAnnotationHover() { + return fAnnotationHover; + } + + /** + * Returns the source viewer for this hover manager. + * + * @return the source viewer for this hover manager + * @since 2.1 + */ + protected ISourceViewer getSourceViewer() { + return fSourceViewer; + } + + /** + * Returns the vertical ruler info for this hover manager + * + * @return the vertical ruler info for this hover manager + * @since 2.1 + */ + protected IVerticalRulerInfo getVerticalRulerInfo() { + return fVerticalRulerInfo; + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#computeSizeConstraints(dwt.widgets.Control, dwt.graphics.Rectangle, dwtx.jface.text.IInformationControl) + * @since 3.0 + */ + protected Point computeSizeConstraints(Control subjectControl, Rectangle subjectArea, IInformationControl informationControl) { + + Point constraints= super.computeSizeConstraints(subjectControl, subjectArea, informationControl); + + // make as big as text area, if possible + StyledText styledText= fSourceViewer.getTextWidget(); + if (styledText !is null) { + Rectangle r= styledText.getClientArea(); + if (r !is null) { + constraints.x= r.width; + constraints.y= r.height; + } + } + + return constraints; + } + + /* + * @see dwtx.jface.text.AbstractInformationControlManager#computeLocation(dwt.graphics.Rectangle, dwt.graphics.Point, dwtx.jface.text.AbstractInformationControlManager.Anchor) + * @since 3.0 + */ + protected Point computeLocation(Rectangle subjectArea, Point controlSize, Anchor anchor) { + MouseEvent event= getHoverEvent(); + IAnnotationHover hover= getHover(event); + + bool allowMouseExit= false; + if ( cast(IAnnotationHoverExtension)hover ) { + IAnnotationHoverExtension extension= cast(IAnnotationHoverExtension) hover; + allowMouseExit= extension.canHandleMouseCursor(); + } + bool hideOnMouseWheel= true; + if ( cast(IAnnotationHoverExtension2)hover ) { + IAnnotationHoverExtension2 extension= cast(IAnnotationHoverExtension2) hover; + hideOnMouseWheel= !extension.canHandleMouseWheel(); + } + fHideOnMouseWheel= hideOnMouseWheel; + + if (allowMouseExit) { + fAllowMouseExit= true; + + Control subjectControl= getSubjectControl(); + // return a location that just overlaps the annotation on the bar + if (anchor is AbstractInformationControlManager.ANCHOR_RIGHT) + return subjectControl.toDisplay(subjectArea.x - 4, subjectArea.y - 2); + else if (anchor is AbstractInformationControlManager.ANCHOR_LEFT) + return subjectControl.toDisplay(subjectArea.x + subjectArea.width - controlSize.x + 4, subjectArea.y - 2); + } + + fAllowMouseExit= false; + return super.computeLocation(subjectArea, controlSize, anchor); + } + + /** + * Returns the currently shown annotation hover or null if none + * hover is shown. + * + * @return the currently shown annotation hover or null + * @since 3.2 + */ + public IAnnotationHover getCurrentAnnotationHover() { + return fCurrentHover; + } + + /** + * Returns an adapter that gives access to internal methods. + *

                    + * Note: This method is not intended to be referenced or overridden by clients. + *

                    + * + * @return the replaceable information control accessor + * @since 3.4 + * @noreference This method is not intended to be referenced by clients. + * @nooverride This method is not intended to be re-implemented or extended by clients. + */ + public InternalAccessor getInternalAccessor() { + return new class() InternalAccessor { + public IInformationControl getCurrentInformationControl() { + return this.outer.superGetInternalAccessor().getCurrentInformationControl(); + } + + public void setInformationControlReplacer(InformationControlReplacer replacer) { + this.outer.superGetInternalAccessor().setInformationControlReplacer(replacer); + } + + public InformationControlReplacer getInformationControlReplacer() { + return this.outer.superGetInternalAccessor().getInformationControlReplacer(); + } + + public bool canReplace(IInformationControl control) { + return this.outer.superGetInternalAccessor().canReplace(control); + } + + public bool isReplaceInProgress() { + return this.outer.superGetInternalAccessor().isReplaceInProgress(); + } + + public void replaceInformationControl(bool takeFocus) { + this.outer.superGetInternalAccessor().replaceInformationControl(takeFocus); + } + + public void cropToClosestMonitor(Rectangle bounds) { + this.outer.superGetInternalAccessor().cropToClosestMonitor(bounds); + } + + public void setHoverEnrichMode(ITextViewerExtension8_EnrichMode mode) { + this.outer.superGetInternalAccessor().setHoverEnrichMode(mode); + } + + public bool getAllowMouseExit() { + return fAllowMouseExit; + } + }; + } + private InternalAccessor superGetInternalAccessor() { + return super.getInternalAccessor(); + } +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/AnnotationColumn.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/AnnotationColumn.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.AnnotationColumn; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + +import dwt.dwthelper.utils; + + +/** + * @deprecated use {@link dwtx.jface.text.source.AnnotationRulerColumn} instead. + * @since 2.0 + */ +public final class AnnotationColumn : AnnotationRulerColumn { + + /** + * Creates a new AnnotationColumn of the given width. + * + * @param width the width of this column + * @deprecated + */ + public this(int width) { + super(width); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/AnnotationMap.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/AnnotationMap.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,291 @@ +/******************************************************************************* + * 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 + * 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.text.source.AnnotationMap; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.dwtxhelper.Collection; + + + + + + + +/** + * Internal implementation of {@link dwtx.jface.text.source.IAnnotationMap}. + * + * @since 3.0 + */ +class AnnotationMap : IAnnotationMap { + + /** + * The lock object used to synchronize the operations explicitly defined by + * IAnnotationMap + */ + private Object fLockObject; + /** + * The internal lock object used if fLockObject is null. + * @since 3.2 + */ + private const Object fInternalLockObject; + + /** The map holding the annotations */ + private Map fInternalMap; + + /** + * Creates a new annotation map with the given capacity. + * + * @param capacity the capacity + */ + public this(int capacity) { + fInternalLockObject= new Object(); + fInternalMap= new HashMap(capacity); + } + + /* + * @see dwtx.jface.text.source.ISynchronizable#setLockObject(java.lang.Object) + */ + public synchronized void setLockObject(Object lockObject) { + fLockObject= lockObject; + } + + /* + * @see dwtx.jface.text.source.ISynchronizable#getLockObject() + */ + public synchronized Object getLockObject() { + if (fLockObject is null) + return fInternalLockObject; + return fLockObject; + } + + /* + * @see dwtx.jface.text.source.IAnnotationMap#valuesIterator() + */ + public Iterator valuesIterator() { + synchronized (getLockObject()) { + return (new ArrayList(fInternalMap.values())).iterator(); + } + } + + /* + * @see dwtx.jface.text.source.IAnnotationMap#keySetIterator() + */ + public Iterator keySetIterator() { + synchronized (getLockObject()) { + return (new ArrayList(fInternalMap.keySet())).iterator(); + } + } + + /* + * @see java.util.Map#containsKey(java.lang.Object) + */ + public bool containsKey(Object annotation) { + synchronized (getLockObject()) { + return fInternalMap.containsKey(annotation); + } + } + + /* + * @see java.util.Map#put(java.lang.Object, java.lang.Object) + */ + public Object put(Object annotation, Object position) { + synchronized (getLockObject()) { + return fInternalMap.put(annotation, position); + } + } + + /* + * @see java.util.Map#get(java.lang.Object) + */ + public Object get(Object annotation) { + synchronized (getLockObject()) { + return fInternalMap.get(annotation); + } + } + + /* + * @see java.util.Map#clear() + */ + public void clear() { + synchronized (getLockObject()) { + fInternalMap.clear(); + } + } + + /* + * @see java.util.Map#remove(java.lang.Object) + */ + public Object remove(Object annotation) { + synchronized (getLockObject()) { + return fInternalMap.remove(annotation); + } + } + + /* + * @see java.util.Map#size() + */ + public int size() { + synchronized (getLockObject()) { + return fInternalMap.size(); + } + } + + /* + * @see java.util.Map#isEmpty() + */ + public bool isEmpty() { + synchronized (getLockObject()) { + return fInternalMap.isEmpty(); + } + } + + /* + * @see java.util.Map#containsValue(java.lang.Object) + */ + public bool containsValue(Object value) { + synchronized(getLockObject()) { + return fInternalMap.containsValue(value); + } + } + + /* + * @see java.util.Map#putAll(java.util.Map) + */ + public void putAll(Map map) { + synchronized (getLockObject()) { + fInternalMap.putAll(map); + } + } + + /* + * @see IAnnotationMap#entrySet() + */ + public Set entrySet() { + synchronized (getLockObject()) { + return fInternalMap.entrySet(); + } + } + + /* + * @see IAnnotationMap#keySet() + */ + public Set keySet() { + synchronized (getLockObject()) { + return fInternalMap.keySet(); + } + } + + /* + * @see IAnnotationMap#values() + */ + public Collection values() { + synchronized (getLockObject()) { + return fInternalMap.values(); + } + } + + /// DWT extension of Collection interfaces + + public bool containsKey(String key) { + return containsKey(stringcast(key)); + } + public Object get(String key) { + return get(stringcast(key)); + } + public Object put(String key, String value) { + return put(stringcast(key), stringcast(value)); + } + public Object put(Object key, String value) { + return put(key, stringcast(value)); + } + public Object put(String key, Object value) { + return put(stringcast(key), value); + } + public Object remove(String key) { + return remove(stringcast(key)); + } + public int opApply (int delegate(ref Object value) dg){ + implMissing(__FILE__,__LINE__); + return 0; + } + public int opApply (int delegate(ref Object key, ref Object value) dg){ + implMissing(__FILE__,__LINE__); + return 0; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/AnnotationModel.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/AnnotationModel.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,1059 @@ +/******************************************************************************* + * 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 + * 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.text.source.AnnotationModel; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; +import tango.core.Exception; +import tango.core.Thread; + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.AbstractDocument; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.BadPositionCategoryException; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentListener; +import dwtx.jface.text.ISynchronizable; +import dwtx.jface.text.Position; + + +/** + * Standard implementation of {@link IAnnotationModel} and its extension + * interfaces. This class can directly be used by clients. Subclasses may adapt + * this annotation model to other existing annotation mechanisms. This class + * also implements {@link dwtx.jface.text.ISynchronizable}. All + * modifications of the model's internal annotation map are synchronized using + * the model's lock object. + */ +public class AnnotationModel : IAnnotationModel, IAnnotationModelExtension, IAnnotationModelExtension2, ISynchronizable { + + + /** + * Iterator that returns the annotations for a given region. + * + * @since 3.4 + * @see AnnotationModel.RegionIterator#RegionIterator(Iterator, IAnnotationModel, int, int, bool, bool) + */ + private static final class RegionIterator : Iterator { + + private const Iterator fParentIterator; + private const bool fCanEndAfter; + private const bool fCanStartBefore; + private const IAnnotationModel fModel; + private Object fNext; + private Position fRegion; + + /** + * Iterator that returns all annotations from the parent iterator which + * have a position in the given model inside the given region. + *

                    + * See {@link IAnnotationModelExtension2} for a definition of inside. + *

                    + * + * @param parentIterator iterator containing all annotations + * @param model the model to use to retrieve positions from for each + * annotation + * @param offset start position of the region + * @param length length of the region + * @param canStartBefore include annotations starting before region + * @param canEndAfter include annotations ending after region + * @see IAnnotationModelExtension2 + */ + public this(Iterator parentIterator, IAnnotationModel model, int offset, int length, bool canStartBefore, bool canEndAfter) { + fParentIterator= parentIterator; + fModel= model; + fRegion= new Position(offset, length); + fCanEndAfter= canEndAfter; + fCanStartBefore= canStartBefore; + fNext= findNext(); + } + + /* + * @see java.util.Iterator#hasNext() + */ + public bool hasNext() { + return fNext !is null; + } + + /* + * @see java.util.Iterator#next() + */ + public Object next() { + if (!hasNext()) + throw new NoSuchElementException(null); + + Object result= fNext; + fNext= findNext(); + return result; + } + + /* + * @see java.util.Iterator#remove() + */ + public void remove() { + throw new UnsupportedOperationException(); + } + + private Object findNext() { + while (fParentIterator.hasNext()) { + Annotation next= cast(Annotation) fParentIterator.next(); + Position position= fModel.getPosition(next); + if (position !is null) { + int offset= position.getOffset(); + if (isWithinRegion(offset, position.getLength())) + return next; + } + } + return null; + } + + private bool isWithinRegion(int start, int length) { + if (fCanStartBefore && fCanEndAfter) + return fRegion.overlapsWith(start, length); + else if (fCanStartBefore) + return fRegion.includes(start + length - 1); + else if (fCanEndAfter) + return fRegion.includes(start); + else + return fRegion.includes(start) && fRegion.includes(start + length - 1); + } + } + + /** + * An iterator iteration over a Positions and mapping positions to + * annotations using a provided map if the provided map contains the element. + * + * @since 3.4 + */ + private static final class AnnotationsInterator : Iterator { + + private Object fNext; + private const Position[] fPositions; + private int fIndex; + private const Map fMap; + + /** + * @param positions positions to iterate over + * @param map a map to map positions to annotations + */ + public this(Position[] positions, Map map) { + fPositions= positions; + fIndex= 0; + fMap= map; + fNext= findNext(); + } + + /* (non-Javadoc) + * @see java.util.Iterator#hasNext() + */ + public bool hasNext() { + return fNext !is null; + } + + /* (non-Javadoc) + * @see java.util.Iterator#next() + */ + public Object next() { + Object result= fNext; + fNext= findNext(); + return result; + } + + /* (non-Javadoc) + * @see java.util.Iterator#remove() + */ + public void remove() { + throw new UnsupportedOperationException(); + } + + private Object findNext() { + while (fIndex < fPositions.length) { + Position position= fPositions[fIndex]; + fIndex++; + if (fMap.containsKey(position)) + return fMap.get(position); + } + + return null; + } + } + + /** + * A single iterator builds its behavior based on a sequence of iterators. + * + * @since 3.1 + */ + private static class MetaIterator : Iterator { + + /** The iterator over a list of iterators. */ + private Iterator fSuperIterator; + /** The current iterator. */ + private Iterator fCurrent; + /** The current element. */ + private Object fCurrentElement; + + + public this(Iterator iterator) { + fSuperIterator= iterator; + fCurrent= cast(Iterator) fSuperIterator.next(); // there is at least one. + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + public bool hasNext() { + if (fCurrentElement !is null) + return true; + + if (fCurrent.hasNext()) { + fCurrentElement= fCurrent.next(); + return true; + } else if (fSuperIterator.hasNext()) { + fCurrent= cast(Iterator) fSuperIterator.next(); + return hasNext(); + } else + return false; + } + + public Object next() { + if (!hasNext()) + throw new NoSuchElementException(null); + + Object element= fCurrentElement; + fCurrentElement= null; + return element; + } + } + + /** + * Internal annotation model listener for forwarding annotation model changes from the attached models to the + * registered listeners of the outer most annotation model. + * + * @since 3.0 + */ + private class InternalModelListener : IAnnotationModelListener, IAnnotationModelListenerExtension { + + /* + * @see dwtx.jface.text.source.IAnnotationModelListener#modelChanged(dwtx.jface.text.source.IAnnotationModel) + */ + public void modelChanged(IAnnotationModel model) { + this.outer.fireModelChanged(new AnnotationModelEvent(model, true)); + } + + /* + * @see dwtx.jface.text.source.IAnnotationModelListenerExtension#modelChanged(dwtx.jface.text.source.AnnotationModelEvent) + */ + public void modelChanged(AnnotationModelEvent event) { + this.outer.fireModelChanged(event); + } + } + + /** + * The list of managed annotations + * @deprecated since 3.0 use getAnnotationMap instead + */ + protected Map fAnnotations; + /** + * The map which maps {@link Position} to {@link Annotation}. + * @since 3.4 + **/ + private IdentityHashMap fPositions; + /** The list of annotation model listeners */ + protected ArrayList fAnnotationModelListeners; + /** The document connected with this model */ + protected IDocument fDocument; + /** The number of open connections to the same document */ + private int fOpenConnections= 0; + /** The document listener for tracking whether document positions might have been changed. */ + private IDocumentListener fDocumentListener; + /** The flag indicating whether the document positions might have been changed. */ + private bool fDocumentChanged= true; + /** + * The model's attachment. + * @since 3.0 + */ + private Map fAttachments; + /** + * The annotation model listener on attached sub-models. + * @since 3.0 + */ + private IAnnotationModelListener fModelListener; + /** + * The current annotation model event. + * @since 3.0 + */ + private AnnotationModelEvent fModelEvent; + /** + * The modification stamp. + * @since 3.0 + */ + private Object fModificationStamp; + /** + * Creates a new annotation model. The annotation is empty, i.e. does not + * manage any annotations and is not connected to any document. + */ + public this() { + fAttachments= new HashMap(); + fModelListener= new InternalModelListener(); + fModificationStamp= new Object(); + fAnnotations= new AnnotationMap(10); + fPositions= new IdentityHashMap(10); + fAnnotationModelListeners= new ArrayList(2); + + fDocumentListener= new class() IDocumentListener { + + public void documentAboutToBeChanged(DocumentEvent event) { + } + + public void documentChanged(DocumentEvent event) { + fDocumentChanged= true; + } + }; + } + + /** + * Returns the annotation map internally used by this annotation model. + * + * @return the annotation map internally used by this annotation model + * @since 3.0 + */ + protected IAnnotationMap getAnnotationMap() { + return cast(IAnnotationMap) fAnnotations; + } + + /* + * @see dwtx.jface.text.ISynchronizable#getLockObject() + * @since 3.0 + */ + public Object getLockObject() { + return getAnnotationMap().getLockObject(); + } + + /* + * @see dwtx.jface.text.ISynchronizable#setLockObject(java.lang.Object) + * @since 3.0 + */ + public void setLockObject(Object lockObject) { + getAnnotationMap().setLockObject(lockObject); + } + + /** + * Returns the current annotation model event. This is the event that will be sent out + * when calling fireModelChanged. + * + * @return the current annotation model event + * @since 3.0 + */ + protected final AnnotationModelEvent getAnnotationModelEvent() { + synchronized (getLockObject()) { + if (fModelEvent is null) { + fModelEvent= createAnnotationModelEvent(); + fModelEvent.markWorldChange(false); + fModificationStamp= fModelEvent; + } + return fModelEvent; + } + } + + /* + * @see dwtx.jface.text.source.IAnnotationModel#addAnnotation(dwtx.jface.text.source.Annotation, dwtx.jface.text.Position) + */ + public void addAnnotation(Annotation annotation, Position position) { + try { + addAnnotation(annotation, position, true); + } catch (BadLocationException e) { + // ignore invalid position + } + } + + /* + * @see dwtx.jface.text.source.IAnnotationModelExtension#replaceAnnotations(dwtx.jface.text.source.Annotation[], java.util.Map) + * @since 3.0 + */ + public void replaceAnnotations(Annotation[] annotationsToRemove, Map annotationsToAdd) { + try { + replaceAnnotations(annotationsToRemove, annotationsToAdd, true); + } catch (BadLocationException x) { + } + } + + /** + * Replaces the given annotations in this model and if advised fires a + * model change event. + * + * @param annotationsToRemove the annotations to be removed + * @param annotationsToAdd the annotations to be added + * @param fireModelChanged true if a model change event + * should be fired, false otherwise + * @throws BadLocationException in case an annotation should be added at an + * invalid position + * @since 3.0 + */ + protected void replaceAnnotations(Annotation[] annotationsToRemove, Map annotationsToAdd, bool fireModelChanged_) { + + if (annotationsToRemove !is null) { + for (int i= 0, length= annotationsToRemove.length; i < length; i++) + removeAnnotation(annotationsToRemove[i], false); + } + + if (annotationsToAdd !is null) { + Iterator iter= annotationsToAdd.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry mapEntry= cast(Map.Entry) iter.next(); + Annotation annotation= cast(Annotation) mapEntry.getKey(); + Position position= cast(Position) mapEntry.getValue(); + addAnnotation(annotation, position, false); + } + } + + if (fireModelChanged_) + fireModelChanged(); + } + + /** + * Adds the given annotation to this model. Associates the + * annotation with the given position. If requested, all annotation + * model listeners are informed about this model change. If the annotation + * is already managed by this model nothing happens. + * + * @param annotation the annotation to add + * @param position the associate position + * @param fireModelChanged indicates whether to notify all model listeners + * @throws BadLocationException if the position is not a valid document position + */ + protected void addAnnotation(Annotation annotation, Position position, bool fireModelChanged_) { + if (!fAnnotations.containsKey(annotation)) { + + addPosition(fDocument, position); + fAnnotations.put(annotation, position); + fPositions.put(position, annotation); + synchronized (getLockObject()) { + getAnnotationModelEvent().annotationAdded(annotation); + } + + if (fireModelChanged_) + fireModelChanged(); + } + } + + /* + * @see dwtx.jface.text.source.IAnnotationModel#addAnnotationModelListener(dwtx.jface.text.source.IAnnotationModelListener) + */ + public void addAnnotationModelListener(IAnnotationModelListener listener) { + if (!fAnnotationModelListeners.contains(cast(Object)listener)) { + fAnnotationModelListeners.add(cast(Object)listener); + if ( cast(IAnnotationModelListenerExtension)listener ) { + IAnnotationModelListenerExtension extension= cast(IAnnotationModelListenerExtension) listener; + AnnotationModelEvent event= createAnnotationModelEvent(); + event.markSealed(); + extension.modelChanged(event); + } else + listener.modelChanged(this); + } + } + + /** + * Adds the given position to the default position category of the + * given document. + * + * @param document the document to which to add the position + * @param position the position to add + * @throws BadLocationException if the position is not a valid document position + */ + protected void addPosition(IDocument document, Position position) { + if (document !is null) + document.addPosition(position); + } + + /** + * Removes the given position from the default position category of the + * given document. + * + * @param document the document to which to add the position + * @param position the position to add + * + * @since 3.0 + */ + protected void removePosition(IDocument document, Position position) { + if (document !is null) + document.removePosition(position); + } + + /* + * @see dwtx.jface.text.source.IAnnotationModel#connect(dwtx.jface.text.IDocument) + */ + public void connect(IDocument document) { + Assert.isTrue(fDocument is null || fDocument is document); + + if (fDocument is null) { + fDocument= document; + Iterator e= getAnnotationMap().valuesIterator(); + while (e.hasNext()) + try { + addPosition(fDocument, cast(Position) e.next()); + } catch (BadLocationException x) { + // ignore invalid position + } + } + + ++ fOpenConnections; + if (fOpenConnections is 1) { + fDocument.addDocumentListener(fDocumentListener); + connected(); + } + + for (Iterator it= fAttachments.keySet().iterator(); it.hasNext();) { + IAnnotationModel model= cast(IAnnotationModel) fAttachments.get(it.next()); + model.connect(document); + } + } + + /** + * Hook method. Is called as soon as this model becomes connected to a document. + * Subclasses may re-implement. + */ + protected void connected() { + } + + /** + * Hook method. Is called as soon as this model becomes disconnected from its document. + * Subclasses may re-implement. + */ + protected void disconnected() { + } + + /* + * @see dwtx.jface.text.source.IAnnotationModel#disconnect(dwtx.jface.text.IDocument) + */ + public void disconnect(IDocument document) { + + Assert.isTrue(fDocument is document); + + for (Iterator it= fAttachments.keySet().iterator(); it.hasNext();) { + IAnnotationModel model= cast(IAnnotationModel) fAttachments.get(it.next()); + model.disconnect(document); + } + + -- fOpenConnections; + if (fOpenConnections is 0) { + + disconnected(); + fDocument.removeDocumentListener(fDocumentListener); + + if (fDocument !is null) { + Iterator e= getAnnotationMap().valuesIterator(); + while (e.hasNext()) { + Position p= cast(Position) e.next(); + removePosition(fDocument, p); + } + fDocument= null; + } + } + } + + /** + * Informs all annotation model listeners that this model has been changed. + */ + protected void fireModelChanged() { + AnnotationModelEvent modelEvent= null; + + synchronized(getLockObject()) { + if (fModelEvent !is null) { + modelEvent= fModelEvent; + fModelEvent= null; + } + } + + if (modelEvent !is null) + fireModelChanged(modelEvent); + } + + /** + * Creates and returns a new annotation model event. Subclasses may override. + * + * @return a new and empty annotation model event + * @since 3.0 + */ + protected AnnotationModelEvent createAnnotationModelEvent() { + return new AnnotationModelEvent(this); + } + + /** + * Informs all annotation model listeners that this model has been changed + * as described in the annotation model event. The event is sent out + * to all listeners implementing IAnnotationModelListenerExtension. + * All other listeners are notified by just calling modelChanged(IAnnotationModel). + * + * @param event the event to be sent out to the listeners + * @since 2.0 + */ + protected void fireModelChanged(AnnotationModelEvent event) { + + event.markSealed(); + + if (event.isEmpty()) + return; + + ArrayList v= new ArrayList(fAnnotationModelListeners); + Iterator e= v.iterator(); + while (e.hasNext()) { + IAnnotationModelListener l= cast(IAnnotationModelListener) e.next(); + if ( cast(IAnnotationModelListenerExtension)l ) + (cast(IAnnotationModelListenerExtension) l).modelChanged(event); + else if (l !is null) + l.modelChanged(this); + } + } + + /** + * Removes the given annotations from this model. If requested all + * annotation model listeners will be informed about this change. + * modelInitiated indicates whether the deletion has + * been initiated by this model or by one of its clients. + * + * @param annotations the annotations to be removed + * @param fireModelChanged indicates whether to notify all model listeners + * @param modelInitiated indicates whether this changes has been initiated by this model + */ + protected void removeAnnotations(List annotations, bool fireModelChanged_, bool modelInitiated) { + if (annotations.size() > 0) { + Iterator e= annotations.iterator(); + while (e.hasNext()) + removeAnnotation(cast(Annotation) e.next(), false); + + if (fireModelChanged_) + fireModelChanged(); + } + } + + /** + * Removes all annotations from the model whose associated positions have been + * deleted. If requested inform all model listeners about the change. + * + * @param fireModelChanged indicates whether to notify all model listeners + */ + protected void cleanup(bool fireModelChanged_) { + cleanup(fireModelChanged_, true); + } + + /** + * Removes all annotations from the model whose associated positions have been + * deleted. If requested inform all model listeners about the change. If requested + * a new thread is created for the notification of the model listeners. + * + * @param fireModelChanged indicates whether to notify all model listeners + * @param forkNotification true iff notification should be done in a new thread + * @since 3.0 + */ + private void cleanup(bool fireModelChanged_, bool forkNotification) { + if (fDocumentChanged) { + fDocumentChanged= false; + + ArrayList deleted= new ArrayList(); + Iterator e= getAnnotationMap().keySetIterator(); + while (e.hasNext()) { + Annotation a= cast(Annotation) e.next(); + Position p= cast(Position) fAnnotations.get(a); + if (p is null || p.isDeleted()) + deleted.add(a); + } + + if (fireModelChanged_ && forkNotification) { + removeAnnotations(deleted, false, false); + synchronized (getLockObject()) { + if (fModelEvent !is null) + (new Thread ( &fireModelChanged )).start(); + } + } else + removeAnnotations(deleted, fireModelChanged_, false); + } + } + + /* + * @see dwtx.jface.text.source.IAnnotationModel#getAnnotationIterator() + */ + public Iterator getAnnotationIterator() { + return getAnnotationIterator(true, true); + } + + /** + * {@inheritDoc} + * + * @since 3.4 + */ + public Iterator getAnnotationIterator(int offset, int length, bool canStartBefore, bool canEndAfter) { + Iterator regionIterator= getRegionAnnotationIterator(offset, length, canStartBefore, canEndAfter); + + if (fAttachments.isEmpty()) + return regionIterator; + + List iterators= new ArrayList(fAttachments.size() + 1); + iterators.add(cast(Object)regionIterator); + Iterator it= fAttachments.keySet().iterator(); + while (it.hasNext()) { + IAnnotationModel attachment= cast(IAnnotationModel) fAttachments.get(it.next()); + if ( cast(IAnnotationModelExtension2)attachment ) + iterators.add(cast(Object)(cast(IAnnotationModelExtension2) attachment).getAnnotationIterator(offset, length, canStartBefore, canEndAfter)); + else + iterators.add(new RegionIterator(attachment.getAnnotationIterator(), attachment, offset, length, canStartBefore, canEndAfter)); + } + + return new MetaIterator(iterators.iterator()); + } + + /** + * Returns an iterator as specified in {@link IAnnotationModelExtension2#getAnnotationIterator(int, int, bool, bool)} + * + * @param offset region start + * @param length region length + * @param canStartBefore position can start before region + * @param canEndAfter position can end after region + * @return an iterator to iterate over annotations in region + * @see IAnnotationModelExtension2#getAnnotationIterator(int, int, bool, bool) + * @since 3.4 + */ + private Iterator getRegionAnnotationIterator(int offset, int length, bool canStartBefore, bool canEndAfter) { + if (!( cast(AbstractDocument)fDocument )) + return new RegionIterator(getAnnotationIterator(true), this, offset, length, canStartBefore, canEndAfter); + + AbstractDocument document= cast(AbstractDocument) fDocument; + cleanup(true); + + try { + Position[] positions= document.getPositions(IDocument.DEFAULT_CATEGORY, offset, length, canStartBefore, canEndAfter); + return new AnnotationsInterator(positions, fPositions); + } catch (BadPositionCategoryException e) { + //can not happen + Assert.isTrue(false); + return null; + } + } + + /** + * Returns all annotations managed by this model. cleanup + * indicates whether all annotations whose associated positions are + * deleted should previously be removed from the model. recurse indicates + * whether annotations of attached sub-models should also be returned. + * + * @param cleanup indicates whether annotations with deleted associated positions are removed + * @param recurse whether to return annotations managed by sub-models. + * @return all annotations managed by this model + * @since 3.0 + */ + private Iterator getAnnotationIterator(bool cleanup, bool recurse) { + Iterator iter= getAnnotationIterator(cleanup); + if (!recurse || fAttachments.isEmpty()) + return iter; + + List iterators= new ArrayList(fAttachments.size() + 1); + iterators.add(cast(Object)iter); + Iterator it= fAttachments.keySet().iterator(); + while (it.hasNext()) + iterators.add(cast(Object)(cast(IAnnotationModel) fAttachments.get(it.next())).getAnnotationIterator()); + + return new MetaIterator(iterators.iterator()); + } + + /** + * Returns all annotations managed by this model. cleanup + * indicates whether all annotations whose associated positions are + * deleted should previously be removed from the model. + * + * @param cleanup indicates whether annotations with deleted associated positions are removed + * @return all annotations managed by this model + */ + protected Iterator getAnnotationIterator(bool cleanup_) { + if (cleanup_) + cleanup(true); + + return getAnnotationMap().keySetIterator(); + } + + /* + * @see dwtx.jface.text.source.IAnnotationModel#getPosition(dwtx.jface.text.source.Annotation) + */ + public Position getPosition(Annotation annotation) { + Position position= cast(Position) fAnnotations.get(annotation); + if (position !is null) + return position; + + Iterator it= fAttachments.values().iterator(); + while (position is null && it.hasNext()) + position= (cast(IAnnotationModel) it.next()).getPosition(annotation); + return position; + } + + /* + * @see dwtx.jface.text.source.IAnnotationModelExtension#removeAllAnnotations() + * @since 3.0 + */ + public void removeAllAnnotations() { + removeAllAnnotations(true); + } + + /** + * Removes all annotations from the annotation model. If requested + * inform all model change listeners about this change. + * + * @param fireModelChanged indicates whether to notify all model listeners + */ + protected void removeAllAnnotations(bool fireModelChanged_) { + + if (fDocument !is null) { + Iterator e= getAnnotationMap().keySetIterator(); + while (e.hasNext()) { + Annotation a= cast(Annotation) e.next(); + Position p= cast(Position) fAnnotations.get(a); + removePosition(fDocument, p); +// p.delete_(); + synchronized (getLockObject()) { + getAnnotationModelEvent().annotationRemoved(a, p); + } + } + } + + fAnnotations.clear(); + fPositions.clear(); + + if (fireModelChanged_) + fireModelChanged(); + } + + /* + * @see dwtx.jface.text.source.IAnnotationModel#removeAnnotation(dwtx.jface.text.source.Annotation) + */ + public void removeAnnotation(Annotation annotation) { + removeAnnotation(annotation, true); + } + + /** + * Removes the given annotation from the annotation model. + * If requested inform all model change listeners about this change. + * + * @param annotation the annotation to be removed + * @param fireModelChanged indicates whether to notify all model listeners + */ + protected void removeAnnotation(Annotation annotation, bool fireModelChanged_) { + if (fAnnotations.containsKey(annotation)) { + + Position p= null; + p= cast(Position) fAnnotations.get(annotation); + if (fDocument !is null) { + removePosition(fDocument, p); +// p.delete_(); + } + + fAnnotations.remove(annotation); + fPositions.remove(p); + synchronized (getLockObject()) { + getAnnotationModelEvent().annotationRemoved(annotation, p); + } + + if (fireModelChanged_) + fireModelChanged(); + } + } + + /* + * @see dwtx.jface.text.source.IAnnotationModelExtension#modifyAnnotationPosition(dwtx.jface.text.source.Annotation, dwtx.jface.text.Position) + * @since 3.0 + */ + public void modifyAnnotationPosition(Annotation annotation, Position position) { + modifyAnnotationPosition(annotation, position, true); + } + + /** + * Modifies the associated position of the given annotation to the given + * position. If the annotation is not yet managed by this annotation model, + * the annotation is added. When the position is null, the + * annotation is removed from the model. + *

                    + * If requested, all annotation model change listeners will be informed + * about the change. + * + * @param annotation the annotation whose associated position should be + * modified + * @param position the position to whose values the associated position + * should be changed + * @param fireModelChanged indicates whether to notify all model listeners + * @since 3.0 + */ + protected void modifyAnnotationPosition(Annotation annotation, Position position, bool fireModelChanged_) { + if (position is null) { + removeAnnotation(annotation, fireModelChanged_); + } else { + Position p= cast(Position) fAnnotations.get(annotation); + if (p !is null) { + + if (position.getOffset() !is p.getOffset() || position.getLength() !is p.getLength()) { + fDocument.removePosition(p); + p.setOffset(position.getOffset()); + p.setLength(position.getLength()); + try { + fDocument.addPosition(p); + } catch (BadLocationException e) { + // ignore invalid position + } + } + synchronized (getLockObject()) { + getAnnotationModelEvent().annotationChanged(annotation); + } + if (fireModelChanged_) + fireModelChanged(); + + } else { + try { + addAnnotation(annotation, position, fireModelChanged_); + } catch (BadLocationException x) { + // ignore invalid position + } + } + } + } + + /** + * Modifies the given annotation if the annotation is managed by this + * annotation model. + *

                    + * If requested, all annotation model change listeners will be informed + * about the change. + * + * @param annotation the annotation to be modified + * @param fireModelChanged indicates whether to notify all model listeners + * @since 3.0 + */ + protected void modifyAnnotation(Annotation annotation, bool fireModelChanged_) { + if (fAnnotations.containsKey(annotation)) { + synchronized (getLockObject()) { + getAnnotationModelEvent().annotationChanged(annotation); + } + if (fireModelChanged_) + fireModelChanged(); + } + } + + /* + * @see IAnnotationModel#removeAnnotationModelListener(IAnnotationModelListener) + */ + public void removeAnnotationModelListener(IAnnotationModelListener listener) { + fAnnotationModelListeners.remove(cast(Object)listener); + } + + /* + * @see dwtx.jface.text.source.IAnnotationModelExtension#attach(java.lang.Object, java.lang.Object) + * @since 3.0 + */ + public void addAnnotationModel(Object key, IAnnotationModel attachment) { + Assert.isNotNull(cast(Object)attachment); + if (!fAttachments.containsValue(cast(Object)attachment)) { + fAttachments.put(key, cast(Object)attachment); + for (int i= 0; i < fOpenConnections; i++) + attachment.connect(fDocument); + attachment.addAnnotationModelListener(fModelListener); + } + } + + /* + * @see dwtx.jface.text.source.IAnnotationModelExtension#get(java.lang.Object) + * @since 3.0 + */ + public IAnnotationModel getAnnotationModel(Object key) { + return cast(IAnnotationModel) fAttachments.get(key); + } + + /* + * @see dwtx.jface.text.source.IAnnotationModelExtension#detach(java.lang.Object) + * @since 3.0 + */ + public IAnnotationModel removeAnnotationModel(Object key) { + IAnnotationModel ret= cast(IAnnotationModel) fAttachments.remove(key); + if (ret !is null) { + for (int i= 0; i < fOpenConnections; i++) + ret.disconnect(fDocument); + ret.removeAnnotationModelListener(fModelListener); + } + return ret; + } + + /* + * @see dwtx.jface.text.source.IAnnotationModelExtension#getModificationStamp() + * @since 3.0 + */ + public Object getModificationStamp() { + return fModificationStamp; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/AnnotationModelEvent.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/AnnotationModelEvent.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,330 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.AnnotationModelEvent; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.dwtxhelper.Collection; + + + + +import dwtx.jface.text.Position; + + +/** + * Specification of changes applied to annotation models. The event carries the + * changed annotation model as well as added, removed, and modified annotations. + *

                    + * An event can be sealed. Afterwards it can not be modified. Thus, the normal + * process is that an empty event is created, filled with the changed + * information, and before it is sent to the listeners, the event is sealed. + * + * @see dwtx.jface.text.source.IAnnotationModel + * @see dwtx.jface.text.source.IAnnotationModelListenerExtension + * @since 2.0 + */ +public class AnnotationModelEvent { + + /** The model this event refers to. */ + private IAnnotationModel fAnnotationModel; + /** + * The added annotations. + * @since 3.0 + */ + private Set fAddedAnnotations; + /** + * The removed annotations. + * @since 3.0 + */ + private Map fRemovedAnnotations; + /** + * The changed annotations. + * @since 3.0 + */ + private Set fChangedAnnotations; + /** + * Indicates that this event does not contain detailed information. + * @since 3.0 + */ + private bool fIsWorldChange; + /** + * The modification stamp. + * @since 3.0 + */ + private Object fModificationStamp; + + /** + * Creates a new annotation model event for the given model. + * + * @param model the model + */ + public this(IAnnotationModel model) { + this(model, true); + } + + /** + * Creates a new annotation model event for the given model. + * + * @param model the model + * @param isWorldChange true if world change + * @since 3.0 + */ + public this(IAnnotationModel model, bool isWorldChange) { + fAddedAnnotations= new HashSet(); + fRemovedAnnotations= new HashMap(); + fChangedAnnotations= new HashSet(); + + fAnnotationModel= model; + fIsWorldChange= isWorldChange; + } + + /** + * Returns the model this event refers to. + * + * @return the model this events belongs to + */ + public IAnnotationModel getAnnotationModel() { + return fAnnotationModel; + } + + /** + * Adds the given annotation to the set of annotations that are reported as + * being added from the model. If this event is considered a world change, + * it is no longer so after this method has successfully finished. + * + * @param annotation the added annotation + * @since 3.0 + */ + public void annotationAdded(Annotation annotation) { + fAddedAnnotations.add(annotation); + fIsWorldChange= false; + } + + /** + * Returns the added annotations. + * + * @return the added annotations + * @since 3.0 + */ + public Annotation[] getAddedAnnotations() { + int size= fAddedAnnotations.size(); + Annotation[] added= new Annotation[size]; + fAddedAnnotations.toArray(added); + return added; + } + + /** + * Adds the given annotation to the set of annotations that are reported as + * being removed from the model. If this event is considered a world + * change, it is no longer so after this method has successfully finished. + * + * @param annotation the removed annotation + * @since 3.0 + */ + public void annotationRemoved(Annotation annotation) { + annotationRemoved(annotation, null); + } + + /** + * Adds the given annotation to the set of annotations that are reported as + * being removed from the model. If this event is considered a world + * change, it is no longer so after this method has successfully finished. + * + * @param annotation the removed annotation + * @param position the position of the removed annotation + * @since 3.0 + */ + public void annotationRemoved(Annotation annotation, Position position) { + fRemovedAnnotations.put(annotation, position); + fIsWorldChange= false; + } + + /** + * Returns the removed annotations. + * + * @return the removed annotations + * @since 3.0 + */ + public Annotation[] getRemovedAnnotations() { + int size= fRemovedAnnotations.size(); + Annotation[] removed= new Annotation[size]; + fRemovedAnnotations.keySet().toArray(removed); + return removed; + } + + /** + * Returns the position of the removed annotation at that point in time + * when the annotation has been removed. + * + * @param annotation the removed annotation + * @return the position of the removed annotation or null + * @since 3.0 + */ + public Position getPositionOfRemovedAnnotation(Annotation annotation) { + return cast(Position) fRemovedAnnotations.get(annotation); + } + + /** + * Adds the given annotation to the set of annotations that are reported as + * being changed from the model. If this event is considered a world + * change, it is no longer so after this method has successfully finished. + * + * @param annotation the changed annotation + * @since 3.0 + */ + public void annotationChanged(Annotation annotation) { + fChangedAnnotations.add(annotation); + fIsWorldChange= false; + } + + /** + * Returns the changed annotations. + * + * @return the changed annotations + * @since 3.0 + */ + public Annotation[] getChangedAnnotations() { + int size= fChangedAnnotations.size(); + Annotation[] changed= new Annotation[size]; + fChangedAnnotations.toArray(changed); + return changed; + } + + /** + * Returns whether this annotation model event is empty or not. If this + * event represents a world change, this method returns false + * although the event does not carry any added, removed, or changed + * annotations. + * + * @return true if this event is empty + * @since 3.0 + */ + public bool isEmpty() { + return !fIsWorldChange && fAddedAnnotations.isEmpty() && fRemovedAnnotations.isEmpty() && fChangedAnnotations.isEmpty(); + } + + /** + * Returns whether this annotation model events contains detailed + * information about the modifications applied to the event annotation + * model or whether it represents a world change. I.e. everything in the + * model might have changed. + * + * @return true if world change, false otherwise + * @since 3.0 + */ + public bool isWorldChange() { + return fIsWorldChange; + } + + /** + * Marks this event as world change according to the given flag. + * + * @param isWorldChange true if this event is a world change, false otherwise + * @since 3.0 + */ + void markWorldChange(bool isWorldChange) { + fIsWorldChange= isWorldChange; + } + + /** + * Returns whether this annotation model event is still valid. + * + * @return true if this event is still valid, false otherwise + * @since 3.0 + */ + public bool isValid() { + if (fModificationStamp !is null && cast(IAnnotationModelExtension)fAnnotationModel ) { + IAnnotationModelExtension extension= cast(IAnnotationModelExtension) fAnnotationModel; + return fModificationStamp is extension.getModificationStamp(); + } + return true; + } + + /** + * Seals this event. Any direct modification to the annotation model after the event has been sealed + * invalidates this event. + * + * @since 3.0 + */ + public void markSealed() { + if ( cast(IAnnotationModelExtension)fAnnotationModel ) { + IAnnotationModelExtension extension= cast(IAnnotationModelExtension) fAnnotationModel; + fModificationStamp= extension.getModificationStamp(); + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/AnnotationPainter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/AnnotationPainter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,1794 @@ +/******************************************************************************* + * 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 + * 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.text.source.AnnotationPainter; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; +import tango.text.convert.Format; +import tango.io.Stdout; + +import dwt.DWT; +import dwt.DWTException; +import dwt.custom.StyleRange; +import dwt.custom.StyledText; +import dwt.events.PaintEvent; +import dwt.events.PaintListener; +import dwt.graphics.Color; +import dwt.graphics.GC; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.graphics.TextStyle; +import dwt.widgets.Display; +import dwtx.core.runtime.Assert; +import dwtx.core.runtime.Platform; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IPaintPositionManager; +import dwtx.jface.text.IPainter; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextInputListener; +import dwtx.jface.text.ITextPresentationListener; +import dwtx.jface.text.ITextViewerExtension2; +import dwtx.jface.text.ITextViewerExtension5; +import dwtx.jface.text.JFaceTextUtil; +import dwtx.jface.text.Position; +import dwtx.jface.text.Region; +import dwtx.jface.text.TextPresentation; + + + /** + * A drawing strategy draws the decoration for an annotation onto the text widget. + * + * @since 3.0 + */ + public interface IDrawingStrategy { + /** + * Draws a decoration for an annotation onto the specified GC at the given text range. There + * are two different invocation modes of the draw method: + *

                      + *
                    • drawing mode: the passed GC is the graphics context of a paint + * event occurring on the text widget. The strategy should draw the decoration onto the + * graphics context, such that the decoration appears at the given range in the text + * widget.
                    • + *
                    • clearing mode: the passed GC is null. In this case + * the strategy must invalidate enough of the text widget's client area to cover any + * decoration drawn in drawing mode. This can usually be accomplished by calling + * {@linkplain StyledText#redrawRange(int, int, bool) textWidget.redrawRange(offset, length, true)}.
                    • + *
                    + * + * @param annotation the annotation to be drawn + * @param gc the graphics context, null when in clearing mode + * @param textWidget the text widget to draw on + * @param offset the offset of the line + * @param length the length of the line + * @param color the color of the line + */ + void draw(Annotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color); + } + + alias IDrawingStrategy AnnotationPainter_IDrawingStrategy; + +/** + * Paints decorations for annotations provided by an annotation model and/or + * highlights them in the associated source viewer. + *

                    + * The annotation painter can be configured with drawing strategies. A drawing + * strategy defines the visual presentation of a particular type of annotation + * decoration.

                    + *

                    + * Clients usually instantiate and configure objects of this class.

                    + * + * @since 2.1 + */ +public class AnnotationPainter : IPainter, PaintListener, IAnnotationModelListener, IAnnotationModelListenerExtension, ITextPresentationListener { + + /** + * Squiggles drawing strategy. + * + * @since 3.0 + * @deprecated As of 3.4, replaced by {@link AnnotationPainter.UnderlineStrategy} + */ + public static class SquigglesStrategy : IDrawingStrategy { + + /* + * @see dwtx.jface.text.source.AnnotationPainter.IDrawingStrategy#draw(dwtx.jface.text.source.Annotation, dwt.graphics.GC, dwt.custom.StyledText, int, int, dwt.graphics.Color) + * @since 3.0 + */ + public void draw(Annotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) { + if (gc !is null) { + + if (length < 1) + return; + + Point left= textWidget.getLocationAtOffset(offset); + Point right= textWidget.getLocationAtOffset(offset + length); + Rectangle rect= textWidget.getTextBounds(offset, offset + length - 1); + left.x= rect.x; + right.x= rect.x + rect.width; + + int[] polyline= computePolyline(left, right, textWidget.getBaseline(offset), textWidget.getLineHeight(offset)); + + gc.setLineWidth(0); // NOTE: 0 means width is 1 but with optimized performance + gc.setLineStyle(DWT.LINE_SOLID); + gc.setForeground(color); + gc.drawPolyline(polyline); + + } else { + textWidget.redrawRange(offset, length, true); + } + } + + /** + * Computes an array of alternating x and y values which are the corners of the squiggly line of the + * given height between the given end points. + * + * @param left the left end point + * @param right the right end point + * @param baseline the font's baseline + * @param lineHeight the height of the line + * @return the array of alternating x and y values which are the corners of the squiggly line + */ + private int[] computePolyline(Point left, Point right, int baseline, int lineHeight) { + + final int WIDTH= 4; // must be even + final int HEIGHT= 2; // can be any number + + int peaks= (right.x - left.x) / WIDTH; + if (peaks is 0 && right.x - left.x > 2) + peaks= 1; + + int leftX= left.x; + + // compute (number of point) * 2 + int length_= ((2 * peaks) + 1) * 2; + if (length_ < 0) + return new int[0]; + + int[] coordinates= new int[length_]; + + // cache peeks' y-coordinates + int top= left.y + Math.min(baseline + 1, lineHeight - HEIGHT - 1); + int bottom= top + HEIGHT; + + // populate array with peek coordinates + for (int i= 0; i < peaks; i++) { + int index= 4 * i; + coordinates[index]= leftX + (WIDTH * i); + coordinates[index+1]= bottom; + coordinates[index+2]= coordinates[index] + WIDTH/2; + coordinates[index+3]= top; + } + + // the last down flank is missing + coordinates[length_-2]= Math.min(Math.max(0, right.x - 1), left.x + (WIDTH * peaks)); + coordinates[length_-1]= bottom; + + return coordinates; + } + } + + /** + * Drawing strategy that does nothing. + * + * @since 3.0 + */ + public static final class NullStrategy : IDrawingStrategy { + + /* + * @see dwtx.jface.text.source.AnnotationPainter.IDrawingStrategy#draw(dwtx.jface.text.source.Annotation, dwt.graphics.GC, dwt.custom.StyledText, int, int, dwt.graphics.Color) + * @since 3.0 + */ + public void draw(Annotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) { + // do nothing + } + } + + + /** + * A text style painting strategy draws the decoration for an annotation + * onto the text widget by applying a {@link TextStyle} on a given + * {@link StyleRange}. + * + * @since 3.4 + */ + public interface ITextStyleStrategy { + + /** + * Applies a text style on the given StyleRange. + * + * @param styleRange the style range on which to apply the text style + * @param annotationColor the color of the annotation + */ + void applyTextStyle(StyleRange styleRange, Color annotationColor); + } + + + /** + * @since 3.4 + */ + public static final class HighlightingStrategy : ITextStyleStrategy { + public void applyTextStyle(StyleRange styleRange, Color annotationColor) { + styleRange.background= annotationColor; + } + } + + + /** + * Underline text style strategy. + * + * @since 3.4 + */ + public static final class UnderlineStrategy : ITextStyleStrategy { + + int fUnderlineStyle; + + public this(int style) { + Assert.isLegal(style is DWT.UNDERLINE_SINGLE || style is DWT.UNDERLINE_DOUBLE || style is DWT.UNDERLINE_ERROR || style is DWT.UNDERLINE_SQUIGGLE); + fUnderlineStyle= style; + } + + public void applyTextStyle(StyleRange styleRange, Color annotationColor) { + styleRange.underline= true; + styleRange.underlineStyle= fUnderlineStyle; + styleRange.underlineColor= annotationColor; + } + } + + + /** + * Box text style strategy. + * + * @since 3.4 + */ + public static final class BoxStrategy : ITextStyleStrategy { + + int fBorderStyle; + + public this(int style) { + Assert.isLegal(style is DWT.BORDER_DASH || style is DWT.BORDER_DASH || style is DWT.BORDER_SOLID); + fBorderStyle= style; + } + + public void applyTextStyle(StyleRange styleRange, Color annotationColor) { + styleRange.borderStyle= fBorderStyle; + styleRange.borderColor= annotationColor; + } + } + + + /** + * Implementation of IRegion that can be reused + * by setting the offset and the length. + */ + private static class ReusableRegion : Position , IRegion { + public override int getOffset(){ + return super.getOffset(); + } + public override int getLength(){ + return super.getLength(); + } + } + + /** + * Tells whether this class is in debug mode. + * @since 3.0 + */ + private static bool DEBUG_; + private static bool DEBUG_init = false; + private static bool DEBUG(){ + if( !DEBUG_init ){ + DEBUG_init = true; + DEBUG_ = "true".equalsIgnoreCase(Platform.getDebugOption("dwtx.jface.text/debug/AnnotationPainter")); //$NON-NLS-1$//$NON-NLS-2$ + } + return DEBUG_; + } + + /** + * The squiggly painter strategy. + * @since 3.0 + */ + private static IDrawingStrategy SQUIGGLES_STRATEGY_; + private static IDrawingStrategy SQUIGGLES_STRATEGY(){ + if( SQUIGGLES_STRATEGY_ is null ){ + synchronized( AnnotationPainter.classinfo ){ + if( SQUIGGLES_STRATEGY_ is null ){ + SQUIGGLES_STRATEGY_ = new SquigglesStrategy(); + } + } + } + return SQUIGGLES_STRATEGY_; + } + + + /** + * This strategy is used to mark the null value in the chache + * maps. + * + * @since 3.4 + */ + private static IDrawingStrategy NULL_STRATEGY_; + private static IDrawingStrategy NULL_STRATEGY(){ + if( NULL_STRATEGY_ is null ){ + synchronized( AnnotationPainter.classinfo ){ + if( NULL_STRATEGY_ is null ){ + NULL_STRATEGY_= new NullStrategy(); + } + } + } + return NULL_STRATEGY_; + } + /** + * The squiggles painter id. + * @since 3.0 + */ + private static Object SQUIGGLES_; + private static Object SQUIGGLES(){ + if( SQUIGGLES_ is null ){ + synchronized( AnnotationPainter.classinfo ){ + if( SQUIGGLES_ is null ){ + SQUIGGLES_= new Object(); + } + } + } + return SQUIGGLES_; + } + /** + * The squiggly painter strategy. + * + * @since 3.4 + */ + private static ITextStyleStrategy HIGHLIGHTING_STRATEGY_; + private static ITextStyleStrategy HIGHLIGHTING_STRATEGY(){ + if( HIGHLIGHTING_STRATEGY_ is null ){ + synchronized( AnnotationPainter.classinfo ){ + if( HIGHLIGHTING_STRATEGY_ is null ){ + HIGHLIGHTING_STRATEGY_= new HighlightingStrategy(); + } + } + } + return HIGHLIGHTING_STRATEGY_; + } + + /** + * The highlighting text style strategy id. + * + * @since 3.4 + */ + private static Object HIGHLIGHTING_; + private static Object HIGHLIGHTING(){ + if( HIGHLIGHTING_ is null ){ + synchronized( AnnotationPainter.classinfo ){ + if( HIGHLIGHTING_ is null ){ + HIGHLIGHTING_= new Object(); + } + } + } + return HIGHLIGHTING_; + } + + /** + * The presentation information (decoration) for an annotation. Each such + * object represents one decoration drawn on the text area, such as squiggly lines + * and underlines. + */ + private static class Decoration { + /** The position of this decoration */ + private Position fPosition; + /** The color of this decoration */ + private Color fColor; + /** + * The annotation's layer + * @since 3.0 + */ + private int fLayer; + /** + * The painting strategy for this decoration. + * @since 3.0 + */ + private Object fPaintingStrategy; + } + + + /** Indicates whether this painter is active */ + private bool fIsActive= false; + /** Indicates whether this painter is managing decorations */ + private bool fIsPainting= false; + /** Indicates whether this painter is setting its annotation model */ + private /+volatile+/ bool fIsSettingModel= false; + /** The associated source viewer */ + private ISourceViewer fSourceViewer; + /** The cached widget of the source viewer */ + private StyledText fTextWidget; + /** The annotation model providing the annotations to be drawn */ + private IAnnotationModel fModel; + /** The annotation access */ + private IAnnotationAccess fAnnotationAccess; + /** + * The map with decorations + * @since 3.0 + */ + private Map fDecorationsMap; // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=50767 + /** + * The map with of highlighted decorations. + * @since 3.0 + */ + private Map fHighlightedDecorationsMap; + /** + * Mutex for highlighted decorations map. + * @since 3.0 + */ + private Object fDecorationMapLock; + /** + * Mutex for for decorations map. + * @since 3.0 + */ + private Object fHighlightedDecorationsMapLock; + /** + * Maps an annotation type to its registered color. + * + * @see #setAnnotationTypeColor(Object, Color) + */ + private Map fAnnotationType2Color; + + /** + * Cache that maps the annotation type to its color. + * @since 3.4 + */ + private Map fCachedAnnotationType2Color; + /** + * The range in which the current highlight annotations can be found. + * @since 3.0 + */ + private Position fCurrentHighlightAnnotationRange= null; + /** + * The range in which all added, removed and changed highlight + * annotations can be found since the last world change. + * @since 3.0 + */ + private Position fTotalHighlightAnnotationRange= null; + /** + * The range in which the currently drawn annotations can be found. + * @since 3.3 + */ + private Position fCurrentDrawRange= null; + /** + * The range in which all added, removed and changed drawn + * annotations can be found since the last world change. + * @since 3.3 + */ + private Position fTotalDrawRange= null; + /** + * The text input listener. + * @since 3.0 + */ + private ITextInputListener fTextInputListener; + /** + * Flag which tells that a new document input is currently being set. + * @since 3.0 + */ + private bool fInputDocumentAboutToBeChanged; + /** + * Maps annotation types to painting strategy identifiers. + * + * @see #addAnnotationType(Object, Object) + * @since 3.0 + */ + private Map fAnnotationType2PaintingStrategyId; + /** + * Maps annotation types to painting strategy identifiers. + * @since 3.4 + */ + private Map fCachedAnnotationType2PaintingStrategy; + + /** + * Maps painting strategy identifiers to painting strategies. + * + * @since 3.0 + */ + private Map fPaintingStrategyId2PaintingStrategy; + + /** + * Reuse this region for performance reasons. + * @since 3.3 + */ + private ReusableRegion fReusableRegion; + + /** + * Creates a new annotation painter for the given source viewer and with the + * given annotation access. The painter is not initialized, i.e. no + * annotation types are configured to be painted. + * + * @param sourceViewer the source viewer for this painter + * @param access the annotation access for this painter + */ + public this(ISourceViewer sourceViewer, IAnnotationAccess access) { + fDecorationsMap= new HashMap(); // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=50767 + fHighlightedDecorationsMap= new HashMap(); // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=50767 + fDecorationMapLock= new Object(); + fHighlightedDecorationsMapLock= new Object(); + fAnnotationType2Color= new HashMap(); + fCachedAnnotationType2Color= new HashMap(); + fReusableRegion= new ReusableRegion(); + fAnnotationType2PaintingStrategyId= new HashMap(); + fCachedAnnotationType2PaintingStrategy= new HashMap(); + fPaintingStrategyId2PaintingStrategy= new HashMap(); + + fSourceViewer= sourceViewer; + fAnnotationAccess= access; + fTextWidget= sourceViewer.getTextWidget(); + + // default drawing strategies: squiggles were the only decoration style before version 3.0 + fPaintingStrategyId2PaintingStrategy.put(SQUIGGLES, cast(Object)SQUIGGLES_STRATEGY); + fPaintingStrategyId2PaintingStrategy.put(HIGHLIGHTING, cast(Object)HIGHLIGHTING_STRATEGY); + } + + /** + * Returns whether this painter has to draw any squiggles. + * + * @return true if there are squiggles to be drawn, false otherwise + */ + private bool hasDecorations() { + synchronized (fDecorationMapLock) { + return !fDecorationsMap.isEmpty(); + } + } + + /** + * Enables painting. This painter registers a paint listener with the + * source viewer's widget. + */ + private void enablePainting() { + if (!fIsPainting && hasDecorations()) { + fIsPainting= true; + fTextWidget.addPaintListener(this); + handleDrawRequest(null); + } + } + + /** + * Disables painting, if is has previously been enabled. Removes + * any paint listeners registered with the source viewer's widget. + * + * @param redraw true if the widget should be redrawn after disabling + */ + private void disablePainting(bool redraw) { + if (fIsPainting) { + fIsPainting= false; + fTextWidget.removePaintListener(this); + if (redraw && hasDecorations()) + handleDrawRequest(null); + } + } + + /** + * Sets the annotation model for this painter. Registers this painter + * as listener of the give model, if the model is not null. + * + * @param model the annotation model + */ + private void setModel(IAnnotationModel model) { + if (fModel !is model) { + if (fModel !is null) + fModel.removeAnnotationModelListener(this); + fModel= model; + if (fModel !is null) { + try { + fIsSettingModel= true; + fModel.addAnnotationModelListener(this); + } finally { + fIsSettingModel= false; + } + } + } + } + + /** + * Updates the set of decorations based on the current state of + * the painter's annotation model. + * + * @param event the annotation model event + */ + private void catchupWithModel(AnnotationModelEvent event) { + + synchronized (fDecorationMapLock) { + if (fDecorationsMap is null) + return; + } + + IRegion clippingRegion= computeClippingRegion(null, true); + IDocument document= fSourceViewer.getDocument(); + + int highlightAnnotationRangeStart= Integer.MAX_VALUE; + int highlightAnnotationRangeEnd= -1; + + int drawRangeStart= Integer.MAX_VALUE; + int drawRangeEnd= -1; + + if (fModel !is null) { + + Map decorationsMap; + Map highlightedDecorationsMap; + + // Clone decoration maps + synchronized (fDecorationMapLock) { + decorationsMap= new HashMap(fDecorationsMap); + } + synchronized (fHighlightedDecorationsMapLock) { + highlightedDecorationsMap= new HashMap(fHighlightedDecorationsMap); + } + + bool isWorldChange= false; + + Iterator e; + if (event is null || event.isWorldChange()) { + isWorldChange= true; + + if (DEBUG && event is null) + System.out_.println("AP: INTERNAL CHANGE"); //$NON-NLS-1$ + + Iterator iter= decorationsMap.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry= cast(Map.Entry)iter.next(); + Annotation annotation= cast(Annotation)entry.getKey(); + Decoration decoration= cast(Decoration)entry.getValue(); + drawDecoration(decoration, null, annotation, clippingRegion, document); + } + + decorationsMap.clear(); + + highlightedDecorationsMap.clear(); + + e= fModel.getAnnotationIterator(); + + + } else { + + // Remove annotations + Annotation[] removedAnnotations= event.getRemovedAnnotations(); + for (int i=0, length= removedAnnotations.length; i < length; i++) { + Annotation annotation= removedAnnotations[i]; + Decoration decoration= cast(Decoration)highlightedDecorationsMap.remove(annotation); + if (decoration !is null) { + Position position= decoration.fPosition; + if (position !is null) { + highlightAnnotationRangeStart= Math.min(highlightAnnotationRangeStart, position.offset); + highlightAnnotationRangeEnd= Math.max(highlightAnnotationRangeEnd, position.offset + position.length); + } + } + decoration= cast(Decoration)decorationsMap.remove(annotation); + if (decoration !is null) { + drawDecoration(decoration, null, annotation, clippingRegion, document); + Position position= decoration.fPosition; + if (position !is null) { + drawRangeStart= Math.min(drawRangeStart, position.offset); + drawRangeEnd= Math.max(drawRangeEnd, position.offset + position.length); + } + } + + } + + // Update existing annotations + Annotation[] changedAnnotations= event.getChangedAnnotations(); + for (int i=0, length= changedAnnotations.length; i < length; i++) { + Annotation annotation= changedAnnotations[i]; + + bool isHighlighting= false; + + Decoration decoration= cast(Decoration)highlightedDecorationsMap.get(annotation); + + if (decoration !is null) { + isHighlighting= true; + // The call below updates the decoration - no need to create new decoration + decoration= getDecoration(annotation, decoration); + if (decoration is null) + highlightedDecorationsMap.remove(annotation); + } else { + decoration= getDecoration(annotation, decoration); + if (decoration !is null && cast(ITextStyleStrategy)decoration.fPaintingStrategy ) { + highlightedDecorationsMap.put(annotation, decoration); + isHighlighting= true; + } + } + + bool usesDrawingStrategy= !isHighlighting && decoration !is null; + + Position position= null; + if (decoration is null) + position= fModel.getPosition(annotation); + else + position= decoration.fPosition; + + if (position !is null && !position.isDeleted()) { + if (isHighlighting) { + highlightAnnotationRangeStart= Math.min(highlightAnnotationRangeStart, position.offset); + highlightAnnotationRangeEnd= Math.max(highlightAnnotationRangeEnd, position.offset + position.length); + } + if (usesDrawingStrategy) { + drawRangeStart= Math.min(drawRangeStart, position.offset); + drawRangeEnd= Math.max(drawRangeEnd, position.offset + position.length); + } + } else { + highlightedDecorationsMap.remove(annotation); + } + + if (usesDrawingStrategy) { + Decoration oldDecoration= cast(Decoration)decorationsMap.get(annotation); + if (oldDecoration !is null) { + drawDecoration(oldDecoration, null, annotation, clippingRegion, document); + + if (decoration !is null) + decorationsMap.put(annotation, decoration); + else if (oldDecoration !is null) + decorationsMap.remove(annotation); + } + } + } + + e= Arrays.asList(event.getAddedAnnotations()).iterator(); + } + + // Add new annotations + while (e.hasNext()) { + Annotation annotation= cast(Annotation) e.next(); + Decoration pp= getDecoration(annotation, null); + if (pp !is null) { + if (cast(IDrawingStrategy)pp.fPaintingStrategy ) { + decorationsMap.put(annotation, pp); + drawRangeStart= Math.min(drawRangeStart, pp.fPosition.offset); + drawRangeEnd= Math.max(drawRangeEnd, pp.fPosition.offset + pp.fPosition.length); + } else if (cast(ITextStyleStrategy)pp.fPaintingStrategy ) { + highlightedDecorationsMap.put(annotation, pp); + highlightAnnotationRangeStart= Math.min(highlightAnnotationRangeStart, pp.fPosition.offset); + highlightAnnotationRangeEnd= Math.max(highlightAnnotationRangeEnd, pp.fPosition.offset + pp.fPosition.length); + } + + } + } + + synchronized (fDecorationMapLock) { + fDecorationsMap= decorationsMap; + updateDrawRanges(drawRangeStart, drawRangeEnd, isWorldChange); + } + + synchronized (fHighlightedDecorationsMapLock) { + fHighlightedDecorationsMap= highlightedDecorationsMap; + updateHighlightRanges(highlightAnnotationRangeStart, highlightAnnotationRangeEnd, isWorldChange); + } + } else { + // annotation model is null -> clear all + synchronized (fDecorationMapLock) { + fDecorationsMap.clear(); + } + synchronized (fHighlightedDecorationsMapLock) { + fHighlightedDecorationsMap.clear(); + } + } + } + + /** + * Updates the remembered highlight ranges. + * + * @param highlightAnnotationRangeStart the start of the range + * @param highlightAnnotationRangeEnd the end of the range + * @param isWorldChange tells whether the range belongs to a annotation model event reporting a world change + * @since 3.0 + */ + private void updateHighlightRanges(int highlightAnnotationRangeStart, int highlightAnnotationRangeEnd, bool isWorldChange) { + if (highlightAnnotationRangeStart !is Integer.MAX_VALUE) { + + int maxRangeStart= highlightAnnotationRangeStart; + int maxRangeEnd= highlightAnnotationRangeEnd; + + if (fTotalHighlightAnnotationRange !is null) { + maxRangeStart= Math.min(maxRangeStart, fTotalHighlightAnnotationRange.offset); + maxRangeEnd= Math.max(maxRangeEnd, fTotalHighlightAnnotationRange.offset + fTotalHighlightAnnotationRange.length); + } + + if (fTotalHighlightAnnotationRange is null) + fTotalHighlightAnnotationRange= new Position(0); + if (fCurrentHighlightAnnotationRange is null) + fCurrentHighlightAnnotationRange= new Position(0); + + if (isWorldChange) { + fTotalHighlightAnnotationRange.offset= highlightAnnotationRangeStart; + fTotalHighlightAnnotationRange.length= highlightAnnotationRangeEnd - highlightAnnotationRangeStart; + fCurrentHighlightAnnotationRange.offset= maxRangeStart; + fCurrentHighlightAnnotationRange.length= maxRangeEnd - maxRangeStart; + } else { + fTotalHighlightAnnotationRange.offset= maxRangeStart; + fTotalHighlightAnnotationRange.length= maxRangeEnd - maxRangeStart; + fCurrentHighlightAnnotationRange.offset=highlightAnnotationRangeStart; + fCurrentHighlightAnnotationRange.length= highlightAnnotationRangeEnd - highlightAnnotationRangeStart; + } + } else { + if (isWorldChange) { + fCurrentHighlightAnnotationRange= fTotalHighlightAnnotationRange; + fTotalHighlightAnnotationRange= null; + } else { + fCurrentHighlightAnnotationRange= null; + } + } + + adaptToDocumentLength(fCurrentHighlightAnnotationRange); + adaptToDocumentLength(fTotalHighlightAnnotationRange); + } + + /** + * Updates the remembered decoration ranges. + * + * @param drawRangeStart the start of the range + * @param drawRangeEnd the end of the range + * @param isWorldChange tells whether the range belongs to a annotation model event reporting a world change + * @since 3.3 + */ + private void updateDrawRanges(int drawRangeStart, int drawRangeEnd, bool isWorldChange) { + if (drawRangeStart !is Integer.MAX_VALUE) { + + int maxRangeStart= drawRangeStart; + int maxRangeEnd= drawRangeEnd; + + if (fTotalDrawRange !is null) { + maxRangeStart= Math.min(maxRangeStart, fTotalDrawRange.offset); + maxRangeEnd= Math.max(maxRangeEnd, fTotalDrawRange.offset + fTotalDrawRange.length); + } + + if (fTotalDrawRange is null) + fTotalDrawRange= new Position(0); + if (fCurrentDrawRange is null) + fCurrentDrawRange= new Position(0); + + if (isWorldChange) { + fTotalDrawRange.offset= drawRangeStart; + fTotalDrawRange.length= drawRangeEnd - drawRangeStart; + fCurrentDrawRange.offset= maxRangeStart; + fCurrentDrawRange.length= maxRangeEnd - maxRangeStart; + } else { + fTotalDrawRange.offset= maxRangeStart; + fTotalDrawRange.length= maxRangeEnd - maxRangeStart; + fCurrentDrawRange.offset=drawRangeStart; + fCurrentDrawRange.length= drawRangeEnd - drawRangeStart; + } + } else { + if (isWorldChange) { + fCurrentDrawRange= fTotalDrawRange; + fTotalDrawRange= null; + } else { + fCurrentDrawRange= null; + } + } + + adaptToDocumentLength(fCurrentDrawRange); + adaptToDocumentLength(fTotalDrawRange); + } + + /** + * Adapts the given position to the document length. + * + * @param position the position to adapt + * @since 3.0 + */ + private void adaptToDocumentLength(Position position) { + if (position is null) + return; + + int length= fSourceViewer.getDocument().getLength(); + position.offset= Math.min(position.offset, length); + position.length= Math.min(position.length, length - position.offset); + } + + /** + * Returns a decoration for the given annotation if this + * annotation is valid and shown by this painter. + * + * @param annotation the annotation + * @param decoration the decoration to be adapted and returned or null if a new one must be created + * @return the decoration or null if there's no valid one + * @since 3.0 + */ + private Decoration getDecoration(Annotation annotation, Decoration decoration) { + + if (annotation.isMarkedDeleted()) + return null; + + String type= annotation.getType(); + + Object paintingStrategy= getPaintingStrategy(type); + if (paintingStrategy is null || cast(NullStrategy)paintingStrategy ) + return null; + + Color color= getColor(stringcast(type)); + if (color is null) + return null; + + Position position= fModel.getPosition(annotation); + if (position is null || position.isDeleted()) + return null; + + if (decoration is null) + decoration= new Decoration(); + + decoration.fPosition= position; + decoration.fColor= color; + if ( cast(IAnnotationAccessExtension)fAnnotationAccess ) { + IAnnotationAccessExtension extension= cast(IAnnotationAccessExtension) fAnnotationAccess; + decoration.fLayer= extension.getLayer(annotation); + } else { + decoration.fLayer= IAnnotationAccessExtension.DEFAULT_LAYER; + } + + decoration.fPaintingStrategy= paintingStrategy; + + return decoration; + } + + /** + * Returns the painting strategy for the given annotation. + * + * @param type the annotation type + * @return the annotation painter + * @since 3.0 + */ + private Object getPaintingStrategy(String type) { + Object strategy= fCachedAnnotationType2PaintingStrategy.get(type); + if (strategy !is null) + return strategy; + + strategy= fPaintingStrategyId2PaintingStrategy.get(fAnnotationType2PaintingStrategyId.get(type)); + if (strategy !is null) { + fCachedAnnotationType2PaintingStrategy.put(type, strategy); + return strategy; + } + + if ( cast(IAnnotationAccessExtension)fAnnotationAccess ) { + IAnnotationAccessExtension ext = cast(IAnnotationAccessExtension) fAnnotationAccess; + Object[] sts = ext.getSupertypes(stringcast(type)); + for (int i= 0; i < sts.length; i++) { + strategy= fPaintingStrategyId2PaintingStrategy.get(fAnnotationType2PaintingStrategyId.get(sts[i])); + if (strategy !is null) { + fCachedAnnotationType2PaintingStrategy.put(type, strategy); + return strategy; + } + } + } + + fCachedAnnotationType2PaintingStrategy.put(type, cast(Object)NULL_STRATEGY); + return null; + + } + + /** + * Returns the color for the given annotation type + * + * @param annotationType the annotation type + * @return the color + * @since 3.0 + */ + private Color getColor(Object annotationType) { + Color color= cast(Color)fCachedAnnotationType2Color.get(annotationType); + if (color !is null) + return color; + + color= cast(Color)fAnnotationType2Color.get(annotationType); + if (color !is null) { + fCachedAnnotationType2Color.put(annotationType, color); + return color; + } + + if ( cast(IAnnotationAccessExtension)fAnnotationAccess ) { + IAnnotationAccessExtension extension= cast(IAnnotationAccessExtension) fAnnotationAccess; + Object[] superTypes= extension.getSupertypes(annotationType); + if (superTypes !is null) { + for (int i= 0; i < superTypes.length; i++) { + color= cast(Color)fAnnotationType2Color.get(superTypes[i]); + if (color !is null) { + fCachedAnnotationType2Color.put(annotationType, color); + return color; + } + } + } + } + + return null; + } + + /** + * Recomputes the squiggles to be drawn and redraws them. + * + * @param event the annotation model event + * @since 3.0 + */ + private void updatePainting(AnnotationModelEvent event) { + disablePainting(event is null); + + catchupWithModel(event); + + if (!fInputDocumentAboutToBeChanged) + invalidateTextPresentation(); + + enablePainting(); + } + + private void invalidateTextPresentation() { + IRegion r= null; + synchronized (fHighlightedDecorationsMapLock) { + if (fCurrentHighlightAnnotationRange !is null) + r= new Region(fCurrentHighlightAnnotationRange.getOffset(), fCurrentHighlightAnnotationRange.getLength()); + } + if (r is null) + return; + + if ( cast(ITextViewerExtension2)fSourceViewer ) { + if (DEBUG) + System.out_.println(Format("AP: invalidating offset: {}, length= {}", r.getOffset(), r.getLength())); //$NON-NLS-1$ //$NON-NLS-2$ + + (cast(ITextViewerExtension2)fSourceViewer).invalidateTextPresentation(r.getOffset(), r.getLength()); + + } else { + fSourceViewer.invalidateTextPresentation(); + } + } + + /* + * @see dwtx.jface.text.ITextPresentationListener#applyTextPresentation(dwtx.jface.text.TextPresentation) + * @since 3.0 + */ + public void applyTextPresentation(TextPresentation tp) { + Set decorations; + + synchronized (fHighlightedDecorationsMapLock) { + if (fHighlightedDecorationsMap is null || fHighlightedDecorationsMap.isEmpty()) + return; + + decorations= new HashSet(fHighlightedDecorationsMap.entrySet()); + } + + IRegion region= tp.getExtent(); + + if (DEBUG) + System.out_.println(Format("AP: applying text presentation offset: {}, length= {}", region.getOffset(), region.getLength())); //$NON-NLS-1$ //$NON-NLS-2$ + + for (int layer= 0, maxLayer= 1; layer < maxLayer; layer++) { + + for (Iterator iter= decorations.iterator(); iter.hasNext();) { + Map.Entry entry= cast(Map.Entry)iter.next(); + + Annotation a= cast(Annotation)entry.getKey(); + if (a.isMarkedDeleted()) + continue; + + Decoration pp = cast(Decoration)entry.getValue(); + + maxLayer= Math.max(maxLayer, pp.fLayer + 1); // dynamically update layer maximum + if (pp.fLayer !is layer) // wrong layer: skip annotation + continue; + + Position p= pp.fPosition; + if ( cast(ITextViewerExtension5)fSourceViewer ) { + ITextViewerExtension5 extension3= cast(ITextViewerExtension5) fSourceViewer; + if (null is extension3.modelRange2WidgetRange(new Region(p.getOffset(), p.getLength()))) + continue; + } else if (!fSourceViewer.overlapsWithVisibleRegion(p.offset, p.length)) { + continue; + } + + int regionEnd= region.getOffset() + region.getLength(); + int pEnd= p.getOffset() + p.getLength(); + if (pEnd >= region.getOffset() && regionEnd > p.getOffset()) { + int start= Math.max(p.getOffset(), region.getOffset()); + int end= Math.min(regionEnd, pEnd); + int length= Math.max(end - start, 0); + StyleRange styleRange= new StyleRange(start, length, null, null); + (cast(ITextStyleStrategy)pp.fPaintingStrategy).applyTextStyle(styleRange, pp.fColor); + tp.mergeStyleRange(styleRange); + } + } + } + } + + /* + * @see dwtx.jface.text.source.IAnnotationModelListener#modelChanged(dwtx.jface.text.source.IAnnotationModel) + */ + public synchronized void modelChanged(IAnnotationModel model) { + if (DEBUG) + System.err.println("AP: OLD API of AnnotationModelListener called"); //$NON-NLS-1$ + + modelChanged(new AnnotationModelEvent(model)); + } + + /* + * @see dwtx.jface.text.source.IAnnotationModelListenerExtension#modelChanged(dwtx.jface.text.source.AnnotationModelEvent) + */ + public void modelChanged(AnnotationModelEvent event) { + Display textWidgetDisplay; + try { + StyledText textWidget= fTextWidget; + if (textWidget is null || textWidget.isDisposed()) + return; + textWidgetDisplay= textWidget.getDisplay(); + } catch (DWTException ex) { + if (ex.code is DWT.ERROR_WIDGET_DISPOSED) + return; + throw ex; + } + + if (fIsSettingModel) { + // inside the UI thread -> no need for posting + if (textWidgetDisplay is Display.getCurrent()) + updatePainting(event); + else { + /* + * we can throw away the changes since + * further update painting will happen + */ + return; + } + } else { + if (DEBUG && event !is null && event.isWorldChange()) { + System.out_.println("AP: WORLD CHANGED, stack trace follows:"); //$NON-NLS-1$ + ExceptionPrintStackTrace( new Exception(""), Stdout ); + } + + // XXX: posting here is a problem for annotations that are being + // removed and the positions of which are not updated to document + // changes any more. If the document gets modified between + // now and running the posted runnable, the position information + // is not accurate any longer. + textWidgetDisplay.asyncExec( dgRunnable( (AnnotationModelEvent event_){ + if (fTextWidget !is null && !fTextWidget.isDisposed()) + updatePainting(event_); + }, event )); + } + } + + /** + * Sets the color in which the squiggly for the given annotation type should be drawn. + * + * @param annotationType the annotation type + * @param color the color + */ + public void setAnnotationTypeColor(Object annotationType, Color color) { + if (color !is null) + fAnnotationType2Color.put(annotationType, color); + else + fAnnotationType2Color.remove(annotationType); + fCachedAnnotationType2Color.clear(); + } + + /** + * Adds the given annotation type to the list of annotation types whose + * annotations should be painted by this painter using squiggly drawing. If the annotation type + * is already in this list, this method is without effect. + * + * @param annotationType the annotation type + */ + public void addAnnotationType(Object annotationType) { + addAnnotationType(annotationType, SQUIGGLES); + } + + /** + * Adds the given annotation type to the list of annotation types whose + * annotations should be painted by this painter using the given drawing strategy. + * If the annotation type is already in this list, the old drawing strategy gets replaced. + * + * @param annotationType the annotation type + * @param drawingStrategyID the id of the drawing strategy that should be used for this annotation type + * @since 3.0 + */ + public void addAnnotationType(Object annotationType, Object drawingStrategyID) { + fAnnotationType2PaintingStrategyId.put(annotationType, drawingStrategyID); + fCachedAnnotationType2PaintingStrategy.clear(); + + if (fTextInputListener is null) { + fTextInputListener= new class() ITextInputListener { + + /* + * @see dwtx.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument) + */ + public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { + fInputDocumentAboutToBeChanged= true; + } + + /* + * @see dwtx.jface.text.ITextInputListener#inputDocumentChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument) + */ + public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { + fInputDocumentAboutToBeChanged= false; + } + }; + fSourceViewer.addTextInputListener(fTextInputListener); + } + + } + + /** + * Registers a new drawing strategy under the given ID. If there is already a + * strategy registered under id, the old strategy gets replaced. + *

                    The given id can be referenced when adding annotation types, see + * {@link #addAnnotationType(Object, Object)}.

                    + * + * @param id the identifier under which the strategy can be referenced, not null + * @param strategy the new strategy + * @since 3.0 + */ + public void addDrawingStrategy(Object id, IDrawingStrategy strategy) { + // don't permit null as null is used to signal that an annotation type is not + // registered with a specific strategy, and that its annotation hierarchy should be searched + if (id is null) + throw new IllegalArgumentException(null); + fPaintingStrategyId2PaintingStrategy.put(id, cast(Object)strategy); + fCachedAnnotationType2PaintingStrategy.clear(); + } + + /** + * Registers a new drawing strategy under the given ID. If there is already + * a strategy registered under id, the old strategy gets + * replaced. + *

                    + * The given id can be referenced when adding annotation types, see + * {@link #addAnnotationType(Object, Object)}. + *

                    + * + * @param id the identifier under which the strategy can be referenced, not null + * @param strategy the new strategy + * @since 3.4 + */ + public void addTextStyleStrategy(Object id, ITextStyleStrategy strategy) { + // don't permit null as null is used to signal that an annotation type is not + // registered with a specific strategy, and that its annotation hierarchy should be searched + if (id is null) + throw new IllegalArgumentException(null); + fPaintingStrategyId2PaintingStrategy.put(id, cast(Object)strategy); + fCachedAnnotationType2PaintingStrategy.clear(); + } + + /** + * Adds the given annotation type to the list of annotation types whose + * annotations should be highlighted this painter. If the annotation type + * is already in this list, this method is without effect. + * + * @param annotationType the annotation type + * @since 3.0 + */ + public void addHighlightAnnotationType(Object annotationType) { + addAnnotationType(annotationType, HIGHLIGHTING); + } + + /** + * Removes the given annotation type from the list of annotation types whose + * annotations are painted by this painter. If the annotation type is not + * in this list, this method is without effect. + * + * @param annotationType the annotation type + */ + public void removeAnnotationType(Object annotationType) { + fCachedAnnotationType2PaintingStrategy.clear(); + fAnnotationType2PaintingStrategyId.remove(annotationType); + if (fAnnotationType2PaintingStrategyId.isEmpty() && fTextInputListener !is null) { + fSourceViewer.removeTextInputListener(fTextInputListener); + fTextInputListener= null; + fInputDocumentAboutToBeChanged= false; + } + } + + /** + * Removes the given annotation type from the list of annotation types whose + * annotations are highlighted by this painter. If the annotation type is not + * in this list, this method is without effect. + * + * @param annotationType the annotation type + * @since 3.0 + */ + public void removeHighlightAnnotationType(Object annotationType) { + removeAnnotationType(annotationType); + } + + /** + * Clears the list of annotation types whose annotations are + * painted by this painter. + */ + public void removeAllAnnotationTypes() { + fCachedAnnotationType2PaintingStrategy.clear(); + fAnnotationType2PaintingStrategyId.clear(); + if (fTextInputListener !is null) { + fSourceViewer.removeTextInputListener(fTextInputListener); + fTextInputListener= null; + } + } + + /** + * Returns whether the list of annotation types whose annotations are painted + * by this painter contains at least on element. + * + * @return true if there is an annotation type whose annotations are painted + */ + public bool isPaintingAnnotations() { + return !fAnnotationType2PaintingStrategyId.isEmpty(); + } + + /* + * @see dwtx.jface.text.IPainter#dispose() + */ + public void dispose() { + + if (fAnnotationType2Color !is null) { + fAnnotationType2Color.clear(); + fAnnotationType2Color= null; + } + + if (fCachedAnnotationType2Color !is null) { + fCachedAnnotationType2Color.clear(); + fCachedAnnotationType2Color= null; + } + + if (fCachedAnnotationType2PaintingStrategy !is null) { + fCachedAnnotationType2PaintingStrategy.clear(); + fCachedAnnotationType2PaintingStrategy= null; + } + + if (fAnnotationType2PaintingStrategyId !is null) { + fAnnotationType2PaintingStrategyId.clear(); + fAnnotationType2PaintingStrategyId= null; + } + + fTextWidget= null; + fSourceViewer= null; + fAnnotationAccess= null; + fModel= null; + synchronized (fDecorationMapLock) { + fDecorationsMap= null; + } + synchronized (fHighlightedDecorationsMapLock) { + fHighlightedDecorationsMap= null; + } + } + + /** + * Returns the document offset of the upper left corner of the source viewer's view port, + * possibly including partially visible lines. + * + * @return the document offset if the upper left corner of the view port + */ + private int getInclusiveTopIndexStartOffset() { + + if (fTextWidget !is null && !fTextWidget.isDisposed()) { + int top= JFaceTextUtil.getPartialTopIndex(fSourceViewer); + try { + IDocument document= fSourceViewer.getDocument(); + return document.getLineOffset(top); + } catch (BadLocationException x) { + } + } + + return -1; + } + + /** + * Returns the first invisible document offset of the lower right corner of the source viewer's view port, + * possibly including partially visible lines. + * + * @return the first invisible document offset of the lower right corner of the view port + */ + private int getExclusiveBottomIndexEndOffset() { + + if (fTextWidget !is null && !fTextWidget.isDisposed()) { + int bottom= JFaceTextUtil.getPartialBottomIndex(fSourceViewer); + try { + IDocument document= fSourceViewer.getDocument(); + + if (bottom >= document.getNumberOfLines()) + bottom= document.getNumberOfLines() - 1; + + return document.getLineOffset(bottom) + document.getLineLength(bottom); + } catch (BadLocationException x) { + } + } + + return -1; + } + + /* + * @see dwt.events.PaintListener#paintControl(dwt.events.PaintEvent) + */ + public void paintControl(PaintEvent event) { + if (fTextWidget !is null) + handleDrawRequest(event); + } + + /** + * Handles the request to draw the annotations using the given graphical context. + * + * @param event the paint event or null + */ + private void handleDrawRequest(PaintEvent event) { + + if (fTextWidget is null) { + // is already disposed + return; + } + + IRegion clippingRegion= computeClippingRegion(event, false); + if (clippingRegion is null) + return; + + int vOffset= clippingRegion.getOffset(); + int vLength= clippingRegion.getLength(); + + final GC gc= event !is null ? event.gc : null; + + // Clone decorations + Collection decorations; + synchronized (fDecorationMapLock) { + decorations= new ArrayList(fDecorationsMap.size()); + decorations.addAll(fDecorationsMap.entrySet()); + } + + /* + * Create a new list of annotations to be drawn, since removing from decorations is more + * expensive. One bucket per drawing layer. Use linked lists as addition is cheap here. + */ + ArrayList toBeDrawn= new ArrayList(10); + for (Iterator e = decorations.iterator(); e.hasNext();) { + Map.Entry entry= cast(Map.Entry)e.next(); + + Annotation a= cast(Annotation)entry.getKey(); + Decoration pp = cast(Decoration)entry.getValue(); + // prune any annotation that is not drawable or does not need drawing + if (!(a.isMarkedDeleted() || skip(a) || !pp.fPosition.overlapsWith(vOffset, vLength))) { + // ensure sized appropriately + for (int i= toBeDrawn.size(); i <= pp.fLayer; i++) + toBeDrawn.add(new LinkedList()); + (cast(List) toBeDrawn.get(pp.fLayer)).add(cast(Object)entry); + } + } + IDocument document= fSourceViewer.getDocument(); + for (Iterator it= toBeDrawn.iterator(); it.hasNext();) { + List layer= cast(List) it.next(); + for (Iterator e = layer.iterator(); e.hasNext();) { + Map.Entry entry= cast(Map.Entry)e.next(); + Annotation a= cast(Annotation)entry.getKey(); + Decoration pp = cast(Decoration)entry.getValue(); + drawDecoration(pp, gc, a, clippingRegion, document); + } + } + } + + private void drawDecoration(Decoration pp, GC gc, Annotation annotation, IRegion clippingRegion, IDocument document) { + if (clippingRegion is null) + return; + + if (!(cast(IDrawingStrategy)pp.fPaintingStrategy )) + return; + + IDrawingStrategy drawingStrategy= cast(IDrawingStrategy)pp.fPaintingStrategy; + + int clippingOffset= clippingRegion.getOffset(); + int clippingLength= clippingRegion.getLength(); + + Position p= pp.fPosition; + try { + + int startLine= document.getLineOfOffset(p.getOffset()); + int lastInclusive= Math.max(p.getOffset(), p.getOffset() + p.getLength() - 1); + int endLine= document.getLineOfOffset(lastInclusive); + + for (int i= startLine; i <= endLine; i++) { + int lineOffset= document.getLineOffset(i); + int paintStart= Math.max(lineOffset, p.getOffset()); + String lineDelimiter= document.getLineDelimiter(i); + int delimiterLength= lineDelimiter !is null ? lineDelimiter.length() : 0; + int paintLength= Math.min(lineOffset + document.getLineLength(i) - delimiterLength, p.getOffset() + p.getLength()) - paintStart; + if (paintLength >= 0 && overlapsWith(paintStart, paintLength, clippingOffset, clippingLength)) { + // otherwise inside a line delimiter + IRegion widgetRange= getWidgetRange(paintStart, paintLength); + if (widgetRange !is null) { + drawingStrategy.draw(annotation, gc, fTextWidget, widgetRange.getOffset(), widgetRange.getLength(), pp.fColor); + } + } + } + + } catch (BadLocationException x) { + } + } + + /** + * Computes the model (document) region that is covered by the paint event's clipping region. If + * event is null, the model range covered by the visible editor + * area (viewport) is returned. + * + * @param event the paint event or null to use the entire viewport + * @param isClearing tells whether the clipping is need for clearing an annotation + * @return the model region comprised by either the paint event's clipping region or the + * viewport + * @since 3.2 + */ + private IRegion computeClippingRegion(PaintEvent event, bool isClearing) { + if (event is null) { + + if (!isClearing && fCurrentDrawRange !is null) + return new Region(fCurrentDrawRange.offset, fCurrentDrawRange.length); + + // trigger a repaint of the entire viewport + int vOffset= getInclusiveTopIndexStartOffset(); + if (vOffset is -1) + return null; + + // http://bugs.eclipse.org/bugs/show_bug.cgi?id=17147 + int vLength= getExclusiveBottomIndexEndOffset() - vOffset; + + return new Region(vOffset, vLength); + } + + int widgetOffset; + try { + int widgetClippingStartOffset= fTextWidget.getOffsetAtLocation(new Point(0, event.y)); + int firstWidgetLine= fTextWidget.getLineAtOffset(widgetClippingStartOffset); + widgetOffset= fTextWidget.getOffsetAtLine(firstWidgetLine); + } catch (IllegalArgumentException ex1) { + try { + int firstVisibleLine= JFaceTextUtil.getPartialTopIndex(fTextWidget); + widgetOffset= fTextWidget.getOffsetAtLine(firstVisibleLine); + } catch (IllegalArgumentException ex2) { // above try code might fail too + widgetOffset= 0; + } + } + + int widgetEndOffset; + try { + int widgetClippingEndOffset= fTextWidget.getOffsetAtLocation(new Point(0, event.y + event.height)); + int lastWidgetLine= fTextWidget.getLineAtOffset(widgetClippingEndOffset); + widgetEndOffset= fTextWidget.getOffsetAtLine(lastWidgetLine + 1); + } catch (IllegalArgumentException ex1) { + // happens if the editor is not "full", e.g. the last line of the document is visible in the editor + try { + int lastVisibleLine= JFaceTextUtil.getPartialBottomIndex(fTextWidget); + if (lastVisibleLine is fTextWidget.getLineCount() - 1) + // last line + widgetEndOffset= fTextWidget.getCharCount(); + else + widgetEndOffset= fTextWidget.getOffsetAtLine(lastVisibleLine + 1) - 1; + } catch (IllegalArgumentException ex2) { // above try code might fail too + widgetEndOffset= fTextWidget.getCharCount(); + } + } + + IRegion clippingRegion= getModelRange(widgetOffset, widgetEndOffset - widgetOffset); + + return clippingRegion; + } + + /** + * Should the given annotation be skipped when handling draw requests? + * + * @param annotation the annotation + * @return true iff the given annotation should be + * skipped when handling draw requests + * @since 3.0 + */ + protected bool skip(Annotation annotation) { + return false; + } + + /** + * Returns the widget region that corresponds to the + * given offset and length in the viewer's document. + * + * @param modelOffset the model offset + * @param modelLength the model length + * @return the corresponding widget region + */ + private IRegion getWidgetRange(int modelOffset, int modelLength) { + fReusableRegion.setOffset(modelOffset); + fReusableRegion.setLength(modelLength); + + if (fReusableRegion is null || fReusableRegion.getOffset() is Integer.MAX_VALUE) + return null; + + if ( cast(ITextViewerExtension5)fSourceViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) fSourceViewer; + return extension.modelRange2WidgetRange(fReusableRegion); + } + + IRegion region= fSourceViewer.getVisibleRegion(); + int offset= region.getOffset(); + int length= region.getLength(); + + if (overlapsWith(fReusableRegion, region)) { + int p1= Math.max(offset, fReusableRegion.getOffset()); + int p2= Math.min(offset + length, fReusableRegion.getOffset() + fReusableRegion.getLength()); + return new Region(p1 - offset, p2 - p1); + } + return null; + } + + /** + * Returns the model region that corresponds to the given region in the + * viewer's text widget. + * + * @param offset the offset in the viewer's widget + * @param length the length in the viewer's widget + * @return the corresponding document region + * @since 3.2 + */ + private IRegion getModelRange(int offset, int length) { + if (offset is Integer.MAX_VALUE) + return null; + + if ( cast(ITextViewerExtension5)fSourceViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) fSourceViewer; + return extension.widgetRange2ModelRange(new Region(offset, length)); + } + + IRegion region= fSourceViewer.getVisibleRegion(); + return new Region(region.getOffset() + offset, length); + } + + /** + * Checks whether the intersection of the given text ranges + * is empty or not. + * + * @param range1 the first range to check + * @param range2 the second range to check + * @return true if intersection is not empty + */ + private bool overlapsWith(IRegion range1, IRegion range2) { + return overlapsWith(range1.getOffset(), range1.getLength(), range2.getOffset(), range2.getLength()); + } + + /** + * Checks whether the intersection of the given text ranges + * is empty or not. + * + * @param offset1 offset of the first range + * @param length1 length of the first range + * @param offset2 offset of the second range + * @param length2 length of the second range + * @return true if intersection is not empty + */ + private bool overlapsWith(int offset1, int length1, int offset2, int length2) { + int end= offset2 + length2; + int thisEnd= offset1 + length1; + + if (length2 > 0) { + if (length1 > 0) + return offset1 < end && offset2 < thisEnd; + return offset2 <= offset1 && offset1 < end; + } + + if (length1 > 0) + return offset1 <= offset2 && offset2 < thisEnd; + return offset1 is offset2; + } + + /* + * @see dwtx.jface.text.IPainter#deactivate(bool) + */ + public void deactivate(bool redraw) { + if (fIsActive) { + fIsActive= false; + disablePainting(redraw); + setModel(null); + catchupWithModel(null); + } + } + + /** + * Returns whether the given reason causes a repaint. + * + * @param reason the reason + * @return true if repaint reason, false otherwise + * @since 3.0 + */ + protected bool isRepaintReason(int reason) { + return CONFIGURATION is reason || INTERNAL is reason; + } + + /** + * Retrieves the annotation model from the given source viewer. + * + * @param sourceViewer the source viewer + * @return the source viewer's annotation model or null if none can be found + * @since 3.0 + */ + protected IAnnotationModel findAnnotationModel(ISourceViewer sourceViewer) { + if(sourceViewer !is null) + return sourceViewer.getAnnotationModel(); + return null; + } + + /* + * @see dwtx.jface.text.IPainter#paint(int) + */ + public void paint(int reason) { + if (fSourceViewer.getDocument() is null) { + deactivate(false); + return; + } + + if (!fIsActive) { + IAnnotationModel model= findAnnotationModel(fSourceViewer); + if (model !is null) { + fIsActive= true; + setModel(model); + } + } else if (isRepaintReason(reason)) + updatePainting(null); + } + + /* + * @see dwtx.jface.text.IPainter#setPositionManager(dwtx.jface.text.IPaintPositionManager) + */ + public void setPositionManager(IPaintPositionManager manager) { + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/AnnotationRulerColumn.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/AnnotationRulerColumn.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,1042 @@ +/******************************************************************************* + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Nikolay Botev - [projection] Editor loses keyboard focus when expanding folded region - https://bugs.eclipse.org/bugs/show_bug.cgi?id=184255 + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.text.source.AnnotationRulerColumn; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + + + + + + + +import dwt.DWT; +import dwt.custom.StyledText; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.events.MouseEvent; +import dwt.events.MouseListener; +import dwt.events.MouseMoveListener; +import dwt.events.PaintEvent; +import dwt.events.PaintListener; +import dwt.graphics.Cursor; +import dwt.graphics.Font; +import dwt.graphics.GC; +import dwt.graphics.Image; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Canvas; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextListener; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.ITextViewerExtension5; +import dwtx.jface.text.IViewportListener; +import dwtx.jface.text.JFaceTextUtil; +import dwtx.jface.text.Position; +import dwtx.jface.text.TextEvent; + + +/** + * A vertical ruler column showing graphical representations of annotations. + * Will become final. + *

                    + * Do not subclass. + *

                    + * + * @since 2.0 + */ +public class AnnotationRulerColumn : IVerticalRulerColumn, IVerticalRulerInfo, IVerticalRulerInfoExtension { + + /** + * Internal listener class. + */ + class InternalListener : IViewportListener, IAnnotationModelListener, ITextListener { + + /* + * @see IViewportListener#viewportChanged(int) + */ + public void viewportChanged(int verticalPosition) { + if (verticalPosition !is fScrollPos) + redraw(); + } + + /* + * @see IAnnotationModelListener#modelChanged(IAnnotationModel) + */ + public void modelChanged(IAnnotationModel model) { + postRedraw(); + } + + /* + * @see ITextListener#textChanged(TextEvent) + */ + public void textChanged(TextEvent e) { + if (e.getViewerRedrawState()) + postRedraw(); + } + } + + /** + * Implementation of IRegion that can be reused + * by setting the offset and the length. + */ + private static class ReusableRegion : Position , IRegion { + public override int getLength(){ + return super.getLength(); + } + public override int getOffset(){ + return super.getOffset(); + } + } + + /** + * Pair of an annotation and their associated position. Used inside the paint method + * for sorting annotations based on the offset of their position. + * @since 3.0 + */ + private static class Tuple { + Annotation annotation; + Position position; + + this(Annotation annotation, Position position) { + this.annotation= annotation; + this.position= position; + } + } + + /** + * Comparator for Tuples. + * @since 3.0 + */ + private static class TupleComparator : Comparator { + /* + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + public int compare(Object o1, Object o2) { + Position p1= (cast(Tuple) o1).position; + Position p2= (cast(Tuple) o2).position; + return p1.getOffset() - p2.getOffset(); + } + } + + /** This column's parent ruler */ + private CompositeRuler fParentRuler; + /** The cached text viewer */ + private ITextViewer fCachedTextViewer; + /** The cached text widget */ + private StyledText fCachedTextWidget; + /** The ruler's canvas */ + private Canvas fCanvas; + /** The vertical ruler's model */ + private IAnnotationModel fModel; + /** Cache for the actual scroll position in pixels */ + private int fScrollPos; + /** The buffer for double buffering */ + private Image fBuffer; + /** The internal listener */ + private InternalListener fInternalListener; + /** The width of this vertical ruler */ + private int fWidth; + /** Switch for enabling/disabling the setModel method. */ + private bool fAllowSetModel= true; + /** + * The list of annotation types to be shown in this ruler. + * @since 3.0 + */ + private Set fConfiguredAnnotationTypes; + /** + * The list of allowed annotation types to be shown in this ruler. + * An allowed annotation type maps to true, a disallowed + * to false. + * @since 3.0 + */ + private Map fAllowedAnnotationTypes; + /** + * The annotation access extension. + * @since 3.0 + */ + private IAnnotationAccessExtension fAnnotationAccessExtension; + /** + * The hover for this column. + * @since 3.0 + */ + private IAnnotationHover fHover; + /** + * The cached annotations. + * @since 3.0 + */ + private List fCachedAnnotations; + /** + * The comparator for sorting annotations according to the offset of their position. + * @since 3.0 + */ + private Comparator fTupleComparator; + /** + * The hit detection cursor. + * @since 3.0 + */ + private Cursor fHitDetectionCursor; + /** + * The last cursor. + * @since 3.0 + */ + private Cursor fLastCursor; + /** + * This ruler's mouse listener. + * @since 3.0 + */ + private MouseListener fMouseListener; + + private void instanceInit(){ + fInternalListener= new InternalListener(); + fConfiguredAnnotationTypes= new HashSet(); + fAllowedAnnotationTypes= new HashMap(); + fCachedAnnotations= new ArrayList(); + fTupleComparator= new TupleComparator(); + } + /** + * Constructs this column with the given arguments. + * + * @param model the annotation model to get the annotations from + * @param width the width of the vertical ruler + * @param annotationAccess the annotation access + * @since 3.0 + */ + public this(IAnnotationModel model, int width, IAnnotationAccess annotationAccess) { + this(width, annotationAccess); + fAllowSetModel= false; + fModel= model; + fModel.addAnnotationModelListener(fInternalListener); + } + + /** + * Constructs this column with the given arguments. + * + * @param width the width of the vertical ruler + * @param annotationAccess the annotation access + * @since 3.0 + */ + public this(int width, IAnnotationAccess annotationAccess) { + instanceInit(); + fWidth= width; + if ( cast(IAnnotationAccessExtension)annotationAccess ) + fAnnotationAccessExtension= cast(IAnnotationAccessExtension) annotationAccess; + } + + /** + * Constructs this column with the given arguments. + * + * @param model the annotation model to get the annotations from + * @param width the width of the vertical ruler + */ + public this(IAnnotationModel model, int width) { + instanceInit(); + fWidth= width; + fAllowSetModel= false; + fModel= model; + fModel.addAnnotationModelListener(fInternalListener); + } + + /** + * Constructs this column with the given width. + * + * @param width the width of the vertical ruler + */ + public this(int width) { + instanceInit(); + fWidth= width; + } + + /* + * @see IVerticalRulerColumn#getControl() + */ + public Control getControl() { + return fCanvas; + } + + /* + * @see IVerticalRulerColumn#getWidth() + */ + public int getWidth() { + return fWidth; + } + + /* + * @see IVerticalRulerColumn#createControl(CompositeRuler, Composite) + */ + public Control createControl(CompositeRuler parentRuler, Composite parentControl) { + + fParentRuler= parentRuler; + fCachedTextViewer= parentRuler.getTextViewer(); + fCachedTextWidget= fCachedTextViewer.getTextWidget(); + + fHitDetectionCursor= new Cursor(parentControl.getDisplay(), DWT.CURSOR_HAND); + + fCanvas= createCanvas(parentControl); + + fCanvas.addPaintListener(new class() PaintListener { + public void paintControl(PaintEvent event) { + if (fCachedTextViewer !is null) + doubleBufferPaint(event.gc); + } + }); + + fCanvas.addDisposeListener(new class() DisposeListener { + public void widgetDisposed(DisposeEvent e) { + handleDispose(); + fCachedTextViewer= null; + fCachedTextWidget= null; + } + }); + + fMouseListener= new class() MouseListener { + public void mouseUp(MouseEvent event) { + int lineNumber; + if (isPropagatingMouseListener()) { + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + lineNumber= fParentRuler.getLineOfLastMouseButtonActivity(); + } else + lineNumber= fParentRuler.toDocumentLineNumber(event.y); + + if (1 is event.button) + mouseClicked(lineNumber); + } + + public void mouseDown(MouseEvent event) { + if (isPropagatingMouseListener()) + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + } + + public void mouseDoubleClick(MouseEvent event) { + int lineNumber; + if (isPropagatingMouseListener()) { + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + lineNumber= fParentRuler.getLineOfLastMouseButtonActivity(); + } else + lineNumber= fParentRuler.toDocumentLineNumber(event.y); + + if (1 is event.button) + mouseDoubleClicked(lineNumber); + } + }; + fCanvas.addMouseListener(fMouseListener); + + fCanvas.addMouseMoveListener(new class() MouseMoveListener { + /* + * @see dwt.events.MouseMoveListener#mouseMove(dwt.events.MouseEvent) + * @since 3.0 + */ + public void mouseMove(MouseEvent e) { + handleMouseMove(e); + } + }); + + if (fCachedTextViewer !is null) { + fCachedTextViewer.addViewportListener(fInternalListener); + fCachedTextViewer.addTextListener(fInternalListener); + } + + return fCanvas; + } + + /** + * Creates a canvas with the given parent. + * + * @param parent the parent + * @return the created canvas + */ + private Canvas createCanvas(Composite parent) { + return new class(parent, DWT.NO_BACKGROUND | DWT.NO_FOCUS) Canvas { + this( Composite p, int s ){ + super(p,s); + } + /* + * @see dwt.widgets.Control#addMouseListener(dwt.events.MouseListener) + * @since 3.0 + */ + public void addMouseListener(MouseListener listener) { + if (isPropagatingMouseListener() || listener is fMouseListener) + super.addMouseListener(listener); + } + }; + } + + /** + * Tells whether this ruler column propagates mouse listener + * events to its parent. + * + * @return true if propagating to parent + * @since 3.0 + */ + protected bool isPropagatingMouseListener() { + return true; + } + + /** + * Hook method for a mouse double click event on the given ruler line. + * + * @param rulerLine the ruler line + */ + protected void mouseDoubleClicked(int rulerLine) { + } + + /** + * Hook method for a mouse click event on the given ruler line. + * + * @param rulerLine the ruler line + * @since 3.0 + */ + protected void mouseClicked(int rulerLine) { + } + + /** + * Handles mouse moves. + * + * @param event the mouse move event + */ + private void handleMouseMove(MouseEvent event) { + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + if (fCachedTextViewer !is null) { + int line= toDocumentLineNumber(event.y); + Cursor cursor= (hasAnnotation(line) ? fHitDetectionCursor : null); + if (cursor !is fLastCursor) { + fCanvas.setCursor(cursor); + fLastCursor= cursor; + } + } + } + + /** + * Tells whether the given line contains an annotation. + * + * @param lineNumber the line number + * @return true if the given line contains an annotation + */ + protected bool hasAnnotation(int lineNumber) { + + IAnnotationModel model= fModel; + if ( cast(IAnnotationModelExtension)fModel ) + model= (cast(IAnnotationModelExtension)fModel).getAnnotationModel(SourceViewer.MODEL_ANNOTATION_MODEL); + + if (model is null) + return false; + + IRegion line; + try { + IDocument d= fCachedTextViewer.getDocument(); + if (d is null) + return false; + + line= d.getLineInformation(lineNumber); + } catch (BadLocationException ex) { + return false; + } + + int lineStart= line.getOffset(); + int lineLength= line.getLength(); + + Iterator e; + if ( cast(IAnnotationModelExtension2)fModel ) + e= (cast(IAnnotationModelExtension2)fModel).getAnnotationIterator(lineStart, lineLength + 1, true, true); + else + e= model.getAnnotationIterator(); + + while (e.hasNext()) { + Annotation a= cast(Annotation) e.next(); + + if (a.isMarkedDeleted()) + continue; + + if (skip(a)) + continue; + + Position p= model.getPosition(a); + if (p is null || p.isDeleted()) + continue; + + if (p.overlapsWith(lineStart, lineLength) || p.length is 0 && p.offset is lineStart + lineLength) + return true; + } + + return false; + } + + /** + * Disposes the ruler's resources. + */ + private void handleDispose() { + + if (fCachedTextViewer !is null) { + fCachedTextViewer.removeViewportListener(fInternalListener); + fCachedTextViewer.removeTextListener(fInternalListener); + } + + if (fModel !is null) + fModel.removeAnnotationModelListener(fInternalListener); + + if (fBuffer !is null) { + fBuffer.dispose(); + fBuffer= null; + } + + if (fHitDetectionCursor !is null) { + fHitDetectionCursor.dispose(); + fHitDetectionCursor= null; + } + + fConfiguredAnnotationTypes.clear(); + fAllowedAnnotationTypes.clear(); + fAnnotationAccessExtension= null; + } + + /** + * Double buffer drawing. + * + * @param dest the GC to draw into + */ + private void doubleBufferPaint(GC dest) { + + Point size= fCanvas.getSize(); + + if (size.x <= 0 || size.y <= 0) + return; + + if (fBuffer !is null) { + Rectangle r= fBuffer.getBounds(); + if (r.width !is size.x || r.height !is size.y) { + fBuffer.dispose(); + fBuffer= null; + } + } + if (fBuffer is null) + fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y); + + GC gc= new GC(fBuffer); + gc.setFont(fCachedTextWidget.getFont()); + try { + gc.setBackground(fCanvas.getBackground()); + gc.fillRectangle(0, 0, size.x, size.y); + + if ( cast(ITextViewerExtension5)fCachedTextViewer ) + doPaint1(gc); + else + doPaint(gc); + } finally { + gc.dispose(); + } + + dest.drawImage(fBuffer, 0, 0); + } + + /** + * Returns the document offset of the upper left corner of the source viewer's + * view port, possibly including partially visible lines. + * + * @return document offset of the upper left corner including partially visible lines + */ + protected int getInclusiveTopIndexStartOffset() { + if (fCachedTextWidget is null || fCachedTextWidget.isDisposed()) + return -1; + + IDocument document= fCachedTextViewer.getDocument(); + if (document is null) + return -1; + + int top= JFaceTextUtil.getPartialTopIndex(fCachedTextViewer); + try { + return document.getLineOffset(top); + } catch (BadLocationException x) { + return -1; + } + } + + /** + * Returns the first invisible document offset of the lower right corner of the source viewer's view port, + * possibly including partially visible lines. + * + * @return the first invisible document offset of the lower right corner of the view port + */ + private int getExclusiveBottomIndexEndOffset() { + if (fCachedTextWidget is null || fCachedTextWidget.isDisposed()) + return -1; + + IDocument document= fCachedTextViewer.getDocument(); + if (document is null) + return -1; + + int bottom= JFaceTextUtil.getPartialBottomIndex(fCachedTextViewer); + try { + if (bottom >= document.getNumberOfLines()) + bottom= document.getNumberOfLines() - 1; + return document.getLineOffset(bottom) + document.getLineLength(bottom); + } catch (BadLocationException x) { + return -1; + } + } + + /** + * Draws the vertical ruler w/o drawing the Canvas background. + * + * @param gc the GC to draw into + */ + protected void doPaint(GC gc) { + + if (fModel is null || fCachedTextViewer is null) + return; + + int topLeft= getInclusiveTopIndexStartOffset(); + // http://dev.eclipse.org/bugs/show_bug.cgi?id=14938 + // http://dev.eclipse.org/bugs/show_bug.cgi?id=22487 + // we want the exclusive offset (right after the last character) + int bottomRight= getExclusiveBottomIndexEndOffset(); + int viewPort= bottomRight - topLeft; + + fScrollPos= fCachedTextWidget.getTopPixel(); + Point dimension= fCanvas.getSize(); + + IDocument doc= fCachedTextViewer.getDocument(); + if (doc is null) + return; + + int topLine= -1, bottomLine= -1; + try { + IRegion region= fCachedTextViewer.getVisibleRegion(); + topLine= doc.getLineOfOffset(region.getOffset()); + bottomLine= doc.getLineOfOffset(region.getOffset() + region.getLength()); + } catch (BadLocationException x) { + return; + } + + // draw Annotations + Rectangle r= new Rectangle(0, 0, 0, 0); + int maxLayer= 1; // loop at least once through layers. + + for (int layer= 0; layer < maxLayer; layer++) { + Iterator iter; + if ( cast(IAnnotationModelExtension2)fModel ) + iter= (cast(IAnnotationModelExtension2)fModel).getAnnotationIterator(topLeft, viewPort + 1, true, true); + else + iter= fModel.getAnnotationIterator(); + + while (iter.hasNext()) { + Annotation annotation= cast(Annotation) iter.next(); + + int lay= IAnnotationAccessExtension.DEFAULT_LAYER; + if (fAnnotationAccessExtension !is null) + lay= fAnnotationAccessExtension.getLayer(annotation); + maxLayer= Math.max(maxLayer, lay+1); // dynamically update layer maximum + if (lay !is layer) // wrong layer: skip annotation + continue; + + if (skip(annotation)) + continue; + + Position position= fModel.getPosition(annotation); + if (position is null) + continue; + + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=20284 + // Position.overlapsWith returns false if the position just starts at the end + // of the specified range. If the position has zero length, we want to include it anyhow + int viewPortSize= position.getLength() is 0 ? viewPort + 1 : viewPort; + if (!position.overlapsWith(topLeft, viewPortSize)) + continue; + + try { + + int offset= position.getOffset(); + int length= position.getLength(); + + int startLine= doc.getLineOfOffset(offset); + if (startLine < topLine) + startLine= topLine; + + int endLine= startLine; + if (length > 0) + endLine= doc.getLineOfOffset(offset + length - 1); + if (endLine > bottomLine) + endLine= bottomLine; + + startLine -= topLine; + endLine -= topLine; + + r.x= 0; + r.y= JFaceTextUtil.computeLineHeight(fCachedTextWidget, 0, startLine, startLine) - fScrollPos; + + r.width= dimension.x; + int lines= endLine - startLine; + + r.height= JFaceTextUtil.computeLineHeight(fCachedTextWidget, startLine, endLine + 1, lines + 1); + + if (r.y < dimension.y && fAnnotationAccessExtension !is null) // annotation within visible area + fAnnotationAccessExtension.paint(annotation, gc, fCanvas, r); + + } catch (BadLocationException x) { + } + } + } + } + + /** + * Draws the vertical ruler w/o drawing the Canvas background. Implementation based + * on ITextViewerExtension5. Will replace doPaint(GC). + * + * @param gc the GC to draw into + */ + protected void doPaint1(GC gc) { + + if (fModel is null || fCachedTextViewer is null) + return; + + ITextViewerExtension5 extension= cast(ITextViewerExtension5) fCachedTextViewer; + + fScrollPos= fCachedTextWidget.getTopPixel(); + Point dimension= fCanvas.getSize(); + + int vOffset= getInclusiveTopIndexStartOffset(); + int vLength= getExclusiveBottomIndexEndOffset() - vOffset; + + // draw Annotations + Rectangle r= new Rectangle(0, 0, 0, 0); + ReusableRegion range= new ReusableRegion(); + + int minLayer= Integer.MAX_VALUE, maxLayer= Integer.MIN_VALUE; + fCachedAnnotations.clear(); + Iterator iter; + if ( cast(IAnnotationModelExtension2)fModel ) + iter= (cast(IAnnotationModelExtension2)fModel).getAnnotationIterator(vOffset, vLength + 1, true, true); + else + iter= fModel.getAnnotationIterator(); + + while (iter.hasNext()) { + Annotation annotation= cast(Annotation) iter.next(); + + if (skip(annotation)) + continue; + + Position position= fModel.getPosition(annotation); + if (position is null) + continue; + + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=217710 + int extendedVLength= position.getLength() is 0 ? vLength + 1 : vLength; + if (!position.overlapsWith(vOffset, extendedVLength)) + continue; + + int lay= IAnnotationAccessExtension.DEFAULT_LAYER; + if (fAnnotationAccessExtension !is null) + lay= fAnnotationAccessExtension.getLayer(annotation); + + minLayer= Math.min(minLayer, lay); + maxLayer= Math.max(maxLayer, lay); + fCachedAnnotations.add(new Tuple(annotation, position)); + } + Collections.sort(fCachedAnnotations, fTupleComparator); + + for (int layer= minLayer; layer <= maxLayer; layer++) { + for (int i= 0, n= fCachedAnnotations.size(); i < n; i++) { + Tuple tuple= cast(Tuple) fCachedAnnotations.get(i); + Annotation annotation= tuple.annotation; + Position position= tuple.position; + + int lay= IAnnotationAccessExtension.DEFAULT_LAYER; + if (fAnnotationAccessExtension !is null) + lay= fAnnotationAccessExtension.getLayer(annotation); + if (lay !is layer) // wrong layer: skip annotation + continue; + + range.setOffset(position.getOffset()); + range.setLength(position.getLength()); + IRegion widgetRegion= extension.modelRange2WidgetRange(range); + if (widgetRegion is null) + continue; + + int startLine= extension.widgetLineOfWidgetOffset(widgetRegion.getOffset()); + if (startLine is -1) + continue; + + int endLine= extension.widgetLineOfWidgetOffset(widgetRegion.getOffset() + Math.max(widgetRegion.getLength() -1, 0)); + if (endLine is -1) + continue; + + r.x= 0; + r.y= JFaceTextUtil.computeLineHeight(fCachedTextWidget, 0, startLine, startLine) - fScrollPos; + + r.width= dimension.x; + int lines= endLine - startLine; + r.height= JFaceTextUtil.computeLineHeight(fCachedTextWidget, startLine, endLine + 1, lines + 1); + + if (r.y < dimension.y && fAnnotationAccessExtension !is null) // annotation within visible area + fAnnotationAccessExtension.paint(annotation, gc, fCanvas, r); + } + } + + fCachedAnnotations.clear(); + } + + + /** + * Post a redraw request for this column into the UI thread. + */ + private void postRedraw() { + if (fCanvas !is null && !fCanvas.isDisposed()) { + Display d= fCanvas.getDisplay(); + if (d !is null) { + d.asyncExec(new class() Runnable { + public void run() { + redraw(); + } + }); + } + } + } + + /* + * @see IVerticalRulerColumn#redraw() + */ + public void redraw() { + if (fCanvas !is null && !fCanvas.isDisposed()) { + GC gc= new GC(fCanvas); + doubleBufferPaint(gc); + gc.dispose(); + } + } + + /* + * @see IVerticalRulerColumn#setModel + */ + public void setModel(IAnnotationModel model) { + if (fAllowSetModel && model !is fModel) { + + if (fModel !is null) + fModel.removeAnnotationModelListener(fInternalListener); + + fModel= model; + + if (fModel !is null) + fModel.addAnnotationModelListener(fInternalListener); + + postRedraw(); + } + } + + /* + * @see IVerticalRulerColumn#setFont(Font) + */ + public void setFont(Font font) { + } + + /** + * Returns the cached text viewer. + * + * @return the cached text viewer + */ + protected ITextViewer getCachedTextViewer() { + return fCachedTextViewer; + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getModel() + */ + public IAnnotationModel getModel() { + return fModel; + } + + /** + * Adds the given annotation type to this annotation ruler column. Starting + * with this call, annotations of the given type are shown in this annotation + * ruler column. + * + * @param annotationType the annotation type + * @since 3.0 + */ + public void addAnnotationType(Object annotationType) { + fConfiguredAnnotationTypes.add(annotationType); + fAllowedAnnotationTypes.clear(); + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfo#getLineOfLastMouseButtonActivity() + * @since 3.0 + */ + public int getLineOfLastMouseButtonActivity() { + return fParentRuler.getLineOfLastMouseButtonActivity(); + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfo#toDocumentLineNumber(int) + * @since 3.0 + */ + public int toDocumentLineNumber(int y_coordinate) { + return fParentRuler.toDocumentLineNumber(y_coordinate); + } + + /** + * Removes the given annotation type from this annotation ruler column. + * Annotations of the given type are no longer shown in this annotation + * ruler column. + * + * @param annotationType the annotation type + * @since 3.0 + */ + public void removeAnnotationType(Object annotationType) { + fConfiguredAnnotationTypes.remove(annotationType); + fAllowedAnnotationTypes.clear(); + } + + /** + * Returns whether the given annotation should be skipped by the drawing + * routine. + * + * @param annotation the annotation + * @return true if annotation of the given type should be + * skipped, false otherwise + * @since 3.0 + */ + private bool skip(Annotation annotation) { + Object annotationType= stringcast(annotation.getType()); + Boolean allowed= cast(Boolean) fAllowedAnnotationTypes.get(annotationType); + if (allowed !is null) + return !allowed.booleanValue(); + + bool skip= skip(annotationType); + fAllowedAnnotationTypes.put(annotationType, !skip ? Boolean.TRUE : Boolean.FALSE); + return skip; + } + + /** + * Computes whether the annotation of the given type should be skipped or + * not. + * + * @param annotationType the annotation type + * @return true if annotation should be skipped, false + * otherwise + * @since 3.0 + */ + private bool skip(Object annotationType) { + if (fAnnotationAccessExtension !is null) { + Iterator e= fConfiguredAnnotationTypes.iterator(); + while (e.hasNext()) { + if (fAnnotationAccessExtension.isSubtype(annotationType, e.next())) + return false; + } + return true; + } + return !fConfiguredAnnotationTypes.contains(annotationType); + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getHover() + * @since 3.0 + */ + public IAnnotationHover getHover() { + return fHover; + } + + /** + * @param hover The hover to set. + * @since 3.0 + */ + public void setHover(IAnnotationHover hover) { + fHover= hover; + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#addVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener) + * @since 3.0 + */ + public void addVerticalRulerListener(IVerticalRulerListener listener) { + throw new UnsupportedOperationException(); + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#removeVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener) + * @since 3.0 + */ + public void removeVerticalRulerListener(IVerticalRulerListener listener) { + throw new UnsupportedOperationException(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/ChangeRulerColumn.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/ChangeRulerColumn.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,631 @@ +/******************************************************************************* + * 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 + * 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.text.source.ChangeRulerColumn; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + + + + +import dwt.DWT; +import dwt.custom.StyledText; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.events.MouseEvent; +import dwt.events.MouseListener; +import dwt.events.MouseMoveListener; +import dwt.events.PaintEvent; +import dwt.events.PaintListener; +import dwt.graphics.Color; +import dwt.graphics.Font; +import dwt.graphics.GC; +import dwt.graphics.Image; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Canvas; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwtx.core.runtime.Assert; +import dwtx.jface.internal.text.revisions.RevisionPainter; +import dwtx.jface.internal.text.source.DiffPainter; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextListener; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.ITextViewerExtension5; +import dwtx.jface.text.IViewportListener; +import dwtx.jface.text.JFaceTextUtil; +import dwtx.jface.text.TextEvent; +import dwtx.jface.text.revisions.IRevisionRulerColumn; +import dwtx.jface.text.revisions.RevisionInformation; +import dwtx.jface.viewers.ISelectionProvider; + +/** + * A vertical ruler column displaying line numbers and serving as a UI for quick diff. + * Clients instantiate and configure object of this class. + * + * @since 3.0 + */ +public final class ChangeRulerColumn : IVerticalRulerColumn, IVerticalRulerInfo, IVerticalRulerInfoExtension, IChangeRulerColumn, IRevisionRulerColumn { + /** + * Handles all the mouse interaction in this line number ruler column. + */ + private class MouseHandler : MouseListener, MouseMoveListener { + + /* + * @see dwt.events.MouseListener#mouseUp(dwt.events.MouseEvent) + */ + public void mouseUp(MouseEvent event) { + } + + /* + * @see dwt.events.MouseListener#mouseDown(dwt.events.MouseEvent) + */ + public void mouseDown(MouseEvent event) { + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + } + + /* + * @see dwt.events.MouseListener#mouseDoubleClick(dwt.events.MouseEvent) + */ + public void mouseDoubleClick(MouseEvent event) { + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + } + + /* + * @see dwt.events.MouseMoveListener#mouseMove(dwt.events.MouseEvent) + */ + public void mouseMove(MouseEvent event) { + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + } + } + + /** + * Internal listener class. + */ + private class InternalListener : IViewportListener, ITextListener { + + /* + * @see IViewportListener#viewportChanged(int) + */ + public void viewportChanged(int verticalPosition) { + if (verticalPosition !is fScrollPos) + redraw(); + } + + /* + * @see ITextListener#textChanged(TextEvent) + */ + public void textChanged(TextEvent event) { + + if (!event.getViewerRedrawState()) + return; + + if (fSensitiveToTextChanges || event.getDocumentEvent() is null) + postRedraw(); + + } + } + + /** + * The view(port) listener. + */ + private /+const+/ InternalListener fInternalListener; + /** + * The mouse handler. + * @since 3.2 + */ + private /+const+/ MouseHandler fMouseHandler; + /** + * The revision painter. + * @since 3.2 + */ + private const RevisionPainter fRevisionPainter; + /** + * The diff info painter. + * @since 3.2 + */ + private const DiffPainter fDiffPainter; + + /** This column's parent ruler */ + private CompositeRuler fParentRuler; + /** Cached text viewer */ + private ITextViewer fCachedTextViewer; + /** Cached text widget */ + private StyledText fCachedTextWidget; + /** The columns canvas */ + private Canvas fCanvas; + /** The background color */ + private Color fBackground; + /** The ruler's annotation model. */ + private IAnnotationModel fAnnotationModel; + /** The width of the change ruler column. */ + private const int fWidth= 5; + + /** Cache for the actual scroll position in pixels */ + private int fScrollPos; + /** The buffer for double buffering */ + private Image fBuffer; + /** Indicates whether this column reacts on text change events */ + private bool fSensitiveToTextChanges= false; + + private void instanceInit(){ + fInternalListener= new InternalListener(); + fMouseHandler= new MouseHandler(); + } + /** + * Creates a new ruler column. + * + * @deprecated since 3.2 use {@link #ChangeRulerColumn(ISharedTextColors)} instead + */ + public this() { + instanceInit(); + fRevisionPainter= null; + fDiffPainter= new DiffPainter(this, null); + } + + /** + * Creates a new revision ruler column. + * + * @param sharedColors the colors to look up RGBs + * @since 3.2 + */ + public this(ISharedTextColors sharedColors) { + instanceInit(); + Assert.isNotNull(cast(Object)sharedColors); + fRevisionPainter= new RevisionPainter(this, sharedColors); + fDiffPainter= new DiffPainter(this, null); // no shading + } + + /** + * Returns the System background color for list widgets. + * + * @return the System background color for list widgets + */ + private Color getBackground() { + if (fBackground is null) + return fCachedTextWidget.getDisplay().getSystemColor(DWT.COLOR_LIST_BACKGROUND); + return fBackground; + } + + /* + * @see IVerticalRulerColumn#createControl(CompositeRuler, Composite) + */ + public Control createControl(CompositeRuler parentRuler, Composite parentControl) { + + fParentRuler= parentRuler; + fCachedTextViewer= parentRuler.getTextViewer(); + fCachedTextWidget= fCachedTextViewer.getTextWidget(); + + fCanvas= new Canvas(parentControl, DWT.NONE); + fCanvas.setBackground(getBackground()); + + fCanvas.addPaintListener(new class() PaintListener { + public void paintControl(PaintEvent event) { + if (fCachedTextViewer !is null) + doubleBufferPaint(event.gc); + } + }); + + fCanvas.addDisposeListener(new class() DisposeListener { + public void widgetDisposed(DisposeEvent e) { + handleDispose(); + fCachedTextViewer= null; + fCachedTextWidget= null; + } + }); + + fCanvas.addMouseListener(fMouseHandler); + fCanvas.addMouseMoveListener(fMouseHandler); + + if (fCachedTextViewer !is null) { + + fCachedTextViewer.addViewportListener(fInternalListener); + fCachedTextViewer.addTextListener(fInternalListener); + } + + fRevisionPainter.setParentRuler(parentRuler); + fDiffPainter.setParentRuler(parentRuler); + + return fCanvas; + } + + /** + * Disposes the column's resources. + */ + protected void handleDispose() { + + if (fCachedTextViewer !is null) { + fCachedTextViewer.removeViewportListener(fInternalListener); + fCachedTextViewer.removeTextListener(fInternalListener); + } + + if (fBuffer !is null) { + fBuffer.dispose(); + fBuffer= null; + } + } + + /** + * Double buffer drawing. + * + * @param dest the GC to draw into + */ + private void doubleBufferPaint(GC dest) { + + Point size= fCanvas.getSize(); + + if (size.x <= 0 || size.y <= 0) + return; + + if (fBuffer !is null) { + Rectangle r= fBuffer.getBounds(); + if (r.width !is size.x || r.height !is size.y) { + fBuffer.dispose(); + fBuffer= null; + } + } + if (fBuffer is null) + fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y); + + GC gc= new GC(fBuffer); + gc.setFont(fCanvas.getFont()); + + try { + gc.setBackground(getBackground()); + gc.fillRectangle(0, 0, size.x, size.y); + + doPaint(gc); + } finally { + gc.dispose(); + } + + dest.drawImage(fBuffer, 0, 0); + } + + /** + * Returns the view port height in lines. + * + * @return the view port height in lines + * @deprecated as of 3.2 the number of lines in the viewport cannot be computed because + * StyledText supports variable line heights + */ + protected int getVisibleLinesInViewport() { + // Hack to reduce amount of copied code. + return LineNumberRulerColumn.getVisibleLinesInViewport(fCachedTextWidget); + } + + /** + * Returns true if the viewport displays the entire viewer contents, i.e. the + * viewer is not vertically scrollable. + * + * @return true if the viewport displays the entire contents, false otherwise + * @since 3.2 + */ + protected final bool isViewerCompletelyShown() { + return JFaceTextUtil.isShowingEntireContents(fCachedTextWidget); + } + + /** + * Draws the ruler column. + * + * @param gc the GC to draw into + */ + private void doPaint(GC gc) { + ILineRange visibleModelLines= computeVisibleModelLines(); + if (visibleModelLines is null) + return; + + fSensitiveToTextChanges= isViewerCompletelyShown(); + + fScrollPos= fCachedTextWidget.getTopPixel(); + + fRevisionPainter.paint(gc, visibleModelLines); + if (!fRevisionPainter.hasInformation()) // don't paint quick diff colors if revisions are painted + fDiffPainter.paint(gc, visibleModelLines); + } + + /* + * @see IVerticalRulerColumn#redraw() + */ + public void redraw() { + + if (fCachedTextViewer !is null && fCanvas !is null && !fCanvas.isDisposed()) { + GC gc= new GC(fCanvas); + doubleBufferPaint(gc); + gc.dispose(); + } + } + + /* + * @see IVerticalRulerColumn#setFont(Font) + */ + public void setFont(Font font) { + } + + /** + * Returns the parent (composite) ruler of this ruler column. + * + * @return the parent ruler + * @since 3.0 + */ + private CompositeRuler getParentRuler() { + return fParentRuler; + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfo#getLineOfLastMouseButtonActivity() + */ + public int getLineOfLastMouseButtonActivity() { + return getParentRuler().getLineOfLastMouseButtonActivity(); + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfo#toDocumentLineNumber(int) + */ + public int toDocumentLineNumber(int y_coordinate) { + return getParentRuler().toDocumentLineNumber(y_coordinate); + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getHover() + */ + public IAnnotationHover getHover() { + int activeLine= getParentRuler().getLineOfLastMouseButtonActivity(); + if (fRevisionPainter.hasHover(activeLine)) + return fRevisionPainter.getHover(); + if (fDiffPainter.hasHover(activeLine)) + return fDiffPainter.getHover(); + return null; + } + + /* + * @see dwtx.jface.text.source.IChangeRulerColumn#setHover(dwtx.jface.text.source.IAnnotationHover) + */ + public void setHover(IAnnotationHover hover) { + fRevisionPainter.setHover(hover); + fDiffPainter.setHover(hover); + } + + /* + * @see IVerticalRulerColumn#setModel(IAnnotationModel) + */ + public void setModel(IAnnotationModel model) { + setAnnotationModel(model); + fRevisionPainter.setModel(model); + fDiffPainter.setModel(model); + } + + private void setAnnotationModel(IAnnotationModel model) { + if (fAnnotationModel !is model) + fAnnotationModel= model; + } + + /* + * @see dwtx.jface.text.source.IChangeRulerColumn#setBackground(dwt.graphics.Color) + */ + public void setBackground(Color background) { + fBackground= background; + if (fCanvas !is null && !fCanvas.isDisposed()) + fCanvas.setBackground(getBackground()); + fRevisionPainter.setBackground(background); + fDiffPainter.setBackground(background); + } + + /* + * @see dwtx.jface.text.source.IChangeRulerColumn#setAddedColor(dwt.graphics.Color) + */ + public void setAddedColor(Color addedColor) { + fDiffPainter.setAddedColor(addedColor); + } + + /* + * @see dwtx.jface.text.source.IChangeRulerColumn#setChangedColor(dwt.graphics.Color) + */ + public void setChangedColor(Color changedColor) { + fDiffPainter.setChangedColor(changedColor); + } + + /* + * @see dwtx.jface.text.source.IChangeRulerColumn#setDeletedColor(dwt.graphics.Color) + */ + public void setDeletedColor(Color deletedColor) { + fDiffPainter.setDeletedColor(deletedColor); + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getModel() + */ + public IAnnotationModel getModel() { + return fAnnotationModel; + } + + /* + * @see IVerticalRulerColumn#getControl() + */ + public Control getControl() { + return fCanvas; + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfo#getWidth() + */ + public int getWidth() { + return fWidth; + } + + /** + * Triggers a redraw in the display thread. + */ + protected final void postRedraw() { + if (fCanvas !is null && !fCanvas.isDisposed()) { + Display d= fCanvas.getDisplay(); + if (d !is null) { + d.asyncExec(new class() Runnable { + public void run() { + redraw(); + } + }); + } + } + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#addVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener) + */ + public void addVerticalRulerListener(IVerticalRulerListener listener) { + throw new UnsupportedOperationException(); + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#removeVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener) + */ + public void removeVerticalRulerListener(IVerticalRulerListener listener) { + throw new UnsupportedOperationException(); + } + + /** + * Computes the document based line range visible in the text widget. + * + * @return the document based line range visible in the text widget + * @since 3.2 + */ + private final ILineRange computeVisibleModelLines() { + IDocument doc= fCachedTextViewer.getDocument(); + if (doc is null) + return null; + + int topLine; + IRegion coverage; + + if ( cast(ITextViewerExtension5)fCachedTextViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) fCachedTextViewer; + + // ITextViewer.getTopIndex returns the fully visible line, but we want the partially + // visible one + int widgetTopLine= JFaceTextUtil.getPartialTopIndex(fCachedTextWidget); + topLine= extension.widgetLine2ModelLine(widgetTopLine); + + coverage= extension.getModelCoverage(); + + } else { + topLine= JFaceTextUtil.getPartialTopIndex(fCachedTextViewer); + coverage= fCachedTextViewer.getVisibleRegion(); + } + + int bottomLine= fCachedTextViewer.getBottomIndex(); + if (bottomLine !is -1) + ++ bottomLine; + + // clip by coverage window + try { + int firstLine= doc.getLineOfOffset(coverage.getOffset()); + if (firstLine > topLine) + topLine= firstLine; + + int lastLine= doc.getLineOfOffset(coverage.getOffset() + coverage.getLength()); + if (lastLine < bottomLine || bottomLine is -1) + bottomLine= lastLine; + } catch (BadLocationException x) { + ExceptionPrintStackTrace(x); + return null; + } + + ILineRange visibleModelLines= new LineRange(topLine, bottomLine - topLine + 1); + return visibleModelLines; + } + + /* + * @see dwtx.jface.text.revisions.IRevisionRulerColumn#setRevisionInformation(dwtx.jface.text.revisions.RevisionInformation) + */ + public void setRevisionInformation(RevisionInformation info) { + fRevisionPainter.setRevisionInformation(info); + fRevisionPainter.setBackground(getBackground()); + } + + /** + * Returns the revision selection provider. + * + * @return the revision selection provider + * @since 3.2 + */ + public ISelectionProvider getRevisionSelectionProvider() { + return fRevisionPainter.getRevisionSelectionProvider(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/CompositeRuler.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/CompositeRuler.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,942 @@ +/******************************************************************************* + * 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 + * 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.text.source.CompositeRuler; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; + +import dwt.DWT; +import dwt.custom.StyledText; +import dwt.events.ControlListener; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.events.FocusListener; +import dwt.events.HelpListener; +import dwt.events.KeyListener; +import dwt.events.MouseListener; +import dwt.events.MouseMoveListener; +import dwt.events.MouseTrackListener; +import dwt.events.PaintListener; +import dwt.events.TraverseListener; +import dwt.graphics.Font; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Canvas; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Layout; +import dwt.widgets.Listener; +import dwt.widgets.Menu; +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.ITextViewerExtension; +import dwtx.jface.text.ITextViewerExtension5; + + +/** + * Standard implementation of + * {@link dwtx.jface.text.source.IVerticalRuler}. + *

                    + * This ruler does not have a a visual representation of its own. The + * presentation comes from the configurable list of vertical ruler columns. Such + * columns must implement the + * {@link dwtx.jface.text.source.IVerticalRulerColumn}. interface.

                    + *

                    + * Clients may instantiate and configure this class.

                    + * + * @see dwtx.jface.text.source.IVerticalRulerColumn + * @see dwtx.jface.text.ITextViewer + * @since 2.0 + */ +public class CompositeRuler : IVerticalRuler, IVerticalRulerExtension, IVerticalRulerInfoExtension { + + + /** + * Layout of the composite vertical ruler. Arranges the list of columns. + */ + class RulerLayout : Layout { + + /** + * Creates the new ruler layout. + */ + protected this() { + } + + /* + * @see Layout#computeSize(Composite, int, int, bool) + */ + protected Point computeSize(Composite composite, int wHint, int hHint, bool flushCache) { + Control[] children= composite.getChildren(); + Point size= new Point(0, 0); + for (int i= 0; i < children.length; i++) { + Point s= children[i].computeSize(DWT.DEFAULT, DWT.DEFAULT, flushCache); + size.x += s.x; + size.y= Math.max(size.y, s.y); + } + size.x += (Math.max(0, children.length -1) * fGap); + return size; + } + + /* + * @see Layout#layout(Composite, bool) + */ + protected void layout(Composite composite, bool flushCache) { + Rectangle clArea= composite.getClientArea(); + int rulerHeight= clArea.height; + + int x= 0; + Iterator e= fDecorators.iterator(); + while (e.hasNext()) { + IVerticalRulerColumn column= cast(IVerticalRulerColumn) e.next(); + int columnWidth= column.getWidth(); + column.getControl().setBounds(x, 0, columnWidth, rulerHeight); + x += (columnWidth + fGap); + } + } + } + + /** + * A canvas that adds listeners to all its children. Used by the implementation of the + * vertical ruler to propagate listener additions and removals to the ruler's columns. + */ + static class CompositeRulerCanvas : Canvas { + + /** + * Keeps the information for which event type a listener object has been added. + */ + static class ListenerInfo { + ClassInfo fClass; + EventListener fListener; + } + + /** The list of listeners added to this canvas. */ + private List fCachedListeners; + /** + * Internal listener for opening the context menu. + * @since 3.0 + */ + private Listener fMenuDetectListener; + + /** + * Creates a new composite ruler canvas. + * + * @param parent the parent composite + * @param style the DWT styles + */ + public this(Composite parent, int style) { + fCachedListeners= new ArrayList(); + + super(parent, style); + fMenuDetectListener= new class() Listener { + public void handleEvent(Event event) { + if (event.type is DWT.MenuDetect) { + Menu menu= getMenu(); + if (menu !is null) { + menu.setLocation(event.x, event.y); + menu.setVisible(true); + } + } + } + }; + super.addDisposeListener(new class() DisposeListener { + public void widgetDisposed(DisposeEvent e) { + if (fCachedListeners !is null) { + fCachedListeners.clear(); + fCachedListeners= null; + } + } + }); + } + + /** + * Adds the given listener object as listener of the given type (clazz) to + * the given control. + * + * @param clazz the listener type + * @param control the control to add the listener to + * @param listener the listener to be added + */ + private void addListener(ClassInfo clazz, Control control, EventListener listener) { + if (ControlListener.classinfo.opEquals(clazz)) { + control. addControlListener(cast(ControlListener) listener); + return; + } + if (FocusListener.classinfo.opEquals(clazz)) { + control. addFocusListener(cast(FocusListener) listener); + return; + } + if (HelpListener.classinfo.opEquals(clazz)) { + control. addHelpListener(cast(HelpListener) listener); + return; + } + if (KeyListener.classinfo.opEquals(clazz)) { + control. addKeyListener(cast(KeyListener) listener); + return; + } + if (MouseListener.classinfo.opEquals(clazz)) { + control. addMouseListener(cast(MouseListener) listener); + return; + } + if (MouseMoveListener.classinfo.opEquals(clazz)) { + control. addMouseMoveListener(cast(MouseMoveListener) listener); + return; + } + if (MouseTrackListener.classinfo.opEquals(clazz)) { + control. addMouseTrackListener(cast(MouseTrackListener) listener); + return; + } + if (PaintListener.classinfo.opEquals(clazz)) { + control. addPaintListener(cast(PaintListener) listener); + return; + } + if (TraverseListener.classinfo.opEquals(clazz)) { + control. addTraverseListener(cast(TraverseListener) listener); + return; + } + if (DisposeListener.classinfo.opEquals(clazz)) { + control. addDisposeListener(cast(DisposeListener) listener); + return; + } + } + + /** + * Removes the given listener object as listener of the given type (clazz) from + * the given control. + * + * @param clazz the listener type + * @param control the control to remove the listener from + * @param listener the listener to be removed + */ + private void removeListener(ClassInfo clazz, Control control, EventListener listener) { + if (ControlListener.classinfo.opEquals(clazz)) { + control. removeControlListener(cast(ControlListener) listener); + return; + } + if (FocusListener.classinfo.opEquals(clazz)) { + control. removeFocusListener(cast(FocusListener) listener); + return; + } + if (HelpListener.classinfo.opEquals(clazz)) { + control. removeHelpListener(cast(HelpListener) listener); + return; + } + if (KeyListener.classinfo.opEquals(clazz)) { + control. removeKeyListener(cast(KeyListener) listener); + return; + } + if (MouseListener.classinfo.opEquals(clazz)) { + control. removeMouseListener(cast(MouseListener) listener); + return; + } + if (MouseMoveListener.classinfo.opEquals(clazz)) { + control. removeMouseMoveListener(cast(MouseMoveListener) listener); + return; + } + if (MouseTrackListener.classinfo.opEquals(clazz)) { + control. removeMouseTrackListener(cast(MouseTrackListener) listener); + return; + } + if (PaintListener.classinfo.opEquals(clazz)) { + control. removePaintListener(cast(PaintListener) listener); + return; + } + if (TraverseListener.classinfo.opEquals(clazz)) { + control. removeTraverseListener(cast(TraverseListener) listener); + return; + } + if (DisposeListener.classinfo.opEquals(clazz)) { + control. removeDisposeListener(cast(DisposeListener) listener); + return; + } + } + + /** + * Adds the given listener object to the internal book keeping under + * the given listener type (clazz). + * + * @param clazz the listener type + * @param listener the listener object + */ + private void addListener(ClassInfo clazz, EventListener listener) { + Control[] children= getChildren(); + for (int i= 0; i < children.length; i++) { + if (children[i] !is null && !children[i].isDisposed()) + addListener(clazz, children[i], listener); + } + + ListenerInfo info= new ListenerInfo(); + info.fClass= clazz; + info.fListener= listener; + fCachedListeners.add(info); + } + + /** + * Removes the given listener object from the internal book keeping under + * the given listener type (clazz). + * + * @param clazz the listener type + * @param listener the listener object + */ + private void removeListener(ClassInfo clazz, EventListener listener) { + int length= fCachedListeners.size(); + for (int i= 0; i < length; i++) { + ListenerInfo info= cast(ListenerInfo) fCachedListeners.get(i); + if (listener is info.fListener && clazz.opEquals(info.fClass)) { + fCachedListeners.remove(i); + break; + } + } + + Control[] children= getChildren(); + for (int i= 0; i < children.length; i++) { + if (children[i] !is null && !children[i].isDisposed()) + removeListener(clazz, children[i], listener); + } + } + + /** + * Tells this canvas that a child has been added. + * + * @param child the child + */ + public void childAdded(Control child) { + if (child !is null && !child.isDisposed()) { + int length= fCachedListeners.size(); + for (int i= 0; i < length; i++) { + ListenerInfo info= cast(ListenerInfo) fCachedListeners.get(i); + addListener(info.fClass, child, info.fListener); + } + child.addListener(DWT.MenuDetect, fMenuDetectListener); + } + } + + /** + * Tells this canvas that a child has been removed. + * + * @param child the child + */ + public void childRemoved(Control child) { + if (child !is null && !child.isDisposed()) { + int length= fCachedListeners.size(); + for (int i= 0; i < length; i++) { + ListenerInfo info= cast(ListenerInfo) fCachedListeners.get(i); + removeListener(info.fClass, child, info.fListener); + } + child.removeListener(DWT.MenuDetect, fMenuDetectListener); + } + } + + /* + * @see Control#removeControlListener(ControlListener) + */ + public void removeControlListener(ControlListener listener) { + removeListener(ControlListener.classinfo, listener); + super.removeControlListener(listener); + } + + /* + * @see Control#removeFocusListener(FocusListener) + */ + public void removeFocusListener(FocusListener listener) { + removeListener(FocusListener.classinfo, listener); + super.removeFocusListener(listener); + } + + /* + * @see Control#removeHelpListener(HelpListener) + */ + public void removeHelpListener(HelpListener listener) { + removeListener(HelpListener.classinfo, listener); + super.removeHelpListener(listener); + } + + /* + * @see Control#removeKeyListener(KeyListener) + */ + public void removeKeyListener(KeyListener listener) { + removeListener(KeyListener.classinfo, listener); + super.removeKeyListener(listener); + } + + /* + * @see Control#removeMouseListener(MouseListener) + */ + public void removeMouseListener(MouseListener listener) { + removeListener(MouseListener.classinfo, listener); + super.removeMouseListener(listener); + } + + /* + * @see Control#removeMouseMoveListener(MouseMoveListener) + */ + public void removeMouseMoveListener(MouseMoveListener listener) { + removeListener(MouseMoveListener.classinfo, listener); + super.removeMouseMoveListener(listener); + } + + /* + * @see Control#removeMouseTrackListener(MouseTrackListener) + */ + public void removeMouseTrackListener(MouseTrackListener listener) { + removeListener(MouseTrackListener.classinfo, listener); + super.removeMouseTrackListener(listener); + } + + /* + * @see Control#removePaintListener(PaintListener) + */ + public void removePaintListener(PaintListener listener) { + removeListener(PaintListener.classinfo, listener); + super.removePaintListener(listener); + } + + /* + * @see Control#removeTraverseListener(TraverseListener) + */ + public void removeTraverseListener(TraverseListener listener) { + removeListener(TraverseListener.classinfo, listener); + super.removeTraverseListener(listener); + } + + /* + * @see Widget#removeDisposeListener(DisposeListener) + */ + public void removeDisposeListener(DisposeListener listener) { + removeListener(DisposeListener.classinfo, listener); + super.removeDisposeListener(listener); + } + + /* + * @seeControl#addControlListener(ControlListener) + */ + public void addControlListener(ControlListener listener) { + super.addControlListener(listener); + addListener(ControlListener.classinfo, listener); + } + + /* + * @see Control#addFocusListener(FocusListener) + */ + public void addFocusListener(FocusListener listener) { + super.addFocusListener(listener); + addListener(FocusListener.classinfo, listener); + } + + /* + * @see Control#addHelpListener(HelpListener) + */ + public void addHelpListener(HelpListener listener) { + super.addHelpListener(listener); + addListener(HelpListener.classinfo, listener); + } + + /* + * @see Control#addKeyListener(KeyListener) + */ + public void addKeyListener(KeyListener listener) { + super.addKeyListener(listener); + addListener(KeyListener.classinfo, listener); + } + + /* + * @see Control#addMouseListener(MouseListener) + */ + public void addMouseListener(MouseListener listener) { + super.addMouseListener(listener); + addListener(MouseListener.classinfo, listener); + } + + /* + * @see Control#addMouseMoveListener(MouseMoveListener) + */ + public void addMouseMoveListener(MouseMoveListener listener) { + super.addMouseMoveListener(listener); + addListener(MouseMoveListener.classinfo, listener); + } + + /* + * @see Control#addMouseTrackListener(MouseTrackListener) + */ + public void addMouseTrackListener(MouseTrackListener listener) { + super.addMouseTrackListener(listener); + addListener(MouseTrackListener.classinfo, listener); + } + + /* + * @seeControl#addPaintListener(PaintListener) + */ + public void addPaintListener(PaintListener listener) { + super.addPaintListener(listener); + addListener(PaintListener.classinfo, listener); + } + + /* + * @see Control#addTraverseListener(TraverseListener) + */ + public void addTraverseListener(TraverseListener listener) { + super.addTraverseListener(listener); + addListener(TraverseListener.classinfo, listener); + } + + /* + * @see Widget#addDisposeListener(DisposeListener) + */ + public void addDisposeListener(DisposeListener listener) { + super.addDisposeListener(listener); + addListener(DisposeListener.classinfo, listener); + } + } + + /** The ruler's viewer */ + private ITextViewer fTextViewer; + /** The ruler's canvas to which to add the ruler columns */ + private CompositeRulerCanvas fComposite; + /** The ruler's annotation model */ + private IAnnotationModel fModel; + /** The list of columns */ + private List fDecorators; + /** The cached location of the last mouse button activity */ + private Point fLocation; + /** The cached line of the list mouse button activity */ + private int fLastMouseButtonActivityLine= -1; + /** The gap between the individual columns of this composite ruler */ + private int fGap; + /** + * The set of annotation listeners. + * @since 3.0 + */ + private Set fAnnotationListeners; + + + /** + * Constructs a new composite vertical ruler. + */ + public this() { + this(0); + } + + /** + * Constructs a new composite ruler with the given gap between its columns. + * + * @param gap + */ + public this(int gap) { + fDecorators= new ArrayList(2); + fLocation= new Point(-1, -1); + fAnnotationListeners= new HashSet(); + + fGap= gap; + } + + /** + * Inserts the given column at the specified slot to this composite ruler. + * Columns are counted from left to right. + * + * @param index the index + * @param rulerColumn the decorator to be inserted + */ + public void addDecorator(int index, IVerticalRulerColumn rulerColumn) { + rulerColumn.setModel(getModel()); + + if (index > fDecorators.size()) + fDecorators.add(cast(Object)rulerColumn); + else + fDecorators.add(index, cast(Object)rulerColumn); + + if (fComposite !is null && !fComposite.isDisposed()) { + rulerColumn.createControl(this, fComposite); + fComposite.childAdded(rulerColumn.getControl()); + layoutTextViewer(); + } + } + + /** + * Removes the decorator in the specified slot from this composite ruler. + * + * @param index the index + */ + public void removeDecorator(int index) { + IVerticalRulerColumn rulerColumn= cast(IVerticalRulerColumn) fDecorators.get(index); + removeDecorator(rulerColumn); + } + + /** + * Removes the given decorator from the composite ruler. + * + * @param rulerColumn the ruler column to be removed + * @since 3.0 + */ + public void removeDecorator(IVerticalRulerColumn rulerColumn) { + fDecorators.remove(cast(Object)rulerColumn); + if (rulerColumn !is null) { + Control cc= rulerColumn.getControl(); + if (cc !is null && !cc.isDisposed()) { + fComposite.childRemoved(cc); + cc.dispose(); + } + } + layoutTextViewer(); + } + + /** + * Layouts the text viewer. This also causes this ruler to get + * be layouted. + */ + private void layoutTextViewer() { + + Control parent= fTextViewer.getTextWidget(); + + if ( cast(ITextViewerExtension)fTextViewer ) { + ITextViewerExtension extension= cast(ITextViewerExtension) fTextViewer; + parent= extension.getControl(); + } + + if ( cast(Composite)parent && !parent.isDisposed()) + (cast(Composite) parent).layout(true); + } + + /* + * @see IVerticalRuler#getControl() + */ + public Control getControl() { + return fComposite; + } + + /* + * @see IVerticalRuler#createControl(Composite, ITextViewer) + */ + public Control createControl(Composite parent, ITextViewer textViewer) { + + fTextViewer= textViewer; + + fComposite= new CompositeRulerCanvas(parent, DWT.NONE); + fComposite.setLayout(new RulerLayout()); + + Iterator iter= fDecorators.iterator(); + while (iter.hasNext()) { + IVerticalRulerColumn column= cast(IVerticalRulerColumn) iter.next(); + column.createControl(this, fComposite); + fComposite.childAdded(column.getControl()); + } + + return fComposite; + } + + /* + * @see IVerticalRuler#setModel(IAnnotationModel) + */ + public void setModel(IAnnotationModel model) { + + fModel= model; + + Iterator e= fDecorators.iterator(); + while (e.hasNext()) { + IVerticalRulerColumn column= cast(IVerticalRulerColumn) e.next(); + column.setModel(model); + } + } + + /* + * @see IVerticalRuler#getModel() + */ + public IAnnotationModel getModel() { + return fModel; + } + + /* + * @see IVerticalRuler#update() + */ + public void update() { + if (fComposite !is null && !fComposite.isDisposed()) { + Display d= fComposite.getDisplay(); + if (d !is null) { + d.asyncExec(new class() Runnable { + public void run() { + immediateUpdate(); + } + }); + } + } + } + + /** + * Immediately redraws the entire ruler (without asynchronous posting). + * + * @since 3.2 + */ + public void immediateUpdate() { + Iterator e= fDecorators.iterator(); + while (e.hasNext()) { + IVerticalRulerColumn column= cast(IVerticalRulerColumn) e.next(); + column.redraw(); + } + } + + /* + * @see IVerticalRulerExtension#setFont(Font) + */ + public void setFont(Font font) { + Iterator e= fDecorators.iterator(); + while (e.hasNext()) { + IVerticalRulerColumn column= cast(IVerticalRulerColumn) e.next(); + column.setFont(font); + } + } + + /* + * @see IVerticalRulerInfo#getWidth() + */ + public int getWidth() { + int width= 0; + Iterator e= fDecorators.iterator(); + while (e.hasNext()) { + IVerticalRulerColumn column= cast(IVerticalRulerColumn) e.next(); + width += (column.getWidth() + fGap); + } + return Math.max(0, width - fGap); + } + + /* + * @see IVerticalRulerInfo#getLineOfLastMouseButtonActivity() + */ + public int getLineOfLastMouseButtonActivity() { + if (fLastMouseButtonActivityLine is -1) + fLastMouseButtonActivityLine= toDocumentLineNumber(fLocation.y); + else if (fTextViewer.getDocument() is null || fLastMouseButtonActivityLine >= fTextViewer.getDocument().getNumberOfLines()) + fLastMouseButtonActivityLine= -1; + return fLastMouseButtonActivityLine; + } + + /* + * @see IVerticalRulerInfo#toDocumentLineNumber(int) + */ + public int toDocumentLineNumber(int y_coordinate) { + if (fTextViewer is null || y_coordinate is -1) + return -1; + + StyledText text= fTextViewer.getTextWidget(); + int line= text.getLineIndex(y_coordinate); + + if (line is text.getLineCount() - 1) { + // check whether y_coordinate exceeds last line + if (y_coordinate > text.getLinePixel(line + 1)) + return -1; + } + + return widgetLine2ModelLine(fTextViewer, line); + } + + /** + * Returns the line in the given viewer's document that correspond to the given + * line of the viewer's widget. + * + * @param viewer the viewer + * @param widgetLine the widget line + * @return the corresponding line the viewer's document + * @since 2.1 + */ + protected final static int widgetLine2ModelLine(ITextViewer viewer, int widgetLine) { + + if ( cast(ITextViewerExtension5)viewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) viewer; + return extension.widgetLine2ModelLine(widgetLine); + } + + try { + IRegion r= viewer.getVisibleRegion(); + IDocument d= viewer.getDocument(); + return widgetLine += d.getLineOfOffset(r.getOffset()); + } catch (BadLocationException x) { + } + return widgetLine; + } + + /** + * Returns this ruler's text viewer. + * + * @return this ruler's text viewer + */ + public ITextViewer getTextViewer() { + return fTextViewer; + } + + /* + * @see IVerticalRulerExtension#setLocationOfLastMouseButtonActivity(int, int) + */ + public void setLocationOfLastMouseButtonActivity(int x, int y) { + fLocation.x= x; + fLocation.y= y; + fLastMouseButtonActivityLine= -1; + } + + /** + * Returns an iterator over the IVerticalRulerColumns that make up this + * composite column. + * + * @return an iterator over the contained columns. + * @since 3.0 + */ + public Iterator getDecoratorIterator() { + Assert.isNotNull(cast(Object)fDecorators, "fDecorators must be initialized"); //$NON-NLS-1$ + return fDecorators.iterator(); + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getHover() + * @since 3.0 + */ + public IAnnotationHover getHover() { + return null; + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#addVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener) + * @since 3.0 + */ + public void addVerticalRulerListener(IVerticalRulerListener listener) { + fAnnotationListeners.add(cast(Object)listener); + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#removeVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener) + * @since 3.0 + */ + public void removeVerticalRulerListener(IVerticalRulerListener listener) { + fAnnotationListeners.remove(cast(Object)listener); + } + + /** + * Fires the annotation selected event to all registered vertical ruler + * listeners. + * TODO use robust iterators + * + * @param event the event to fire + * @since 3.0 + */ + public void fireAnnotationSelected(VerticalRulerEvent event) { + // forward to listeners + for (Iterator it= fAnnotationListeners.iterator(); it.hasNext();) { + IVerticalRulerListener listener= cast(IVerticalRulerListener) it.next(); + listener.annotationSelected(event); + } + } + + /** + * Fires the annotation default selected event to all registered vertical + * ruler listeners. + * TODO use robust iterators + * + * @param event the event to fire + * @since 3.0 + */ + public void fireAnnotationDefaultSelected(VerticalRulerEvent event) { + // forward to listeners + for (Iterator it= fAnnotationListeners.iterator(); it.hasNext();) { + IVerticalRulerListener listener= cast(IVerticalRulerListener) it.next(); + listener.annotationDefaultSelected(event); + } + } + + /** + * Informs all registered vertical ruler listeners that the content menu on a selected annotation\ + * is about to be shown. + * TODO use robust iterators + * + * @param event the event to fire + * @param menu the menu that is about to be shown + * @since 3.0 + */ + public void fireAnnotationContextMenuAboutToShow(VerticalRulerEvent event, Menu menu) { + // forward to listeners + for (Iterator it= fAnnotationListeners.iterator(); it.hasNext();) { + IVerticalRulerListener listener= cast(IVerticalRulerListener) it.next(); + listener.annotationContextMenuAboutToShow(event, menu); + } + } + + /** + * Relayouts the receiver. + * + * @since 3.3 + */ + public void relayout() { + layoutTextViewer(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/ContentAssistantFacade.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/ContentAssistantFacade.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,157 @@ +/******************************************************************************* + * 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.text.source.ContentAssistantFacade; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + + +import dwtx.core.commands.IHandler; +import dwtx.core.runtime.Assert; +import dwtx.jface.text.contentassist.ICompletionListener; +import dwtx.jface.text.contentassist.IContentAssistant; +import dwtx.jface.text.contentassist.IContentAssistantExtension2; +import dwtx.jface.text.contentassist.IContentAssistantExtension4; + + +/** + * Facade to allow minimal access to the given content assistant. + *

                    + * The offered API access can grow over time. + *

                    + * + * @since 3.4 + */ +public final class ContentAssistantFacade { + + private IContentAssistant fContentAssistant; + + /** + * Creates a new facade. + * + * @param contentAssistant the content assistant which implements {@link IContentAssistantExtension2} and {@link IContentAssistantExtension4} + */ + public this(IContentAssistant contentAssistant) { + Assert.isLegal(cast(IContentAssistantExtension4)contentAssistant && cast(IContentAssistantExtension4)contentAssistant ); + fContentAssistant= contentAssistant; + } + + /** + * Returns the handler for the given command identifier. + *

                    + * The same handler instance will be returned when called a more than once + * with the same command identifier. + *

                    + * + * @param commandId the command identifier + * @return the handler for the given command identifier + * @throws IllegalArgumentException if the command is not supported by this + * content assistant + * @throws IllegalStateException if called when the content assistant is + * uninstalled + */ + public IHandler getHandler(String commandId) { + if (fContentAssistant is null) + throw new IllegalStateException(); + return (cast(IContentAssistantExtension4)fContentAssistant).getHandler(commandId); + } + + /** + * Adds a completion listener that will be informed before proposals are + * computed. + * + * @param listener the listener + * @throws IllegalStateException if called when the content assistant is + * uninstalled + */ + public void addCompletionListener(ICompletionListener listener) { + if (fContentAssistant is null) + throw new IllegalStateException(); + (cast(IContentAssistantExtension2)fContentAssistant).addCompletionListener(listener); + } + + /** + * Removes a completion listener. + * + * @param listener the listener to remove + * @throws IllegalStateException if called when the content assistant is + * uninstalled + */ + public void removeCompletionListener(ICompletionListener listener) { + (cast(IContentAssistantExtension2)fContentAssistant).removeCompletionListener(listener); + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/DefaultAnnotationHover.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/DefaultAnnotationHover.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,302 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.text.source.DefaultAnnotationHover; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + + + +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.Position; +import dwtx.jface.text.source.projection.AnnotationBag; + +/** + * Standard implementation of {@link dwtx.jface.text.source.IAnnotationHover}. + * + * @since 3.2 + */ +public class DefaultAnnotationHover : IAnnotationHover { + + + /** + * Tells whether the line number should be shown when no annotation is found + * under the cursor. + * + * @since 3.4 + */ + private bool fShowLineNumber; + + /** + * Creates a new default annotation hover. + * + * @since 3.4 + */ + public this() { + this(false); + } + + /** + * Creates a new default annotation hover. + * + * @param showLineNumber true if the line number should be shown when no annotation is found + * @since 3.4 + */ + public this(bool showLineNumber) { + fShowLineNumber= showLineNumber; + } + + /* + * @see dwtx.jface.text.source.IAnnotationHover#getHoverInfo(dwtx.jface.text.source.ISourceViewer, int) + */ + public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) { + List javaAnnotations= getAnnotationsForLine(sourceViewer, lineNumber); + if (javaAnnotations !is null) { + + if (javaAnnotations.size() is 1) { + + // optimization + Annotation annotation= cast(Annotation) javaAnnotations.get(0); + String message= annotation.getText(); + if (message !is null && message.trim().length() > 0) + return formatSingleMessage(message); + + } else { + + List messages= new ArrayList(); + + Iterator e= javaAnnotations.iterator(); + while (e.hasNext()) { + Annotation annotation= cast(Annotation) e.next(); + String message= annotation.getText(); + if (message !is null && message.trim().length() > 0) + messages.add(message.trim()); + } + + if (messages.size() is 1) + return formatSingleMessage(stringcast(messages.get(0))); + + if (messages.size() > 1) + return formatMultipleMessages(messages); + } + } + + if (fShowLineNumber && lineNumber > -1) + return JFaceTextMessages.getFormattedString("DefaultAnnotationHover.lineNumber", stringcast(Integer.toString(lineNumber + 1)) ); //$NON-NLS-1$ + + return null; + } + + /** + * Tells whether the annotation should be included in + * the computation. + * + * @param annotation the annotation to test + * @return true if the annotation is included in the computation + */ + protected bool isIncluded(Annotation annotation) { + return true; + } + + /** + * Hook method to format the given single message. + *

                    + * Subclasses can change this to create a different + * format like HTML. + *

                    + * + * @param message the message to format + * @return the formatted message + */ + protected String formatSingleMessage(String message) { + return message; + } + + /** + * Hook method to formats the given messages. + *

                    + * Subclasses can change this to create a different + * format like HTML. + *

                    + * + * @param messages the messages to format + * @return the formatted message + */ + protected String formatMultipleMessages(List messages) { + StringBuffer buffer= new StringBuffer(); + buffer.append(JFaceTextMessages.getString("DefaultAnnotationHover.multipleMarkers")); //$NON-NLS-1$ + + Iterator e= messages.iterator(); + while (e.hasNext()) { + buffer.append('\n'); + String listItemText= stringcast( e.next()); + buffer.append(JFaceTextMessages.getFormattedString("DefaultAnnotationHover.listItem", stringcast(listItemText ))); //$NON-NLS-1$ + } + return buffer.toString(); + } + + private bool isRulerLine(Position position, IDocument document, int line) { + if (position.getOffset() > -1 && position.getLength() > -1) { + try { + return line is document.getLineOfOffset(position.getOffset()); + } catch (BadLocationException x) { + } + } + return false; + } + + private IAnnotationModel getAnnotationModel(ISourceViewer viewer) { + if ( cast(ISourceViewerExtension2)viewer ) { + ISourceViewerExtension2 extension= cast(ISourceViewerExtension2) viewer; + return extension.getVisualAnnotationModel(); + } + return viewer.getAnnotationModel(); + } + + private bool isDuplicateAnnotation(Map messagesAtPosition, Position position, String message) { + if (messagesAtPosition.containsKey(position)) { + Object value= messagesAtPosition.get(position); + if (message==/++/stringcast(value)) + return true; + + if ( cast(List)value ) { + List messages= cast(List)value; + if (messages.contains(message)) + return true; + + messages.add(message); + } else { + ArrayList messages= new ArrayList(); + messages.add(value); + messages.add(message); + messagesAtPosition.put(position, messages); + } + } else + messagesAtPosition.put(position, message); + return false; + } + + private bool includeAnnotation(Annotation annotation, Position position, HashMap messagesAtPosition) { + if (!isIncluded(annotation)) + return false; + + String text= annotation.getText(); + return (text !is null && !isDuplicateAnnotation(messagesAtPosition, position, text)); + } + + private List getAnnotationsForLine(ISourceViewer viewer, int line) { + IAnnotationModel model= getAnnotationModel(viewer); + if (model is null) + return null; + + IDocument document= viewer.getDocument(); + List javaAnnotations= new ArrayList(); + HashMap messagesAtPosition= new HashMap(); + Iterator iterator= model.getAnnotationIterator(); + + while (iterator.hasNext()) { + Annotation annotation= cast(Annotation) iterator.next(); + + Position position= model.getPosition(annotation); + if (position is null) + continue; + + if (!isRulerLine(position, document, line)) + continue; + + if ( cast(AnnotationBag)annotation ) { + AnnotationBag bag= cast(AnnotationBag) annotation; + Iterator e= bag.iterator(); + while (e.hasNext()) { + annotation= cast(Annotation) e.next(); + position= model.getPosition(annotation); + if (position !is null && includeAnnotation(annotation, position, messagesAtPosition)) + javaAnnotations.add(annotation); + } + continue; + } + + if (includeAnnotation(annotation, position, messagesAtPosition)) + javaAnnotations.add(annotation); + } + + return javaAnnotations; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/DefaultCharacterPairMatcher.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/DefaultCharacterPairMatcher.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,423 @@ +/******************************************************************************* + * 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: + * Christian Plesner Hansen (plesner@quenta.org) - initial API and implementation + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.text.source.DefaultCharacterPairMatcher; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentExtension3; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITypedRegion; +import dwtx.jface.text.Region; +import dwtx.jface.text.TextUtilities; + +/** + * A character pair matcher that matches a specified set of character + * pairs against each other. Only characters that occur in the same + * partitioning are matched. + * + * @since 3.3 + */ +public class DefaultCharacterPairMatcher : ICharacterPairMatcher { + + private int fAnchor= -1; + private const CharPairs fPairs; + private const String fPartitioning; + + /** + * Creates a new character pair matcher that matches the specified + * characters within the specified partitioning. The specified + * list of characters must have the form + *
                    { start, end, start, end, ..., start, end }
                    + * For instance: + *
                    +     * char[] chars = new char[] {'(', ')', '{', '}', '[', ']'};
                    +     * new SimpleCharacterPairMatcher(chars, ...);
                    +     * 
                    + * + * @param chars a list of characters + * @param partitioning the partitioning to match within + */ + public this(char[] chars, String partitioning) { + Assert.isLegal(chars.length % 2 is 0); + Assert.isNotNull(partitioning); + fPairs= new CharPairs(chars); + fPartitioning= partitioning; + } + + /** + * Creates a new character pair matcher that matches characters + * within the default partitioning. The specified list of + * characters must have the form + *
                    { start, end, start, end, ..., start, end }
                    + * For instance: + *
                    +     * char[] chars = new char[] {'(', ')', '{', '}', '[', ']'};
                    +     * new SimpleCharacterPairMatcher(chars);
                    +     * 
                    + * + * @param chars a list of characters + */ + public this(char[] chars) { + this(chars, IDocumentExtension3.DEFAULT_PARTITIONING); + } + + /* @see ICharacterPairMatcher#match(IDocument, int) */ + public IRegion match(IDocument doc, int offset) { + if (doc is null || offset < 0 || offset > doc.getLength()) return null; + try { + return performMatch(doc, offset); + } catch (BadLocationException ble) { + return null; + } + } + + /* + * Performs the actual work of matching for #match(IDocument, int). + */ + private IRegion performMatch(IDocument doc, int caretOffset) { + final int charOffset= caretOffset - 1; + final char prevChar= doc.getChar(Math.max(charOffset, 0)); + if (!fPairs.contains(prevChar)) return null; + final bool isForward= fPairs.isStartCharacter(prevChar); + fAnchor= isForward ? ICharacterPairMatcher.LEFT : ICharacterPairMatcher.RIGHT; + final int searchStartPosition= isForward ? caretOffset : caretOffset - 2; + final int adjustedOffset= isForward ? charOffset : caretOffset; + final String partition= TextUtilities.getContentType(doc, fPartitioning, charOffset, false); + final DocumentPartitionAccessor partDoc= new DocumentPartitionAccessor(doc, fPartitioning, partition); + int endOffset= findMatchingPeer(partDoc, prevChar, fPairs.getMatching(prevChar), + isForward, isForward ? doc.getLength() : -1, + searchStartPosition); + if (endOffset is -1) return null; + final int adjustedEndOffset= isForward ? endOffset + 1: endOffset; + if (adjustedEndOffset is adjustedOffset) return null; + return new Region(Math.min(adjustedOffset, adjustedEndOffset), + Math.abs(adjustedEndOffset - adjustedOffset)); + } + + /** + * Searches doc for the specified end character, end. + * + * @param doc the document to search + * @param start the opening matching character + * @param end the end character to search for + * @param searchForward search forwards or backwards? + * @param boundary a boundary at which the search should stop + * @param startPos the start offset + * @return the index of the end character if it was found, otherwise -1 + * @throws BadLocationException + */ + private int findMatchingPeer(DocumentPartitionAccessor doc, char start, char end, bool searchForward, int boundary, int startPos) { + int pos= startPos; + while (pos !is boundary) { + final char c= doc.getChar(pos); + if (doc.isMatch(pos, end)) { + return pos; + } else if (c is start && doc.inPartition(pos)) { + pos= findMatchingPeer(doc, start, end, searchForward, boundary, + doc.getNextPosition(pos, searchForward)); + if (pos is -1) return -1; + } + pos= doc.getNextPosition(pos, searchForward); + } + return -1; + } + + /* @see ICharacterPairMatcher#getAnchor() */ + public int getAnchor() { + return fAnchor; + } + + /* @see ICharacterPairMatcher#dispose() */ + public void dispose() { } + + /* @see ICharacterPairMatcher#clear() */ + public void clear() { + fAnchor= -1; + } + + /** + * Utility class that wraps a document and gives access to + * partitioning information. A document is tied to a particular + * partition and, when considering whether or not a position is a + * valid match, only considers position within its partition. + */ + private static class DocumentPartitionAccessor { + + private const IDocument fDocument; + private const String fPartitioning, fPartition; + private ITypedRegion fCachedPartition; + + /** + * Creates a new partitioned document for the specified document. + * + * @param doc the document to wrap + * @param partitioning the partitioning used + * @param partition the partition managed by this document + */ + public this(IDocument doc, String partitioning, + String partition) { + fDocument= doc; + fPartitioning= partitioning; + fPartition= partition; + } + + /** + * Returns the character at the specified position in this document. + * + * @param pos an offset within this document + * @return the character at the offset + * @throws BadLocationException + */ + public char getChar(int pos) { + return fDocument.getChar(pos); + } + + /** + * Returns true if the character at the specified position is a + * valid match for the specified end character. To be a valid + * match, it must be in the appropriate partition and equal to the + * end character. + * + * @param pos an offset within this document + * @param end the end character to match against + * @return true exactly if the position represents a valid match + * @throws BadLocationException + */ + public bool isMatch(int pos, char end) { + return getChar(pos) is end && inPartition(pos); + } + + /** + * Returns true if the specified offset is within the partition + * managed by this document. + * + * @param pos an offset within this document + * @return true if the offset is within this document's partition + */ + public bool inPartition(int pos) { + final ITypedRegion partition= getPartition(pos); + return partition !is null && partition.getType().equals(fPartition); + } + + /** + * Returns the next position to query in the search. The position + * is not guaranteed to be in this document's partition. + * + * @param pos an offset within the document + * @param searchForward the direction of the search + * @return the next position to query + */ + public int getNextPosition(int pos, bool searchForward) { + final ITypedRegion partition= getPartition(pos); + if (partition is null) return simpleIncrement(pos, searchForward); + if (fPartition.equals(partition.getType())) + return simpleIncrement(pos, searchForward); + if (searchForward) { + int end= partition.getOffset() + partition.getLength(); + if (pos < end) + return end; + } else { + int offset= partition.getOffset(); + if (pos > offset) + return offset - 1; + } + return simpleIncrement(pos, searchForward); + } + + private int simpleIncrement(int pos, bool searchForward) { + return pos + (searchForward ? 1 : -1); + } + + /** + * Returns partition information about the region containing the + * specified position. + * + * @param pos a position within this document. + * @return positioning information about the region containing the + * position + */ + private ITypedRegion getPartition(int pos) { + if (fCachedPartition is null || !contains(fCachedPartition, pos)) { + Assert.isTrue(pos >= 0 && pos <= fDocument.getLength()); + try { + fCachedPartition= TextUtilities.getPartition(fDocument, fPartitioning, pos, false); + } catch (BadLocationException e) { + fCachedPartition= null; + } + } + return fCachedPartition; + } + + private static bool contains(IRegion region, int pos) { + int offset= region.getOffset(); + return offset <= pos && pos < offset + region.getLength(); + } + + } + + /** + * Utility class that encapsulates access to matching character pairs. + */ + private static class CharPairs { + + private const char[] fPairs; + + public this(char[] pairs) { + fPairs= pairs; + } + + /** + * Returns true if the specified character pair occurs in one + * of the character pairs. + * + * @param c a character + * @return true exactly if the character occurs in one of the pairs + */ + public bool contains(char c) { + return getAllCharacters().contains(new Character(c)); + } + + private Set/**/ fCharsCache= null; + /** + * @return A set containing all characters occurring in character pairs. + */ + private Set/**/ getAllCharacters() { + if (fCharsCache is null) { + Set/**/ set= new HashSet/**/(); + for (int i= 0; i < fPairs.length; i++) + set.add(new Character(fPairs[i])); + fCharsCache= set; + } + return fCharsCache; + } + + /** + * Returns true if the specified character opens a character pair + * when scanning in the specified direction. + * + * @param c a character + * @param searchForward the direction of the search + * @return whether or not the character opens a character pair + */ + public bool isOpeningCharacter(char c, bool searchForward) { + for (int i= 0; i < fPairs.length; i += 2) { + if (searchForward && getStartChar(i) is c) return true; + else if (!searchForward && getEndChar(i) is c) return true; + } + return false; + } + + /** + * Returns true of the specified character is a start character. + * + * @param c a character + * @return true exactly if the character is a start character + */ + public bool isStartCharacter(char c) { + return this.isOpeningCharacter(c, true); + } + + /** + * Returns the matching character for the specified character. + * + * @param c a character occurring in a character pair + * @return the matching character + */ + public char getMatching(char c) { + for (int i= 0; i < fPairs.length; i += 2) { + if (getStartChar(i) is c) return getEndChar(i); + else if (getEndChar(i) is c) return getStartChar(i); + } + Assert.isTrue(false); + return '\0'; + } + + private char getStartChar(int i) { + return fPairs[i]; + } + + private char getEndChar(int i) { + return fPairs[i + 1]; + } + + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IAnnotationAccess.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IAnnotationAccess.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,133 @@ +/******************************************************************************* + * 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 + * 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.text.source.IAnnotationAccess; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +/** + * An annotation access provides access to information that is not available via + * the API of {@link dwtx.jface.text.source.Annotation}. With version + * 3.0 all this information is now available from the annotation itself. + *

                    + * + * In order to provide backward compatibility for clients of + * IAnnotationAccess, extension interfaces are used as a means + * of evolution. The following extension interfaces exist: + *

                      + *
                    • {@link dwtx.jface.text.source.IAnnotationAccessExtension} since + * version 3.0 replacing all methods in that interface
                    • + *
                    • {@link IAnnotationAccessExtension2} since + * version 3.2 allowing to set a quick assist assistant to an annotation access.
                    • + *

                    + *

                    + * Clients usually implement this interface and its extension interfaces.

                    + * + * @see dwtx.jface.text.source.IAnnotationAccessExtension + * @see dwtx.jface.text.source.Annotation + * @since 2.1 + */ +public interface IAnnotationAccess { + + /** + * Returns the type of the given annotation. + * + * @param annotation the annotation + * @return the type of the given annotation or null if it has none. + * @deprecated use Annotation.getType() + */ + Object getType(Annotation annotation); + + /** + * Returns whether the given annotation spans multiple lines. + * + * @param annotation the annotation + * @return true if the annotation spans multiple lines, + * false otherwise + * + * @deprecated assumed to always return true + */ + bool isMultiLine(Annotation annotation); + + /** + * Returns whether the given annotation is temporary rather than persistent. + * + * @param annotation the annotation + * @return true if the annotation is temporary, + * false otherwise + * @deprecated use Annotation.isPersistent() + */ + bool isTemporary(Annotation annotation); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IAnnotationAccessExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IAnnotationAccessExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,168 @@ +/******************************************************************************* + * 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 + * 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.text.source.IAnnotationAccessExtension; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.graphics.GC; +import dwt.graphics.Rectangle; +import dwt.widgets.Canvas; + +/** + * Extension interface for {@link dwtx.jface.text.source.IAnnotationAccess}.

                    + * This interface replaces the methods of IAnnotationAccess.

                    + * This interface provides + *

                      + *
                    • a label for the annotation type of a given annotation
                    • + *
                    • the paint layer of a given annotation
                    • + *
                    • means to paint a given annotation
                    • + *
                    • information about the type hierarchy of the annotation type of a given annotation
                    • + *
                        . + * + * @see dwtx.jface.text.source.IAnnotationAccess + * @since 3.0 + */ +public interface IAnnotationAccessExtension { + + /** + * The default annotation layer. + */ + static const int DEFAULT_LAYER= IAnnotationPresentation.DEFAULT_LAYER; + + /** + * Returns the label for the given annotation's type. + * + * @param annotation the annotation + * @return the label the given annotation's type or null if no such label exists + */ + String getTypeLabel(Annotation annotation); + + /** + * Returns the layer for given annotation. Annotations are considered + * being located at layers and are considered being painted starting with + * layer 0 upwards. Thus an annotation at layer 5 will be drawn on top of + * all co-located annotations at the layers 4 - 0. + * + * @param annotation the annotation + * @return the layer of the given annotation + */ + int getLayer(Annotation annotation); + + /** + * Draws a graphical representation of the given annotation within the given bounds. + *

                        + * Note that this method is not used when drawing annotations on the editor's + * text widget. This is handled trough a {@link dwtx.jface.text.source.AnnotationPainter.IDrawingStrategy}. + *

                        + * @param annotation the given annotation + * @param gc the drawing GC + * @param canvas the canvas to draw on + * @param bounds the bounds inside the canvas to draw on + */ + void paint(Annotation annotation, GC gc, Canvas canvas, Rectangle bounds); + + /** + * Returns true if painting annotation will produce something + * meaningful, false if not. E.g. if no image is available. + *

                        + * Note that this method is not used when drawing annotations on the editor's + * text widget. This is handled trough a {@link dwtx.jface.text.source.AnnotationPainter.IDrawingStrategy}. + *

                        + * @param annotation the annotation to check whether it can be painted + * @return true if painting annotation will succeed + */ + bool isPaintable(Annotation annotation); + + /** + * Returns true if the given annotation is of the given type + * or false otherwise. + * + * @param annotationType the annotation type + * @param potentialSupertype the potential super annotation type + * @return true if annotation type is a sub-type of the potential annotation super type + */ + bool isSubtype(Object annotationType, Object potentialSupertype); + + /** + * Returns the list of super types for the given annotation type. This does not include the type + * itself. The index in the array of super types indicates the length of the path in the hierarchy + * graph to the given annotation type. + * + * @param annotationType the annotation type to check + * @return the super types for the given annotation type + */ + Object[] getSupertypes(Object annotationType); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IAnnotationAccessExtension2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IAnnotationAccessExtension2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,100 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.text.source.IAnnotationAccessExtension2; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.quickassist.IQuickAssistAssistant; + + +/** + * Extension interface for {@link dwtx.jface.text.source.IAnnotationAccess}.

                        + * This interface allows clients to set a quick assist assistant. + * + * @see dwtx.jface.text.source.IAnnotationAccess + * @since 3.2 + */ +public interface IAnnotationAccessExtension2 { + + /** + * Provides this annotation access with a quick assist assistant that + * is used to decide whether the quick fix image should be shown. + * + * @param assistant the quick assist assistant + */ + void setQuickAssistAssistant(IQuickAssistAssistant assistant); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IAnnotationHover.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IAnnotationHover.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,116 @@ +/******************************************************************************* + * 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 + * 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.text.source.IAnnotationHover; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + + +/** + * Provides the information to be displayed in a hover popup window which + * appears over the presentation area of annotations. + *

                        + * In order to provide backward compatibility for clients of + * IAnnotationHover, extension interfaces are used as a means of + * evolution. The following extension interfaces exist: + *

                          + *
                        • {@link dwtx.jface.text.source.IAnnotationHoverExtension} since + * version 3.0 allowing a text hover to provide a creator for the hover control. + * This allows for sophisticated hovers in a way that information computed by + * the hover can be displayed in the best possible form.
                        • + *
                        • {@link dwtx.jface.text.source.IAnnotationHoverExtension2} since + * version 3.2 allowing a text hover to specify whether it handles mouse-wheel + * events itself.
                        • + *

                        + *

                        + * Clients may implement this interface.

                        + * + * @see dwtx.jface.text.source.IAnnotationHoverExtension + * @see dwtx.jface.text.source.IAnnotationHoverExtension2 + */ +public interface IAnnotationHover { + + /** + * Returns the text which should be presented in the a + * hover popup window. This information is requested based on + * the specified line number. + * + * @param sourceViewer the source viewer this hover is registered with + * @param lineNumber the line number for which information is requested + * @return the requested information or null if no such information exists + */ + String getHoverInfo(ISourceViewer sourceViewer, int lineNumber); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IAnnotationHoverExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IAnnotationHoverExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.IAnnotationHoverExtension; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.IInformationControlCreator; + +/** + * Extension interface for {@link dwtx.jface.text.source.IAnnotationHover} for + *
                          + *
                        • providing its own information control creator
                        • + *
                        • providing the range of lines for which the hover for a given line is valid
                        • + *
                        • providing whether the information control can interact with the mouse cursor
                        • + *
                        + * + * @see dwtx.jface.text.IInformationControlCreator + * @see dwtx.jface.text.source.IAnnotationHover + * @since 3.0 + */ +public interface IAnnotationHoverExtension { + + /** + * Returns the hover control creator of this annotation hover. + * + * @return the hover control creator + */ + IInformationControlCreator getHoverControlCreator(); + + /** + * Returns whether the provided information control can interact with the mouse cursor. I.e. the + * hover must implement custom information control management. + * + * @return true if the mouse cursor can be handled + */ + bool canHandleMouseCursor(); + + /** + * Returns the object which should be presented in the a + * hover popup window. The information is requested based on + * the specified line range. + * + * @param sourceViewer the source viewer this hover is registered with + * @param lineRange the line range for which information is requested + * @param visibleNumberOfLines the number of visible lines + * @return the requested information or null if no such information exists + */ + Object getHoverInfo(ISourceViewer sourceViewer, ILineRange lineRange, int visibleNumberOfLines); + + /** + * Returns the range of lines that include the given line number for which + * the same hover information is valid. + * + * @param viewer the viewer which the hover is queried for + * @param lineNumber the line number of the line for which a hover is displayed for + * @return the computed line range or null for no range + */ + ILineRange getHoverLineRange(ISourceViewer viewer, int lineNumber); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IAnnotationHoverExtension2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IAnnotationHoverExtension2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,98 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.text.source.IAnnotationHoverExtension2; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Extension interface for {@link dwtx.jface.text.source.IAnnotationHover} for + *
                          + *
                        • providing whether the information control can interact with the mouse wheel
                        • + *
                        + * + * @see dwtx.jface.text.source.IAnnotationHover + * @since 3.2 + */ +public interface IAnnotationHoverExtension2 { + /** + * Returns whether the provided information control can interact with the mouse wheel. I.e. the + * hover will not be closed when the mouse wheel is moved. + * + * @return true if the mouse wheel is handled by the hover + */ + bool canHandleMouseWheel(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IAnnotationMap.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IAnnotationMap.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.IAnnotationMap; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.dwtxhelper.Collection; + + + + +import dwtx.jface.text.ISynchronizable; + + +/** + * An annotation map is a map specialized for the requirements of an annotation + * model. The annotation map supports a customizable lock object which is used + * to synchronize concurrent operations on the map (see + * {@link dwtx.jface.text.ISynchronizable}. The map supports two + * iterator methods, one for the values and one for the keys of the map. The + * returned iterators are robust, i.e. they work on a copy of the values and + * keys set that is made at the point in time the iterator methods are called. + *

                        + * The returned collections of the methods values, + * entrySet, and keySet are not synchronized on + * the annotation map's lock object. + *

                        + * + * @see dwtx.jface.text.source.IAnnotationModel + * @since 3.0 + */ +public interface IAnnotationMap : Map, ISynchronizable { + + /** + * Returns an iterator for a copy of this annotation map's values. + * + * @return an iterator for a copy of this map's values + */ + Iterator valuesIterator(); + + /** + * Returns an iterator for a copy of this map's key set. + * + * @return an iterator for a copy of this map's key set + */ + Iterator keySetIterator(); + + /** + * {@inheritDoc} + * + * The returned set is not synchronized on this annotation map's lock object. + */ + Set entrySet(); + + /** + * {@inheritDoc} + * + * The returned set is not synchronized on this annotation map's lock object. + */ + Set keySet(); + + /** + * {@inheritDoc} + * + * The returned collection is not synchronized on this annotation map's lock object. + */ + Collection values(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IAnnotationModel.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IAnnotationModel.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,214 @@ +/******************************************************************************* + * 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 + * 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.text.source.IAnnotationModel; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + +import dwtx.jface.text.IDocument; +import dwtx.jface.text.Position; + + +/** + * This interface defines the model for managing annotations attached to a document. + * The model maintains a set of annotations for a given document and notifies registered annotation + * model listeners about annotation model changes. It also provides methods + * for querying the current position of an annotation managed + * by this model. + *

                        + * In order to provide backward compatibility for clients of IAnnotationModel, extension + * interfaces are used to provide a means of evolution. The following extension interfaces + * exist: + *

                          + *
                        • {@link dwtx.jface.text.source.IAnnotationModelExtension} since version 3.0 introducing the concept + * of model piggybacking annotation models, modification time stamps, and enhanced manipulation methods. + *
                        • + *
                        • {@link dwtx.jface.text.source.IAnnotationModelExtension2} since version 3.4 allows to retrieve + * annotations within a given region. + *
                        • + *
                        + *

                        + * + * Clients may implement this interface or use the default implementation provided + * by AnnotationModel. + * + * @see dwtx.jface.text.source.IAnnotationModelExtension + * @see dwtx.jface.text.source.IAnnotationModelExtension2 + * @see dwtx.jface.text.source.Annotation + * @see dwtx.jface.text.source.IAnnotationModelListener + */ +public interface IAnnotationModel { + + /** + * Registers the annotation model listener with this annotation model. + * After registration listener is informed about each change of this model. + * If the listener is already registered nothing happens. + * + * @param listener the listener to be registered, may not be null + */ + void addAnnotationModelListener(IAnnotationModelListener listener); + + /** + * Removes the listener from the model's list of annotation model listeners. + * If the listener is not registered with the model nothing happens. + * + * @param listener the listener to be removed, may not be null + */ + void removeAnnotationModelListener(IAnnotationModelListener listener); + + /** + * Connects the annotation model to a document. The annotations managed + * by this model must subsequently update according to the changes applied + * to the document. Once an annotation model is connected to a document, + * all further connect calls must mention the document the + * model is already connected to. An annotation model primarily uses + * connect and disconnect for reference counting + * the document. Reference counting frees the clients from keeping tracker + * whether a model has already been connected to a document. + * + * @param document the document the model gets connected to, + * may not be null + * + * @see #disconnect(IDocument) + */ + void connect(IDocument document); + + /** + * Disconnects this model from a document. After that, document changes no longer matter. + * An annotation model may only be disconnected from a document to which it has been + * connected before. If the model reference counts the connections to a document, + * the connection to the document may only be terminated if the reference count does + * down to 0. + * + * @param document the document the model gets disconnected from, + * may not be null + * + * @see #connect(IDocument) for further specification details + */ + void disconnect(IDocument document); + + /** + * Adds a annotation to this annotation model. The annotation is associated with + * with the given position which describes the range covered by the annotation. + * All registered annotation model listeners are informed about the change. + * If the model is connected to a document, the position is automatically + * updated on document changes. If the annotation is already managed by + * this annotation model or is not a valid position in the connected document + * nothing happens. + *

                        + * Performance hint: Use {@link IAnnotationModelExtension#replaceAnnotations(Annotation[], java.util.Map)} + * if several annotations are added and/or removed. + *

                        + * + * @param annotation the annotation to add, may not be null + * @param position the position describing the range covered by this annotation, + * may not be null + */ + void addAnnotation(Annotation annotation, Position position); + + /** + * Removes the given annotation from the model. I.e. the annotation is no + * longer managed by this model. The position associated with the annotation + * is no longer updated on document changes. If the annotation is not + * managed by this model, nothing happens. + *

                        + * Performance hint: Use {@link IAnnotationModelExtension#replaceAnnotations(Annotation[], java.util.Map)} + * if several annotations are removed and/or added. + *

                        + * + * @param annotation the annotation to be removed from this model, + * may not be null + */ + void removeAnnotation(Annotation annotation); + + /** + * Returns all annotations managed by this model. + * + * @return all annotations managed by this model (element type: {@link Annotation}) + */ + Iterator getAnnotationIterator(); + + /** + * Returns the position associated with the given annotation. + * + * @param annotation the annotation whose position should be returned + * @return the position of the given annotation or null if no + * associated annotation exists + */ + Position getPosition(Annotation annotation); +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IAnnotationModelExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IAnnotationModelExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,172 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.IAnnotationModelExtension; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.dwtxhelper.Collection; + +import dwtx.jface.text.Position; + + +/** + * Extends {@link dwtx.jface.text.source.IAnnotationModel}with the + * ability piggyback other annotation models. It also introduces the concept of + * modification time stamps and adds methods for richer manipulation methods. + * + * @since 3.0 + */ +public interface IAnnotationModelExtension { + + /** + * Attaches attachment to the receiver. Connects + * attachment to the currently connected document. If + * attachment is already attached (even) under a different + * key), it is not attached again. + * + * @param key the key through which the attachment is identified. + * @param attachment the attached IAnnotationModel + */ + void addAnnotationModel(Object key, IAnnotationModel attachment); + + /** + * Returns the attached IAnnotationModel for key, + * or null if none is attached for key. + * + * @param key the key through which the attachment is identified. + * @return an IAnnotationModel attached under + * key, or null + */ + IAnnotationModel getAnnotationModel(Object key); + + /** + * Removes and returns the attached IAnnotationModel for + * key. + * + * @param key the key through which the attachment is identified. + * @return an IAnnotationModel attached under + * key, or null + */ + IAnnotationModel removeAnnotationModel(Object key); + + /** + * Adds and removes annotations to/from this annotation model in a single + * step. The annotations to remove are given in an array. The annotations to + * add are provided in a map associating the annotations with the positions + * at which they should be added. All registered annotation model listeners + * are informed about the change. If the model is connected to a document, + * the positions are automatically updated on document changes. Annotations + * that are already managed by this annotation model or are not associated + * with a valid position in the connected document have no effect. + * + * @param annotationsToRemove the annotations to be removed, may be + * null + * @param annotationsToAdd the annotations which will be added, may be + * null each map entry has an + * Annotation as key and a Position + * as value + * @throws ClassCastException if one of the map key or values has a wrong + * type + */ + void replaceAnnotations(Annotation[] annotationsToRemove, Map annotationsToAdd) ; + + /** + * Modifies the position associated with the given annotation to equal the + * given position. If the annotation is not yet managed by this annotation + * model, the annotation is added. If the given position is + * null the annotation is removed from the model. All + * annotation model change listeners will be informed about the change. + * + * @param annotation the annotation whose associated position should be + * modified + * @param position the position to whose values the associated position + * should be changed + */ + void modifyAnnotationPosition(Annotation annotation, Position position); + + /** + * Removes all annotations from this annotation model. + */ + void removeAllAnnotations(); + + /** + * Returns the modification stamp of this annotation model. + * + * @return the modification stamp of this annotation model + */ + Object getModificationStamp(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IAnnotationModelExtension2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IAnnotationModelExtension2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,104 @@ +/******************************************************************************* + * 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.text.source.IAnnotationModelExtension2; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + +/** + * Extends {@link dwtx.jface.text.source.IAnnotationModel} with the + * ability to retrieve a set of annotations within a given region. + * + * @since 3.4 + */ +public interface IAnnotationModelExtension2 { + + /** + * Returns an iterator over all annotations managed by this model that are + * inside the given region. + * + * @param offset the start position of the region, must be >= 0 + * @param length the length of the region, must be >= 0 + * @param canStartBefore if true then annotations are included + * which start before the region if they end at or after the region's start + * @param canEndAfter if true then annotations are included + * which end after the region if they start at or before the region's end + * @return all annotations inside the region managed by this model (element type: {@link Annotation}) + */ + Iterator getAnnotationIterator(int offset, int length, bool canStartBefore, bool canEndAfter); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IAnnotationModelListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IAnnotationModelListener.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.IAnnotationModelListener; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Interface for objects interested in getting informed about annotation model + * changes. Changes are the addition or removal of annotations managed by the + * model. Clients may implement this interface. + * + * In order to provided backward compatibility for clients of + * IAnnotationModelListener, extension interfaces are used to + * provide a means of evolution. The following extension interfaces exist: + *
                          + *
                        • {@link dwtx.jface.text.source.IAnnotationModelListenerExtension} + * since version 2.0 replacing the change notification mechanisms.
                        • + *
                        + * + * @see dwtx.jface.text.source.IAnnotationModel + */ +public interface IAnnotationModelListener { + + /** + * Called if a model change occurred on the given model.

                        + * Replaced by {@link IAnnotationModelListenerExtension#modelChanged(AnnotationModelEvent)}. + * + * @param model the changed annotation model + */ + void modelChanged(IAnnotationModel model); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IAnnotationModelListenerExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IAnnotationModelListenerExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.IAnnotationModelListenerExtension; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Extension interface for {@link IAnnotationModelListener}. Introduces a + * notification mechanism that notifies the user by means of AnnotationModelEvents. + * Thus, more detailed information can be sent to the listener. This mechanism replaces the original notification + * mechanism of IAnnotationModelListener. + * + * @since 2.0 + */ +public interface IAnnotationModelListenerExtension { + + /** + * Called if a model change occurred on the given model. + * + * @param event the event to be sent out + */ + void modelChanged(AnnotationModelEvent event); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IAnnotationPresentation.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IAnnotationPresentation.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,116 @@ +/******************************************************************************* + * 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 + * 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.text.source.IAnnotationPresentation; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.graphics.GC; +import dwt.graphics.Rectangle; +import dwt.widgets.Canvas; + +/** + * Interface for annotations that can take care of their own visible representation. + * + * @since 3.0 + */ +public interface IAnnotationPresentation { + + /** + * The default annotation layer. + */ + static const int DEFAULT_LAYER= 0; + + + /** + * Returns the annotations drawing layer. + * + * @return the annotations drawing layer + */ + int getLayer(); + + /** + * Implement this method to draw a graphical representation + * of this annotation within the given bounds. + *

                        + * Note that this method is not used when drawing annotations on the editor's + * text widget. This is handled trough a {@link dwtx.jface.text.source.AnnotationPainter.IDrawingStrategy}. + *

                        + * @param gc the drawing GC + * @param canvas the canvas to draw on + * @param bounds the bounds inside the canvas to draw on + */ + void paint(GC gc, Canvas canvas, Rectangle bounds); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IChangeRulerColumn.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IChangeRulerColumn.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.IChangeRulerColumn; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.graphics.Color; + +/** + * An IChangeRulerColumn can display quick diff information. + * + * @since 3.0 + */ +public interface IChangeRulerColumn : IVerticalRulerColumn, IVerticalRulerInfoExtension { + + /** The ID under which the quick diff model is registered with a document's annotation model. */ + public static const String QUICK_DIFF_MODEL_ID= "diff"; //$NON-NLS-1$ + + /** + * Sets the hover of this ruler column. + * + * @param hover the hover that will produce hover information text for this ruler column + */ + public abstract void setHover(IAnnotationHover hover); + + /** + * Sets the background color for normal lines. The color has to be disposed of by the caller when + * the receiver is no longer used. + * + * @param backgroundColor the new color to be used as standard line background + */ + public abstract void setBackground(Color backgroundColor); + + /** + * Sets the background color for added lines. The color has to be disposed of by the caller when + * the receiver is no longer used. + * + * @param addedColor the new color to be used for the added lines background + */ + public abstract void setAddedColor(Color addedColor); + + /** + * Sets the background color for changed lines. The color has to be disposed of by the caller when + * the receiver is no longer used. + * + * @param changedColor the new color to be used for the changed lines background + */ + public abstract void setChangedColor(Color changedColor); + + /** + * Sets the color for the deleted lines indicator. The color has to be disposed of by the caller when + * the receiver is no longer used. + * + * @param deletedColor the new color to be used for the deleted lines indicator. + */ + public abstract void setDeletedColor(Color deletedColor); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/ICharacterPairMatcher.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/ICharacterPairMatcher.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.ICharacterPairMatcher; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; + +/** + * A character pair matcher finds to a character at a certain document offset + * the matching peer character. It is the matchers responsibility to define the + * concepts of "matching" and "peer". The matching process starts at a given + * offset. Starting of this offset, the matcher chooses a character close to + * this offset. The anchor defines whether the chosen character is left or right + * of the initial offset. The matcher then searches for the matching peer + * character of the chosen character and if it finds one, delivers the minimal + * region of the document that contains both characters. + * + * @since 2.1 + */ +public interface ICharacterPairMatcher { + + /** + * Indicates the anchor value "right". + */ + static const int RIGHT= 0; + /** + * Indicates the anchor value "left". + */ + static const int LEFT= 1; + + + /** + * Disposes this pair matcher. + */ + void dispose(); + + /** + * Clears this pair matcher. I.e. the matcher throws away all state it might + * remember and prepares itself for a new call of the match + * method. + */ + void clear(); + + /** + * Starting at the given offset, the matcher chooses a character close to this offset. + * The matcher then searches for the matching peer character of the chosen character + * and if it finds one, returns the minimal region of the document that contains both characters. + * It returns null if there is no peer character. + * + * @param iDocument the document to work on + * @param i the start offset + * @return the minimal region containing the peer characters + */ + IRegion match(IDocument iDocument, int i); + + /** + * Returns the anchor for the region of the matching peer characters. The anchor + * says whether the character that has been chosen to search for its peer character + * has been left or right of the initial offset. + * + * @return RIGHT or LEFT + */ + int getAnchor(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/ILineDiffInfo.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/ILineDiffInfo.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,140 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.ILineDiffInfo; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * Describes the change state of one line, which consists of the state of the line itself, which + * can be UNCHANGED, CHANGED or ADDED, and the number of + * deleted lines before and after this line. + *

                        + * This interface may be implemented by clients. + *

                        + * + * @since 3.0 + */ +public interface ILineDiffInfo { + + /** Denotes an unchanged line. */ + static const int UNCHANGED= 0; + + /** Denotes an added line. */ + static const int ADDED= 1; + + /** Denotes a changed line. */ + static const int CHANGED= 2; + + /** + * Returns the number of deleted lines after this line. + * + * @return the number of lines after this line. + */ + int getRemovedLinesBelow(); + + /** + * Returns the number of deleted lines before this line. + * + * @return the number of lines before this line. + */ + int getRemovedLinesAbove(); + + /** + * Returns the type of this line, one out of UNCHANGED, CHANGED or + * ADDED. + * + * @return the type of this line. + */ + int getChangeType(); + + /** + * Returns whether this line has any changes (to itself, or any deletions before or after it). + * + * @return true, if the line's state (as returned by getType) is + * either CHANGED or ADDED or either of getRemovedLinesBelow + * and getRemovedLinesAbove would return a number > 0 + */ + bool hasChanges(); + + /** + * Returns the original text of this changed region + * + * @return the original text of this changed region, including any deleted lines. The returned + * value and its elements may not be null/code>, it may however be of zero length + */ + String[] getOriginalText(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/ILineDiffer.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/ILineDiffer.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,155 @@ +/******************************************************************************* + * 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 + * 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.text.source.ILineDiffer; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.BadLocationException; + + +/** + * Protocol that allows direct access to line information. Usually, implementations will also + * implement IAnnotationModel, which only allows Iterator based access + * to annotations. + *

                        + * ILineDiffer also allows to revert any lines to their original + * contents as defined by the quick diff reference used by the receiver. + *

                        + *

                        + * This interface may be implemented by clients. + *

                        + *

                        + * In order to provide backward compatibility for clients of ILineDiffer, extension + * interfaces are used to provide a means of evolution. The following extension interface + * exists: + *

                          + *
                        • {@link ILineDifferExtension} (since version 3.1): introducing the concept + * suspending and resuming an ILineDiffer.
                        • + *
                        • {@link ILineDifferExtension2} (since version 3.3): allowing to query the suspension state + * of an ILineDiffer.
                        • + *
                        + *

                        + * + * @since 3.0 + */ +public interface ILineDiffer { + + /** + * Determines the line state for line line in the targeted document. + * + * @param line the line to get diff information for + * @return the line information object for line or null if none + */ + ILineDiffInfo getLineInfo(int line); + + /** + * Reverts a single changed line to its original state, not touching any lines that + * are deleted at its borders. + * + * @param line the line number of the line to be restored. + * @throws BadLocationException if line is out of bounds. + */ + void revertLine(int line) ; + + /** + * Reverts a block of modified / added lines to their original state, including any deleted + * lines inside the block or at its borders. A block is considered to be a range of modified + * (e.g. changed, or added) lines. + * + * @param line any line in the block to be reverted. + * @throws BadLocationException if line is out of bounds. + */ + void revertBlock(int line) ; + + /** + * Reverts a range of lines to their original state, including any deleted + * lines inside the block or at its borders. + * + * @param line any line in the block to be reverted. + * @param nLines the number of lines to be reverted, must be > 0. + * @throws BadLocationException if line is out of bounds. + */ + void revertSelection(int line, int nLines) ; + + /** + * Restores the deleted lines after line. + * + * @param line the deleted lines following this line number are restored. + * @return the number of restored lines. + * @throws BadLocationException if line is out of bounds. + */ + int restoreAfterLine(int line) ; +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/ILineDifferExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/ILineDifferExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.ILineDifferExtension; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Extension interface for {@link ILineDiffer}. + *

                        + * Introduces the concept of suspending a differ. A ILineDiffer may + * be suspended into a dormant state, and resumed to normal operation. + *

                        + * + * @since 3.1 + */ +public interface ILineDifferExtension { + + /** + * Suspends the receiver. All differences are cleared. + */ + void suspend(); + + /** + * Resumes the receiver. Must only be called after suspend. + */ + void resume(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/ILineDifferExtension2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/ILineDifferExtension2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,95 @@ +/******************************************************************************* + * 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 + * 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.text.source.ILineDifferExtension2; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Extension interface for {@link ILineDiffer}. + *

                        + * Allows to query the suspension state. + *

                        + * + * @since 3.3 + */ +public interface ILineDifferExtension2 { + /** + * Returns true if the receiver is suspended, false otherwise. + * + * @return true if the receiver is suspended, false otherwise + */ + bool isSuspended(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/ILineRange.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/ILineRange.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.ILineRange; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Describes a range of lines. + *

                        + * Note that the number of lines is 1-based, e.g. getStartLine() + getNumberOfLines() + * computes the first line after the range, and a range with + * getNumberOfLines() is 0 is empty. + *

                        + * + * @since 3.0 + */ +public interface ILineRange { + + /** + * Returns the start line of this line range or -1. + * + * @return the start line of this line range or -1 if this line range is invalid. + */ + int getStartLine(); + + /** + * Returns the number of lines of this line range or -1. + * + * @return the number of lines in this line range or -1 if this line range is invalid. + */ + int getNumberOfLines(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IOverviewRuler.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IOverviewRuler.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,184 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.IOverviewRuler; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.graphics.Color; +import dwt.widgets.Control; + +/** + * This interface defines a visual component which may serve + * text viewers as an overview annotation presentation area. This means, + * presentation of annotations is independent from the actual view port of + * the text viewer. The annotations of the viewer's whole document are + * visible in the overview ruler. + *

                        + * This interfaces embodies three contracts: + *

                          + *
                        • The overview ruler retrieves the annotations it presents from an annotation model. + *
                        • The ruler is a visual component which must be integrated in a hierarchy of DWT controls. + *
                        • The ruler provides interested clients with mapping and + * interaction information. This covers the mapping between + * coordinates of the ruler's control and line numbers based + * on the connected text viewer's document (IVerticalRulerInfo). + *

                        + *

                        + * Clients may implement this interface or use the default implementation provided + * by OverviewlRuler.

                        + * + * @see dwtx.jface.text.ITextViewer + * @since 2.1 + */ +public interface IOverviewRuler : IVerticalRuler { + + /** + * Returns whether there is an annotation an the given vertical coordinate. This + * method takes the compression factor of the overview ruler into account. + * + * @param y the y-coordinate + * @return true if there is an annotation, false otherwise + */ + bool hasAnnotation(int y); + + /** + * Returns the height of the visual presentation of an annotation in this + * overview ruler. Assumes that all annotations are represented using the + * same height. + * + * @return int the visual height of an annotation + */ + int getAnnotationHeight(); + + /** + * Sets the color for the given annotation type in this overview ruler. + * + * @param annotationType the annotation type + * @param color the color + */ + void setAnnotationTypeColor(Object annotationType, Color color); + + /** + * Sets the drawing layer for the given annotation type in this overview ruler. + * + * @param annotationType the annotation type + * @param layer the drawing layer + */ + void setAnnotationTypeLayer(Object annotationType, int layer); + + /** + * Adds the given annotation type to this overview ruler. Starting with this + * call, annotations of the given type are shown in the overview ruler. + * + * @param annotationType the annotation type + */ + void addAnnotationType(Object annotationType); + + /** + * Removes the given annotation type from this overview ruler. Annotations + * of the given type are no longer shown in the overview ruler. + * + * @param annotationType the annotation type + */ + void removeAnnotationType(Object annotationType); + + /** + * Adds the given annotation type to the header of this ruler. Starting with + * this call, the presence of annotations is tracked and the header is drawn + * in the configured color. + * + * @param annotationType the annotation type to be tracked + */ + void addHeaderAnnotationType(Object annotationType); + + /** + * Removes the given annotation type from the header of this ruler. The + * presence of annotations of the given type is no longer tracked and the + * header is drawn in the default color, depending on the other configured + * configured annotation types. + * + * @param annotationType the annotation type to be removed + */ + void removeHeaderAnnotationType(Object annotationType); + + /** + * Returns this rulers header control. This is the little area between the + * top of the text widget and the top of this overview ruler. + * + * @return the header control of this overview ruler. + */ + Control getHeaderControl(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/ISharedTextColors.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/ISharedTextColors.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.ISharedTextColors; + +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.graphics.Color; +import dwt.graphics.RGB; + + +/** + * Manages DWT color objects. Until the dispose method is called, + * the same color object is returned for equal RGB values. + *

                        + * This interface may be implemented by clients. + *

                        + * + * @since 2.1 + */ +public interface ISharedTextColors { + + /** + * Returns the color object for the value represented by the given + * RGB object. + * + * @param rgb the RBG color specification + * @return the color object for the given RGB value + */ + Color getColor(RGB rgb); + + /** + * Tells this object to dispose all its managed colors. + */ + void dispose(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/ISourceViewer.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/ISourceViewer.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,264 @@ +/******************************************************************************* + * 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.text.source.ISourceViewer; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextOperationTarget; +import dwtx.jface.text.ITextViewer; + + +/** + * In addition to the text viewer functionality a source viewer supports: + *
                          + *
                        • visual annotations based on an annotation model + *
                        • visual range indication + *
                        • management of text viewer add-ons + *
                        • explicit configuration + *
                        + * It is assumed that range indication and visual annotations are shown inside + * the same presentation area. There are no assumptions about whether this area + * is different from the viewer's text widget. + *

                        + * As the visibility of visual annotations can dynamically be changed, it is + * assumed that the annotation presentation area can dynamically be hidden if it + * is different from the text widget. + *

                        + * In order to provide backward compatibility for clients of + * ISourceViewer, extension interfaces are used as a means of + * evolution. The following extension interfaces exist: + *

                          + *
                        • {@link dwtx.jface.text.source.ISourceViewerExtension} since version 2.1 + * introducing the concept of an annotation overview.
                        • + *
                        • {@link dwtx.jface.text.source.ISourceViewerExtension2} since version 3.0 + * allowing source viewers to roll back a previously performed configuration and + * allows access to the viewer's visual annotation model.
                        • + *
                        • {@link dwtx.jface.text.source.ISourceViewerExtension3} since version 3.2 + * introducing the concept of a quick assist assistant and providing access + * to the quick assist invocation context as well as the current annotation hover.
                        • + *
                        • {@link dwtx.jface.text.source.ISourceViewerExtension4} since version 3.4 + * introducing API to access a minimal set of content assistant APIs.
                        • + *

                        + *

                        + * Clients may implement this interface and its extension interfaces or use the + * default implementation provided by + * {@link dwtx.jface.text.source.SourceViewer}.

                        + * + * @see dwtx.jface.text.source.ISourceViewerExtension + * @see dwtx.jface.text.source.ISourceViewerExtension2 + * @see dwtx.jface.text.source.ISourceViewerExtension3 + * @see dwtx.jface.text.source.ISourceViewerExtension4 + */ +public interface ISourceViewer : ITextViewer { + + /** + * Text operation code for requesting content assist to show completion + * proposals for the current insert position. + */ + static const int CONTENTASSIST_PROPOSALS= ITextOperationTarget.STRIP_PREFIX + 1; + + /** + * Text operation code for requesting content assist to show + * the content information for the current insert position. + */ + static const int CONTENTASSIST_CONTEXT_INFORMATION= ITextOperationTarget.STRIP_PREFIX + 2; + + /** + * Text operation code for formatting the selected text or complete document + * of this viewer if the selection is empty. + */ + static const int FORMAT= ITextOperationTarget.STRIP_PREFIX + 3; + + /** + * Text operation code for requesting information at the current insertion position. + * @since 2.0 + */ + static const int INFORMATION = ITextOperationTarget.STRIP_PREFIX + 4; + + /* + * XXX: Cannot continue numbering due to operation codes used in ProjectionViewer + */ + + /** + * Text operation code for requesting quick assist. This will normally + * show quick assist and quick fix proposals for the current position. + * @since 3.2 + */ + static const int QUICK_ASSIST= ITextOperationTarget.STRIP_PREFIX + 10; + + /** + * Configures the source viewer using the given configuration. Prior to 3.0 this + * method can only be called once. Since 3.0 this method can be called again + * after a call to {@link ISourceViewerExtension2#unconfigure()}. + * + * @param configuration the source viewer configuration to be used + */ + void configure(SourceViewerConfiguration configuration); + + /** + * Sets the annotation hover of this source viewer. The annotation hover + * provides the information to be displayed in a hover popup window + * if requested over the annotation presentation area. The annotation + * hover is assumed to be line oriented. + * + * @param annotationHover the hover to be used, null is a valid argument + */ + void setAnnotationHover(IAnnotationHover annotationHover); + + /** + * Sets the given document as this viewer's text model and the + * given annotation model as the model for this viewer's visual + * annotations. The presentation is accordingly updated. An appropriate + * TextEvent is issued. This text event does not carry + * a related document event. + * + * @param document the viewer's new input document + * @param annotationModel the model for the viewer's visual annotations + * + * @see ITextViewer#setDocument(IDocument) + */ + void setDocument(IDocument document, IAnnotationModel annotationModel); + + /** + * Sets the given document as this viewer's text model and the + * given annotation model as the model for this viewer's visual + * annotations. The presentation is accordingly updated whereby + * only the specified region is exposed. An appropriate + * TextEvent is issued. The text event does not carry a + * related document event. This method is a convenience method for + * setDocument(document, annotationModel);setVisibleRegion(offset, length). + * + * @param document the new input document + * @param annotationModel the model of the viewer's visual annotations + * @param modelRangeOffset the offset of the model range + * @param modelRangeLength the length of the model range + * + * @see ITextViewer#setDocument(IDocument, int, int) + */ + void setDocument(IDocument document, IAnnotationModel annotationModel, int modelRangeOffset, int modelRangeLength); + + /** + * Returns this viewer's annotation model. Use + * {@link ISourceViewerExtension2#getVisualAnnotationModel()}in order to + * get access to the viewer's visual annotation model. + * + * @return this viewer's annotation model + */ + IAnnotationModel getAnnotationModel(); + + /** + * Sets the annotation used by this viewer as range indicator. The + * range covered by this annotation is referred to as range indication. + * + * @param rangeIndicator the annotation to be used as this viewer's range indicator + */ + void setRangeIndicator(Annotation rangeIndicator); + + /** + * Sets the viewers's range indication to the specified range. Its is indicated + * whether the cursor should also be moved to the beginning of the specified range. + * + * @param offset the offset of the range + * @param length the length of the range + * @param moveCursor indicates whether the cursor should be moved to the given offset + */ + void setRangeIndication(int offset, int length, bool moveCursor); + + /** + * Returns the viewer's range indication. + * + * @return the viewer's range indication. + */ + IRegion getRangeIndication(); + + /** + * Removes the viewer's range indication. There is no visible range indication + * after this method completed. + */ + void removeRangeIndication(); + + /** + * Controls the visibility of annotations and in the case of separate + * presentation areas of text and annotations, the visibility of the + * annotation's presentation area.

                        + * By default, annotations and their presentation area are visible. + * + * @param show indicates the visibility of annotations + */ + void showAnnotations(bool show); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/ISourceViewerExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/ISourceViewerExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.ISourceViewerExtension; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + +import dwt.dwthelper.utils; + +/** + * Extension interface {@link dwtx.jface.text.source.ISourceViewer}. + *

                        + * Extends the source viewer with the concept of an annotation overview. The + * annotation overview differs from the annotation presentation in that it is + * independent from the viewer's view port, i.e. the annotations of the whole + * document are visible. There are no assumptions about the area in which the + * annotation overview is shown. + *

                        + * As the visibility of annotation overview can dynamically be changed, it is + * assumed that the presentation area can dynamically be hidden if it is + * different from the text widget. + * + * @see dwtx.jface.text.source.ISourceViewer + * @since 2.1 + */ +public interface ISourceViewerExtension { + + /** + * Shows/hides an overview representation of the annotations of the whole document of this viewer. + * + * @param show true if annotation overview should be visible, false otherwise + */ + void showAnnotationsOverview(bool show); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/ISourceViewerExtension2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/ISourceViewerExtension2.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.ISourceViewerExtension2; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + +import dwt.dwthelper.utils; + +/** + * Extension interface for {@link dwtx.jface.text.source.ISourceViewer}.

                        + * Allows the source viewer to roll back a previous configuration process and allows + * clients access to the viewer's visual annotation model. + * + * @since 3.0 + */ +public interface ISourceViewerExtension2 { + + /** + * Rolls back the configuration process of this source viewer. The source + * viewer can be configured again after a call to this method. Unlike + * {@link ISourceViewer#configure(SourceViewerConfiguration)} this method + * can be called more than once without interleaving calls to + * {@link ISourceViewer#configure(SourceViewerConfiguration)}. + */ + void unconfigure(); + + /** + * Returns the visual annotation model of this viewer. + * + * @return the visual annotation model of this viewer + */ + IAnnotationModel getVisualAnnotationModel(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/ISourceViewerExtension3.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/ISourceViewerExtension3.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,118 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ + + +module dwtx.jface.text.source.ISourceViewerExtension3; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + +import dwt.dwthelper.utils; + +import dwtx.jface.text.quickassist.IQuickAssistAssistant; +import dwtx.jface.text.quickassist.IQuickAssistInvocationContext; + +/** + * Extension interface for {@link dwtx.jface.text.source.ISourceViewer}.

                        + * It introduces the concept of a quick assist assistant and provides access + * to the quick assist invocation context. It also gives access to any currently + * showing annotation hover.

                        + * + * @see IQuickAssistAssistant + * @see IQuickAssistInvocationContext + * @since 3.2 + */ +public interface ISourceViewerExtension3 { + + /** + * Returns this viewers quick assist assistant. + * + * @return the quick assist assistant or null if none is configured + * @since 3.2 + */ + public IQuickAssistAssistant getQuickAssistAssistant(); + + /** + * Returns this viewer's quick assist invocation context. + * + * @return the quick assist invocation context or null if none is available + */ + IQuickAssistInvocationContext getQuickAssistInvocationContext(); + + /** + * Returns the currently displayed annotation hover if any, null otherwise. + * + * @return the currently displayed annotation hover or null + */ + IAnnotationHover getCurrentAnnotationHover(); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/ISourceViewerExtension4.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/ISourceViewerExtension4.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,102 @@ +/******************************************************************************* + * 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.text.source.ISourceViewerExtension4; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.contentassist.IContentAssistant; + + +/** + * Extension interface for {@link dwtx.jface.text.source.ISourceViewer}. + *

                        + * It introduces API to access a minimal set of content assistant APIs. + *

                        + * + * @see IContentAssistant + * @since 3.4 + */ +public interface ISourceViewerExtension4 { + + /** + * Returns a facade for this viewer's content assistant. + * + * @return a content assistant facade or null if none is + * configured + */ + public ContentAssistantFacade getContentAssistantFacade(); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IVerticalRuler.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IVerticalRuler.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.IVerticalRuler; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + + + +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwtx.jface.text.ITextViewer; + + +/** + * This interface defines a visual component which may serve text viewers as an + * annotation presentation area. Implementers of this interface have to define + * the presentation modus. This can either depend on the connected viewer's view + * port or not. If the modus is view port dependent the ruler only shows those + * annotations that are attached to document regions that are visible in the + * view port. If independent, the presented annotations can also be attached to + * invisible document regions. + * + * This interfaces comprises three contracts: + *
                          + *
                        • The vertical ruler retrieves the annotations it presents from an + * annotation model. + *
                        • The ruler is a visual component which must be integrated in a hierarchy + * of DWT controls. + *
                        • The ruler provides interested clients with mapping and interaction + * information. This covers the mapping between coordinates of the ruler's + * control and line numbers based on the connected text viewer's document (see + * {@link dwtx.jface.text.source.IVerticalRulerInfo}). + *
                        + *

                        + * In order to provide backward compatibility for clients of + * IVerticalRuler, extension interfaces are used as a means of + * evolution. The following extension interfaces exist: + *

                          + *
                        • {@link dwtx.jface.text.source.IVerticalRulerExtension} since + * version 2.0 introducing setters for font and mouse button activity location.
                        • + *

                        + *

                        + * Clients may implement this interface or use the default implementation + * provided by {@link dwtx.jface.text.source.CompositeRuler} and + * {@link dwtx.jface.text.source.VerticalRuler}.

                        + * + * @see dwtx.jface.text.source.IVerticalRulerExtension + * @see dwtx.jface.text.ITextViewer + */ +public interface IVerticalRuler : IVerticalRulerInfo { + + /** + * Associates an annotation model with this ruler. + * A value null is acceptable and clears the ruler. + * + * @param model the new annotation model, may be null + */ + void setModel(IAnnotationModel model); + + /** + * Returns the current annotation model of this ruler or null + * if the ruler has no model. + * + * @return this ruler's annotation model or null if there is no model + */ + IAnnotationModel getModel(); + + /** + * Forces the vertical ruler to synchronize itself with its + * annotation model and its viewer's view port. + */ + void update(); + + /** + * Creates the ruler's DWT control. + * + * @param parent the parent control of the ruler's control + * @param textViewer the text viewer to which this ruler belongs + * @return the ruler's DWT control + */ + Control createControl(Composite parent, ITextViewer textViewer); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IVerticalRulerColumn.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IVerticalRulerColumn.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,141 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.IVerticalRulerColumn; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + +import dwt.graphics.Font; +import dwt.widgets.Composite; +import dwt.widgets.Control; + + +/** + * A vertical ruler column is an element that can be added to a composite + * vertical ruler ({@link dwtx.jface.text.source.CompositeRuler}). A + * composite vertical ruler is a vertical ruler with dynamically changing + * appearance and behavior depending on its actual arrangement of ruler columns. + * A vertical ruler column supports a subset of the contract of a vertical + * ruler. + * + * @see dwtx.jface.text.source.CompositeRuler + * @since 2.0 + */ +public interface IVerticalRulerColumn { + + /** + * Associates an annotation model with this ruler column. + * A value null is acceptable and clears the ruler. + * + * @param model the new annotation model, may be null + */ + void setModel(IAnnotationModel model); + + /** + * Redraws this column. + */ + void redraw(); + + /** + * Creates the column's DWT control. + * + * @param parentRuler the parent ruler of this column + * @param parentControl the control of the parent ruler + * @return the column's DWT control + */ + Control createControl(CompositeRuler parentRuler, Composite parentControl); + + /** + * Returns the column's DWT control. + * + * @return the column's DWT control + */ + Control getControl(); + + /** + * Returns the width of this column's control. + * + * @return the width of this column's control + */ + int getWidth(); + + /** + * Sets the font of this ruler column. + * + * @param font the new font of the ruler column + */ + void setFont(Font font); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IVerticalRulerExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IVerticalRulerExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.IVerticalRulerExtension; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + +import dwt.graphics.Font; + + +/** + * Extension interface for {@link IVerticalRuler}. + *

                        + * Allows to set the font of the vertical ruler and to set the location of the + * last mouse button activity. + * + * @since 2.0 + */ +public interface IVerticalRulerExtension { + + /** + * Sets the font of this vertical ruler. + * + * @param font the new font of the vertical ruler + */ + void setFont(Font font); + + /** + * Sets the location of the last mouse button activity. This method is used for + * example by external mouse listeners. + * + * @param x the x-coordinate + * @param y the y-coordinate + */ + void setLocationOfLastMouseButtonActivity(int x, int y); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IVerticalRulerInfo.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IVerticalRulerInfo.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,138 @@ +/******************************************************************************* + * 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.text.source.IVerticalRulerInfo; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + +import dwt.dwthelper.utils; + + +import dwt.widgets.Control; + + +/** + * A vertical ruler is a visual component which may serve text viewers as an + * annotation presentation area. The vertical ruler info provides interested + * clients with the mapping and interaction aspect of the vertical ruler. This + * covers the mapping between coordinates of the ruler's control and line + * numbers based on the connected text viewer's document. + * + * In order to provide backward compatibility for clients of + * IVerticalRulerInfo, extension interfaces are used as a means + * of evolution. The following extension interfaces exist: + *

                          + *
                        • {@link dwtx.jface.text.source.IVerticalRulerInfoExtension} since + * version 3.0 allowing custom annotation hovers and specific annotation models. + *
                        • + *
                        + * + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension + * @since 2.0 + */ +public interface IVerticalRulerInfo { + + /** + * Returns the ruler's DWT control. + * + * @return the ruler's DWT control + */ + Control getControl(); + + /** + * Returns the line number of the last mouse button activity. + * Based on the input document of the connected text viewer. + * + * @return the line number of the last mouse button activity or -1 if + * the last mouse activity does not correspond to a valid document line + */ + int getLineOfLastMouseButtonActivity(); + + /** + * Translates a y-coordinate of the ruler's DWT control into + * the according line number of the document of the connected text viewer. + * + * @param y_coordinate a y-coordinate of the ruler's DWT control + * @return the line number of that coordinate or -1 if that + * coordinate does not correspond to a valid document line + */ + int toDocumentLineNumber(int y_coordinate); + + /** + * Returns the width of this ruler's control. + * + * @return the width of this ruler's control + */ + int getWidth(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IVerticalRulerInfoExtension.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IVerticalRulerInfoExtension.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.IVerticalRulerInfoExtension; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Extension interface for + * {@link dwtx.jface.text.source.IVerticalRulerInfo}. + *

                        + * Introduces the ability to define a custom hover to be used when hovering over + * the vertical ruler described by this info instance, and to specify the + * annotation model used by it. + *

                        + * It also allows client to register as listeners on the represented vertical + * ruler and sends out notifications similar to selection events such as that a + * particular annotation presented in the vertical ruler has been selected. + * + * @see dwtx.jface.text.source.IVerticalRuler + * @see dwtx.jface.text.source.IAnnotationModel + * @since 3.0 + */ +public interface IVerticalRulerInfoExtension { + /** + * Returns the hover for this vertical ruler (column). + * + * @return the hover for this column + */ + IAnnotationHover getHover(); + + /** + * Returns the model currently used by the receiver. + * + * @return the model of the receiver, or null if no model is + * installed. + */ + IAnnotationModel getModel(); + + /** + * Registers a vertical ruler listener to be informed if an annotation gets + * selected on the vertical ruler. + * + * @param listener the listener to be informed + */ + void addVerticalRulerListener(IVerticalRulerListener listener); + + /** + * Removes a previously registered listener. If listener is not registered + * with the receiver, calling this method has no effect. + * + * @param listener the listener to be removed + */ + void removeVerticalRulerListener(IVerticalRulerListener listener); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/IVerticalRulerListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/IVerticalRulerListener.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.IVerticalRulerListener; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.widgets.Menu; + + +/** + * Interface for listening to annotation related events happening on a vertical ruler. + *

                        + * This interface may be implemented by clients. + *

                        + * + * @since 3.0 + */ +public interface IVerticalRulerListener { + + /** + * Called when an annotation is selected in the vertical ruler. + * + * @param event the annotation event that occurred + */ + void annotationSelected(VerticalRulerEvent event); + + /** + * Called when a default selection occurs on an + * annotation in the vertical ruler. + * + * @param event the annotation event that occurred + */ + void annotationDefaultSelected(VerticalRulerEvent event); + + /** + * Called when the context menu is opened on an annotation in the + * vertical ruler. + * + * @param event the annotation event that occurred + * @param menu the menu that is about to be shown + */ + void annotationContextMenuAboutToShow(VerticalRulerEvent event, Menu menu); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/ImageUtilities.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/ImageUtilities.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,159 @@ +/******************************************************************************* + * 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 + * 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.text.source.ImageUtilities; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.DWT; +import dwt.graphics.FontMetrics; +import dwt.graphics.GC; +import dwt.graphics.Image; +import dwt.graphics.Rectangle; +import dwt.widgets.Canvas; + +/** + * Provides methods for drawing images onto a canvas. + *

                        + * This class is neither intended to be instantiated nor subclassed. + *

                        + * + * @since 3.0 + * @noinstantiate This class is not intended to be instantiated by clients. + * @noextend This class is not intended to be subclassed by clients. + */ +public class ImageUtilities { + + /** + * Draws an image aligned inside the given rectangle on the given canvas. + * + * @param image the image to be drawn + * @param gc the drawing GC + * @param canvas the canvas on which to draw + * @param r the clipping rectangle + * @param halign the horizontal alignment of the image to be drawn + * @param valign the vertical alignment of the image to be drawn + */ + public static void drawImage(Image image, GC gc, Canvas canvas, Rectangle r, int halign, int valign) { + if (image !is null) { + + Rectangle bounds= image.getBounds(); + + int x= 0; + switch(halign) { + case DWT.LEFT: + break; + case DWT.CENTER: + x= (r.width - bounds.width) / 2; + break; + case DWT.RIGHT: + x= r.width - bounds.width; + break; + } + + int y= 0; + switch (valign) { + case DWT.TOP: { + FontMetrics fontMetrics= gc.getFontMetrics(); + y= (fontMetrics.getHeight() - bounds.height)/2; + break; + } + case DWT.CENTER: + y= (r.height - bounds.height) / 2; + break; + case DWT.BOTTOM: { + FontMetrics fontMetrics= gc.getFontMetrics(); + y= r.height - (fontMetrics.getHeight() + bounds.height)/2; + break; + } + } + + gc.drawImage(image, r.x+x, r.y+y); + } + } + + /** + * Draws an image aligned inside the given rectangle on the given canvas. + * + * @param image the image to be drawn + * @param gc the drawing GC + * @param canvas the canvas on which to draw + * @param r the clipping rectangle + * @param align the alignment of the image to be drawn + */ + public static void drawImage(Image image, GC gc, Canvas canvas, Rectangle r, int align_) { + drawImage(image, gc, canvas, r, align_, DWT.CENTER); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/JFaceTextMessages.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/JFaceTextMessages.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,139 @@ +/******************************************************************************* + * 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 + * 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.text.source.JFaceTextMessages; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + +import dwt.dwthelper.utils; + +import dwt.dwthelper.ResourceBundle; +import dwtx.dwtxhelper.MessageFormat; + +/** + * Accessor for the JFaceTextMessages.properties file in + * package dwtx.jface.text. + * @since 2.0 + */ +class JFaceTextMessages { + + /** The resource bundle name. */ +// private static const String RESOURCE_BUNDLE= "dwtx.jface.text.JFaceTextMessages";//$NON-NLS-1$ + + /** The resource bundle. */ + private static ResourceBundle fgResourceBundle;//= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + static this() { + fgResourceBundle = ResourceBundle.getBundle( + getImportData!("dwtx.jface.text.JFaceTextMessages.properties")); + } + + /** + * Prohibits the creation of accessor objects. + */ + private this() { + } + + /** + * Returns the string found in the resource bundle under the given key or a place holder string. + * + * @param key the look up key + * @return the value found under the given key + */ + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" ~ key ~ "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + } + + /** + * Gets a string from the resource bundle and formats it with the argument + * + * @param key the string used to get the bundle value, must not be null + * @param args arguments used when formatting the string + * @return the formatted string + * @since 3.0 + */ + public static String getFormattedString(String key, Object[] args...) { + String format= null; + try { + format= fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" ~ key ~ "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + return MessageFormat.format(format, args); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/LineChangeHover.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/LineChangeHover.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,397 @@ +/******************************************************************************* + * 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 + * 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.text.source.LineChangeHover; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + +import dwt.graphics.Point; +import dwt.widgets.Shell; +import dwtx.jface.action.ToolBarManager; +import dwtx.jface.text.DefaultInformationControl; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IInformationControl; +import dwtx.jface.text.IInformationControlCreator; +import dwtx.jface.text.information.IInformationProviderExtension2; + + +/** + * A hover for line oriented diffs. It determines the text to show as hover for a certain line in the + * document. + * + * @since 3.0 + */ +public class LineChangeHover : IAnnotationHover, IAnnotationHoverExtension, IInformationProviderExtension2 { + + /* + * @see dwtx.jface.text.source.IAnnotationHover#getHoverInfo(dwtx.jface.text.source.ISourceViewer, int) + */ + public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) { + return null; + } + + /** + * Formats the source w/ syntax coloring etc. This implementation replaces tabs with spaces. + * May be overridden by subclasses. + * + * @param content the hover content + * @return content reformatted + */ + protected String formatSource(String content) { + if (content !is null) { + StringBuffer sb= new StringBuffer(content); + final String tabReplacement= getTabReplacement(); + for (int pos= 0; pos < sb.length(); pos++) { + if (sb.slice()[pos] is '\t'){ + sb.select( pos, pos + 1); + sb.replace(tabReplacement); + } + } + return sb.toString(); + } + return content; + } + + /** + * Returns a replacement for the tab character. The default implementation + * returns a tabulator character, but subclasses may override to specify a + * number of spaces. + * + * @return a whitespace String that will be substituted for the tabulator + * character + */ + protected String getTabReplacement() { + return "\t"; //$NON-NLS-1$ + } + + /** + * Computes the content of the hover for the document contained in viewer on + * line line. + * + * @param viewer the connected viewer + * @param first the first line in viewer's document to consider + * @param last the last line in viewer's document to consider + * @param maxLines the max number of lines + * @return The hover content corresponding to the parameters + * @see #getHoverInfo(ISourceViewer, int) + * @see #getHoverInfo(ISourceViewer, ILineRange, int) + */ + private String computeContent(ISourceViewer viewer, int first, int last, int maxLines) { + ILineDiffer differ= getDiffer(viewer); + if (differ is null) + return null; + + final List lines= new LinkedList(); + for (int l= first; l <= last; l++) { + ILineDiffInfo info= differ.getLineInfo(l); + if (info !is null) + lines.add(cast(Object)info); + } + + return decorateText(lines, maxLines); + } + + /** + * Takes a list of ILineDiffInfos and computes a hover of at most maxLines. + * Added lines are prefixed with a '+', changed lines with '>' and + * deleted lines with '-'. + *

                        Deleted and added lines can even each other out, so that a number of deleted lines get + * displayed where - in the current document - the added lines are. + * + * @param diffInfos a List of ILineDiffInfo + * @param maxLines the maximum number of lines. Note that adding up all annotations might give + * more than that due to deleted lines. + * @return a String suitable for hover display + */ + protected String decorateText(List diffInfos, int maxLines) { + /* maxLines controls the size of the hover (not more than what fits into the display are of + * the viewer). + * added controls how many lines are added - added lines are + */ + String text= ""; //$NON-NLS-1$ + int added= 0; + for (Iterator it= diffInfos.iterator(); it.hasNext();) { + ILineDiffInfo info= cast(ILineDiffInfo)it.next(); + String[] original= info.getOriginalText(); + int type= info.getChangeType(); + int i= 0; + if (type is ILineDiffInfo.ADDED) + added++; + else if (type is ILineDiffInfo.CHANGED) { + text ~= "> " ~ (original.length > 0 ? original[i++] : ""); //$NON-NLS-1$ //$NON-NLS-2$ + maxLines--; + } else if (type is ILineDiffInfo.UNCHANGED) { + maxLines++; + } + if (maxLines is 0) + return trimTrailing(text); + for (; i < original.length; i++) { + text ~= "- " ~ original[i]; //$NON-NLS-1$ + added--; + if (--maxLines is 0) + return trimTrailing(text); + } + } + text= text.trim(); + if (text.length() is 0 && added-- > 0 && maxLines-- > 0) + text ~= "+ "; //$NON-NLS-1$ + while (added-- > 0 && maxLines-- > 0) + text ~= "\n+ "; //$NON-NLS-1$ + return text; + } + + /** + * Trims trailing spaces + * + * @param text a String + * @return a copy of text with trailing spaces removed + */ + private String trimTrailing(String text) { + int pos= text.length() - 1; + while (pos >= 0 && Character.isWhitespace(text.charAt(pos))) { + pos--; + } + return text.substring(0, pos + 1); + } + + /** + * Extracts the line differ - if any - from the viewer's document's annotation model. + * @param viewer the viewer + * @return a line differ for the document displayed in viewer, or null. + */ + private ILineDiffer getDiffer(ISourceViewer viewer) { + IAnnotationModel model= viewer.getAnnotationModel(); + + if (model is null) + return null; + + if ( cast(IAnnotationModelExtension)model ) { + IAnnotationModel diffModel= (cast(IAnnotationModelExtension)model).getAnnotationModel(cast(Object)IChangeRulerColumn.QUICK_DIFF_MODEL_ID); + if (diffModel !is null) + model= diffModel; + } + if ( cast(ILineDiffer)model ) { + if (cast(ILineDifferExtension2)model && (cast(ILineDifferExtension2)model).isSuspended()) + return null; + return cast(ILineDiffer)model; + } + return null; + } + + /** + * Computes the block of lines which form a contiguous block of changes covering line. + * + * @param viewer the source viewer showing + * @param line the line which a hover is displayed for + * @param min the first line in viewer's document to consider + * @param max the last line in viewer's document to consider + * @return the selection in the document displayed in viewer containing line + * that is covered by the hover information returned by the receiver. + */ + protected Point computeLineRange(ISourceViewer viewer, int line, int min, int max) { + /* Algorithm: + * All lines that have changes to themselves (added, changed) are taken that form a + * contiguous block of lines that includes line. + * + * If line is itself unchanged, if there is a deleted line either above or + * below, or both, the lines +/- 1 from line are included in the search as well, + * without applying this last rule to them, though. (I.e., if line is unchanged, + * but has a deleted line above, this one is taken in. If the line above has changes, the block + * is extended from there. If the line has no changes itself, the search stops). + * + * The block never extends the visible line range of the viewer. + */ + + ILineDiffer differ= getDiffer(viewer); + if (differ is null) + return new Point(-1, -1); + + // backward search + + int l= line; + ILineDiffInfo info= differ.getLineInfo(l); + // search backwards until a line has no changes to itself + while (l >= min && info !is null && (info.getChangeType() is ILineDiffInfo.CHANGED || info.getChangeType() is ILineDiffInfo.ADDED)) { + info= differ.getLineInfo(--l); + } + + int first= Math.min(l + 1, line); + + // forward search + + l= line; + info= differ.getLineInfo(l); + // search forward until a line has no changes to itself + while (l <= max && info !is null && (info.getChangeType() is ILineDiffInfo.CHANGED || info.getChangeType() is ILineDiffInfo.ADDED)) { + info= differ.getLineInfo(++l); + } + + int last= Math.max(l - 1, line); + + return new Point(first, last); + } + + /* + * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverInfo(dwtx.jface.text.source.ISourceViewer, dwtx.jface.text.source.ILineRange, int) + */ + public Object getHoverInfo(ISourceViewer sourceViewer, ILineRange lineRange, int visibleLines) { + int first= adaptFirstLine(sourceViewer, lineRange.getStartLine()); + int last= adaptLastLine(sourceViewer, lineRange.getStartLine() + lineRange.getNumberOfLines() - 1); + String content= computeContent(sourceViewer, first, last, visibleLines); + return stringcast(formatSource(content)); + } + + /** + * Adapts the start line to the implementation of ILineDiffInfo. + * + * @param viewer the source viewer + * @param startLine the line to adapt + * @return startLine - 1 if that line exists and is an + * unchanged line followed by deletions, startLine + * otherwise + */ + private int adaptFirstLine(ISourceViewer viewer, int startLine) { + ILineDiffer differ= getDiffer(viewer); + if (differ !is null && startLine > 0) { + int l= startLine - 1; + ILineDiffInfo info= differ.getLineInfo(l); + if (info !is null && info.getChangeType() is ILineDiffInfo.UNCHANGED && info.getRemovedLinesBelow() > 0) + return l; + } + return startLine; + } + + /** + * Adapts the last line to the implementation of ILineDiffInfo. + * + * @param viewer the source viewer + * @param lastLine the line to adapt + * @return lastLine - 1 if that line exists and is an + * unchanged line followed by deletions, startLine + * otherwise + */ + private int adaptLastLine(ISourceViewer viewer, int lastLine) { + ILineDiffer differ= getDiffer(viewer); + if (differ !is null && lastLine > 0) { + ILineDiffInfo info= differ.getLineInfo(lastLine); + if (info !is null && info.getChangeType() is ILineDiffInfo.UNCHANGED) + return lastLine - 1; + } + return lastLine; + } + + /* + * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverLineRange(dwtx.jface.text.source.ISourceViewer, int) + */ + public ILineRange getHoverLineRange(ISourceViewer viewer, int lineNumber) { + IDocument document= viewer.getDocument(); + if (document !is null) { + Point range= computeLineRange(viewer, lineNumber, 0, Math.max(0, document.getNumberOfLines() - 1)); + if (range.x !is -1 && range.y !is -1) + return new LineRange(range.x, range.y - range.x + 1); + } + return null; + } + + /* + * @see dwtx.jface.text.source.IAnnotationHoverExtension#canHandleMouseCursor() + */ + public bool canHandleMouseCursor() { + return false; + } + + /* + * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverControlCreator() + */ + public IInformationControlCreator getHoverControlCreator() { + return null; + } + + /* + * @see dwtx.jface.text.information.IInformationProviderExtension2#getInformationPresenterControlCreator() + * @since 3.2 + */ + public IInformationControlCreator getInformationPresenterControlCreator() { + return new class() IInformationControlCreator { + public IInformationControl createInformationControl(Shell parent) { + return new DefaultInformationControl(parent, cast(ToolBarManager)null, null); + } + }; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/LineNumberChangeRulerColumn.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/LineNumberChangeRulerColumn.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,456 @@ +/******************************************************************************* + * 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.text.source.LineNumberChangeRulerColumn; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + + + + +import dwt.graphics.Color; +import dwt.graphics.GC; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwtx.core.runtime.Assert; +import dwtx.jface.internal.text.revisions.RevisionPainter; +import dwtx.jface.internal.text.source.DiffPainter; +import dwtx.jface.text.revisions.IRevisionListener; +import dwtx.jface.text.revisions.IRevisionRulerColumn; +import dwtx.jface.text.revisions.IRevisionRulerColumnExtension; +import dwtx.jface.text.revisions.RevisionInformation; +import dwtx.jface.viewers.ISelectionProvider; + +/** + * A vertical ruler column displaying line numbers and serving as a UI for quick diff. + * Clients usually instantiate and configure object of this class. + * + * @since 3.0 + */ +public final class LineNumberChangeRulerColumn : LineNumberRulerColumn , IVerticalRulerInfo, IVerticalRulerInfoExtension, IChangeRulerColumn, IRevisionRulerColumn, IRevisionRulerColumnExtension { + + public Control getControl() { + return super.getControl(); + } + + /** The ruler's annotation model. */ + private IAnnotationModel fAnnotationModel; + /** true if changes should be displayed using character indications instead of background colors. */ + private bool fCharacterDisplay; + /** + * The revision painter strategy. + * + * @since 3.2 + */ + private const RevisionPainter fRevisionPainter; + /** + * The diff information painter strategy. + * + * @since 3.2 + */ + private const DiffPainter fDiffPainter; + /** + * Whether to show number or to behave like a change ruler column. + * @since 3.3 + */ + private bool fShowNumbers= true; + + /** + * Creates a new instance. + * + * @param sharedColors the shared colors provider to use + */ + public this(ISharedTextColors sharedColors) { + Assert.isNotNull(cast(Object)sharedColors); + fRevisionPainter= new RevisionPainter(this, sharedColors); + fDiffPainter= new DiffPainter(this, sharedColors); + } + + /* + * @see dwtx.jface.text.source.LineNumberRulerColumn#createControl(dwtx.jface.text.source.CompositeRuler, dwt.widgets.Composite) + */ + public Control createControl(CompositeRuler parentRuler, Composite parentControl) { + Control control= super.createControl(parentRuler, parentControl); + fRevisionPainter.setParentRuler(parentRuler); + fDiffPainter.setParentRuler(parentRuler); + return control; + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfo#getLineOfLastMouseButtonActivity() + */ + public int getLineOfLastMouseButtonActivity() { + return getParentRuler().getLineOfLastMouseButtonActivity(); + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfo#toDocumentLineNumber(int) + */ + public int toDocumentLineNumber(int y_coordinate) { + return getParentRuler().toDocumentLineNumber(y_coordinate); + } + + /* + * @see IVerticalRulerColumn#setModel(IAnnotationModel) + */ + public void setModel(IAnnotationModel model) { + setAnnotationModel(model); + fRevisionPainter.setModel(model); + fDiffPainter.setModel(model); + updateNumberOfDigits(); + computeIndentations(); + layout(true); + postRedraw(); + } + + private void setAnnotationModel(IAnnotationModel model) { + if (fAnnotationModel !is model) + fAnnotationModel= model; + } + + + /** + * Sets the display mode of the ruler. If character mode is set to true, diff + * information will be displayed textually on the line number ruler. + * + * @param characterMode true if diff information is to be displayed textually. + */ + public void setDisplayMode(bool characterMode) { + if (characterMode !is fCharacterDisplay) { + fCharacterDisplay= characterMode; + updateNumberOfDigits(); + computeIndentations(); + layout(true); + } + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getModel() + */ + public IAnnotationModel getModel() { + return fAnnotationModel; + } + + /* + * @see dwtx.jface.text.source.LineNumberRulerColumn#createDisplayString(int) + */ + protected String createDisplayString(int line) { + StringBuffer buffer= new StringBuffer(); + if (fShowNumbers) + buffer.append(super.createDisplayString(line)); + if (fCharacterDisplay && getModel() !is null) + buffer.append(fDiffPainter.getDisplayCharacter(line)); + return buffer.toString(); + } + + /* + * @see dwtx.jface.text.source.LineNumberRulerColumn#computeNumberOfDigits() + */ + protected int computeNumberOfDigits() { + int digits; + if (fCharacterDisplay && getModel() !is null) { + if (fShowNumbers) + digits= super.computeNumberOfDigits() + 1; + else + digits= 1; + } else { + if (fShowNumbers) + digits= super.computeNumberOfDigits(); + else + digits= 0; + } + if (fRevisionPainter.hasInformation()) + digits+= fRevisionPainter.getRequiredWidth(); + return digits; + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#addVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener) + */ + public void addVerticalRulerListener(IVerticalRulerListener listener) { + throw new UnsupportedOperationException(); + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#removeVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener) + */ + public void removeVerticalRulerListener(IVerticalRulerListener listener) { + throw new UnsupportedOperationException(); + } + + /* + * @see dwtx.jface.text.source.LineNumberRulerColumn#doPaint(dwt.graphics.GC) + */ + void doPaint(GC gc, ILineRange visibleLines) { + Color foreground= gc.getForeground(); + if (visibleLines !is null) { + if (fRevisionPainter.hasInformation()) + fRevisionPainter.paint(gc, visibleLines); + else if (fDiffPainter.hasInformation()) // don't paint quick diff colors if revisions are painted + fDiffPainter.paint(gc, visibleLines); + } + gc.setForeground(foreground); + if (fShowNumbers || fCharacterDisplay) + super.doPaint(gc, visibleLines); + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getHover() + */ + public IAnnotationHover getHover() { + int activeLine= getParentRuler().getLineOfLastMouseButtonActivity(); + if (fRevisionPainter.hasHover(activeLine)) + return fRevisionPainter.getHover(); + if (fDiffPainter.hasHover(activeLine)) + return fDiffPainter.getHover(); + return null; + } + + /* + * @see dwtx.jface.text.source.IChangeRulerColumn#setHover(dwtx.jface.text.source.IAnnotationHover) + */ + public void setHover(IAnnotationHover hover) { + fRevisionPainter.setHover(hover); + fDiffPainter.setHover(hover); + } + + /* + * @see dwtx.jface.text.source.IChangeRulerColumn#setBackground(dwt.graphics.Color) + */ + public void setBackground(Color background) { + super.setBackground(background); + fRevisionPainter.setBackground(background); + fDiffPainter.setBackground(background); + } + + /* + * @see dwtx.jface.text.source.IChangeRulerColumn#setAddedColor(dwt.graphics.Color) + */ + public void setAddedColor(Color addedColor) { + fDiffPainter.setAddedColor(addedColor); + } + + /* + * @see dwtx.jface.text.source.IChangeRulerColumn#setChangedColor(dwt.graphics.Color) + */ + public void setChangedColor(Color changedColor) { + fDiffPainter.setChangedColor(changedColor); + } + + /* + * @see dwtx.jface.text.source.IChangeRulerColumn#setDeletedColor(dwt.graphics.Color) + */ + public void setDeletedColor(Color deletedColor) { + fDiffPainter.setDeletedColor(deletedColor); + } + + /* + * @see dwtx.jface.text.revisions.IRevisionRulerColumn#setRevisionInformation(dwtx.jface.text.revisions.RevisionInformation) + */ + public void setRevisionInformation(RevisionInformation info) { + fRevisionPainter.setRevisionInformation(info); + updateNumberOfDigits(); + computeIndentations(); + layout(true); + postRedraw(); + } + + /* + * @see dwtx.jface.text.revisions.IRevisionRulerColumnExtension#getRevisionSelectionProvider() + * @since 3.2 + */ + public ISelectionProvider getRevisionSelectionProvider() { + return fRevisionPainter.getRevisionSelectionProvider(); + } + + /* + * @see dwtx.jface.text.revisions.IRevisionRulerColumnExtension#setRenderingMode(dwtx.jface.text.revisions.IRevisionRulerColumnExtension.RenderingMode) + * @since 3.3 + */ + public void setRevisionRenderingMode(RenderingMode renderingMode) { + fRevisionPainter.setRenderingMode(renderingMode); + } + + /** + * Sets the line number display mode. + * + * @param showNumbers true to show numbers, false to only show + * diff / revision info. + * @since 3.3 + */ + public void showLineNumbers(bool showNumbers) { + if (fShowNumbers !is showNumbers) { + fShowNumbers= showNumbers; + updateNumberOfDigits(); + computeIndentations(); + layout(true); + } + } + + /* + * @see dwtx.jface.text.source.LineNumberRulerColumn#getWidth() + * @since 3.3 + */ + public int getWidth() { + int width= super.getWidth(); + return width > 0 ? width : 8; // minimal width to display quick diff / revisions if no textual info is shown + } + + /** + * Returns true if the ruler is showing line numbers, false + * otherwise + * + * @return true if line numbers are shown, false otherwise + * @since 3.3 + */ + public bool isShowingLineNumbers() { + return fShowNumbers; + } + + /** + * Returns true if the ruler is showing revision information, false + * otherwise + * + * @return true if revision information is shown, false otherwise + * @since 3.3 + */ + public bool isShowingRevisionInformation() { + return fRevisionPainter.hasInformation(); + } + + /** + * Returns true if the ruler is showing change information, false + * otherwise + * + * @return true if change information is shown, false otherwise + * @since 3.3 + */ + public bool isShowingChangeInformation() { + return fDiffPainter.hasInformation(); + } + + /* + * @see dwtx.jface.text.revisions.IRevisionRulerColumnExtension#showRevisionAuthor(bool) + * @since 3.3 + */ + public void showRevisionAuthor(bool show) { + fRevisionPainter.showRevisionAuthor(show); + updateNumberOfDigits(); + computeIndentations(); + layout(true); + postRedraw(); + } + + /* + * @see dwtx.jface.text.revisions.IRevisionRulerColumnExtension#showRevisionId(bool) + * @since 3.3 + */ + public void showRevisionId(bool show) { + fRevisionPainter.showRevisionId(show); + updateNumberOfDigits(); + computeIndentations(); + layout(true); + postRedraw(); + } + + /* + * @see dwtx.jface.text.revisions.IRevisionRulerColumnExtension#addRevisionListener(dwtx.jface.text.revisions.IRevisionListener) + * @since 3.3 + */ + public void addRevisionListener(IRevisionListener listener) { + fRevisionPainter.addRevisionListener(listener); + } + + /* + * @see dwtx.jface.text.revisions.IRevisionRulerColumnExtension#removeRevisionListener(dwtx.jface.text.revisions.IRevisionListener) + * @since 3.3 + */ + public void removeRevisionListener(IRevisionListener listener) { + fRevisionPainter.removeRevisionListener(listener); + } + + /* + * @see dwtx.jface.text.source.LineNumberRulerColumn#handleDispose() + * @since 3.3 + */ + protected void handleDispose() { + fRevisionPainter.setParentRuler(null); + fRevisionPainter.setModel(null); + fDiffPainter.setParentRuler(null); + fDiffPainter.setModel(null); + super.handleDispose(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/LineNumberRulerColumn.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/LineNumberRulerColumn.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,974 @@ +/******************************************************************************* + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Nikolay Botev - [rulers] Shift clicking in line number column doesn't select range - https://bugs.eclipse.org/bugs/show_bug.cgi?id=32166 + * Nikolay Botev - [rulers] Clicking in line number ruler should not trigger annotation ruler - https://bugs.eclipse.org/bugs/show_bug.cgi?id=40889 + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.text.source.LineNumberRulerColumn; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + +import dwt.DWT; +import dwt.custom.StyledText; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.events.MouseEvent; +import dwt.events.MouseListener; +import dwt.events.MouseMoveListener; +import dwt.events.PaintEvent; +import dwt.events.PaintListener; +import dwt.graphics.Color; +import dwt.graphics.Font; +import dwt.graphics.FontMetrics; +import dwt.graphics.GC; +import dwt.graphics.Image; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Canvas; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.TypedListener; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextListener; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.ITextViewerExtension; +import dwtx.jface.text.ITextViewerExtension5; +import dwtx.jface.text.IViewportListener; +import dwtx.jface.text.JFaceTextUtil; +import dwtx.jface.text.TextEvent; + + +/** + * A vertical ruler column displaying line numbers. + * Clients usually instantiate and configure object of this class. + * + * @since 2.0 + */ +public class LineNumberRulerColumn : IVerticalRulerColumn { + + /** + * Internal listener class. + */ + class InternalListener : IViewportListener, ITextListener { + + /** + * @since 3.1 + */ + private bool fCachedRedrawState= true; + + /* + * @see IViewportListener#viewportChanged(int) + */ + public void viewportChanged(int verticalPosition) { + if (fCachedRedrawState && verticalPosition !is fScrollPos) + redraw(); + } + + /* + * @see ITextListener#textChanged(TextEvent) + */ + public void textChanged(TextEvent event) { + + fCachedRedrawState= event.getViewerRedrawState(); + if (!fCachedRedrawState) + return; + + if (updateNumberOfDigits()) { + computeIndentations(); + layout(event.getViewerRedrawState()); + return; + } + + bool viewerCompletelyShown= isViewerCompletelyShown(); + if (viewerCompletelyShown || fSensitiveToTextChanges || event.getDocumentEvent() is null) + postRedraw(); + fSensitiveToTextChanges= viewerCompletelyShown; + } + } + + /** + * Handles all the mouse interaction in this line number ruler column. + */ + class MouseHandler : MouseListener, MouseMoveListener { + + /** The cached view port size. */ + private int fCachedViewportSize; + /** The area of the line at which line selection started. */ + private int fStartLineOffset; + /** The number of the line at which line selection started. */ + private int fStartLineNumber; + /** The auto scroll direction. */ + private int fAutoScrollDirection; + /* @since 3.2 */ + private bool fIsListeningForMove= false; + + /* + * @see dwt.events.MouseListener#mouseUp(dwt.events.MouseEvent) + */ + public void mouseUp(MouseEvent event) { + // see bug 45700 + if (event.button is 1) { + stopSelecting(); + stopAutoScroll(); + } + } + + /* + * @see dwt.events.MouseListener#mouseDown(dwt.events.MouseEvent) + */ + public void mouseDown(MouseEvent event) { + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + // see bug 45700 + if (event.button is 1) { + startSelecting((event.stateMask & DWT.SHIFT) !is 0); + } + } + + /* + * @see dwt.events.MouseListener#mouseDoubleClick(dwt.events.MouseEvent) + */ + public void mouseDoubleClick(MouseEvent event) { + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + stopSelecting(); + stopAutoScroll(); + } + + /* + * @see dwt.events.MouseMoveListener#mouseMove(dwt.events.MouseEvent) + */ + public void mouseMove(MouseEvent event) { + if (fIsListeningForMove && !autoScroll(event)) { + int newLine= fParentRuler.toDocumentLineNumber(event.y); + expandSelection(newLine); + } + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + } + + /** + * Called when line drag selection started. Adds mouse move and track + * listeners to this column's control. + * + * @param expandExistingSelection if true the existing selection will be expanded, + * otherwise a new selection is started + */ + private void startSelecting(bool expandExistingSelection) { + try { + + // select line + IDocument document= fCachedTextViewer.getDocument(); + int lineNumber= fParentRuler.getLineOfLastMouseButtonActivity(); + if (expandExistingSelection && cast(ITextViewerExtension5)fCachedTextViewer + && fCachedTextViewer.getTextWidget() !is null) { + ITextViewerExtension5 extension5= (cast(ITextViewerExtension5)fCachedTextViewer); + // Find model curosr position + int widgetCaret= fCachedTextViewer.getTextWidget().getCaretOffset(); + int modelCaret= extension5.widgetOffset2ModelOffset(widgetCaret); + // Find model selection range + Point selection= fCachedTextViewer.getSelectedRange(); + // Start from tail of selection range (opposite of cursor position) + int startOffset= modelCaret is selection.x ? selection.x + selection.y : selection.x; + + fStartLineNumber= document.getLineOfOffset(startOffset); + fStartLineOffset= startOffset; + + expandSelection(lineNumber); + } else { + fStartLineNumber= lineNumber; + fStartLineOffset= document.getLineInformation(fStartLineNumber).getOffset(); + fCachedTextViewer.setSelectedRange(fStartLineOffset, 0); + } + fCachedViewportSize= getVisibleLinesInViewport(); + + // prepare for drag selection + fIsListeningForMove= true; + + } catch (BadLocationException x) { + } + } + + /** + * Called when line drag selection stopped. Removes all previously + * installed listeners from this column's control. + */ + private void stopSelecting() { + // drag selection stopped + fIsListeningForMove= false; + } + + /** + * Expands the line selection from the remembered start line to the + * given line. + * + * @param lineNumber the line to which to expand the selection + */ + private void expandSelection(int lineNumber) { + try { + + IDocument document= fCachedTextViewer.getDocument(); + IRegion lineInfo= document.getLineInformation(lineNumber); + + Display display= fCachedTextWidget.getDisplay(); + Point absolutePosition= display.getCursorLocation(); + Point relativePosition= fCachedTextWidget.toControl(absolutePosition); + + int offset; + + if (relativePosition.x < 0) + offset= lineInfo.getOffset(); + else { + try { + int widgetOffset= fCachedTextWidget.getOffsetAtLocation(relativePosition); + Point p= fCachedTextWidget.getLocationAtOffset(widgetOffset); + if (p.x > relativePosition.x) + widgetOffset--; + + // Convert to model offset + if ( cast(ITextViewerExtension5)fCachedTextViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5)fCachedTextViewer; + offset= extension.widgetOffset2ModelOffset(widgetOffset); + } else + offset= widgetOffset + fCachedTextViewer.getVisibleRegion().getOffset(); + + } catch (IllegalArgumentException ex) { + int lineEndOffset= lineInfo.getOffset() + lineInfo.getLength(); + + // Convert to widget offset + int lineEndWidgetOffset; + if ( cast(ITextViewerExtension5)fCachedTextViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5)fCachedTextViewer; + lineEndWidgetOffset= extension.modelOffset2WidgetOffset(lineEndOffset); + } else + lineEndWidgetOffset= lineEndOffset - fCachedTextViewer.getVisibleRegion().getOffset(); + + Point p= fCachedTextWidget.getLocationAtOffset(lineEndWidgetOffset); + if (p.x < relativePosition.x) + offset= lineEndOffset; + else + offset= lineInfo.getOffset(); + } + } + + int start= Math.min(fStartLineOffset, offset); + int end= Math.max(fStartLineOffset, offset); + + if (lineNumber < fStartLineNumber) + fCachedTextViewer.setSelectedRange(end, start - end); + else + fCachedTextViewer.setSelectedRange(start, end - start); + + } catch (BadLocationException x) { + } + } + + /** + * Called when auto scrolling stopped. Clears the auto scroll direction. + */ + private void stopAutoScroll() { + fAutoScrollDirection= DWT.NULL; + } + + /** + * Called on drag selection. + * + * @param event the mouse event caught by the mouse move listener + * @return true if scrolling happened, false otherwise + */ + private bool autoScroll(MouseEvent event) { + Rectangle area= fCanvas.getClientArea(); + + if (event.y > area.height) { + autoScroll(DWT.DOWN); + return true; + } + + if (event.y < 0) { + autoScroll(DWT.UP); + return true; + } + + stopAutoScroll(); + return false; + } + + /** + * Scrolls the viewer into the given direction. + * + * @param direction the scroll direction + */ + private void autoScroll(int direction) { + + if (fAutoScrollDirection is direction) + return; + + final int TIMER_INTERVAL= 5; + final Display display= fCanvas.getDisplay(); + Runnable timer= null; + switch (direction) { + case DWT.UP: + timer= new class() Runnable { + public void run() { + if (fAutoScrollDirection is DWT.UP) { + int top= getInclusiveTopIndex(); + if (top > 0) { + fCachedTextViewer.setTopIndex(top -1); + expandSelection(top -1); + display.timerExec(TIMER_INTERVAL, this); + } + } + } + }; + break; + case DWT.DOWN: + timer= new class() Runnable { + public void run() { + if (fAutoScrollDirection is DWT.DOWN) { + int top= getInclusiveTopIndex(); + fCachedTextViewer.setTopIndex(top +1); + expandSelection(top +1 + fCachedViewportSize); + display.timerExec(TIMER_INTERVAL, this); + } + } + }; + break; + } + + if (timer !is null) { + fAutoScrollDirection= direction; + display.timerExec(TIMER_INTERVAL, timer); + } + } + + /** + * Returns the viewer's first visible line, even if only partially visible. + * + * @return the viewer's first visible line + */ + private int getInclusiveTopIndex() { + if (fCachedTextWidget !is null && !fCachedTextWidget.isDisposed()) { + return JFaceTextUtil.getPartialTopIndex(fCachedTextViewer); + } + return -1; + } + } + + /** This column's parent ruler */ + private CompositeRuler fParentRuler; + /** Cached text viewer */ + private ITextViewer fCachedTextViewer; + /** Cached text widget */ + private StyledText fCachedTextWidget; + /** The columns canvas */ + private Canvas fCanvas; + /** Cache for the actual scroll position in pixels */ + private int fScrollPos; + /** The drawable for double buffering */ + private Image fBuffer; + /** The internal listener */ + private InternalListener fInternalListener; + /** The font of this column */ + private Font fFont; + /** The indentation cache */ + private int[] fIndentation; + /** Indicates whether this column reacts on text change events */ + private bool fSensitiveToTextChanges= false; + /** The foreground color */ + private Color fForeground; + /** The background color */ + private Color fBackground; + /** Cached number of displayed digits */ + private int fCachedNumberOfDigits= -1; + /** Flag indicating whether a relayout is required */ + private bool fRelayoutRequired= false; + /** + * Redraw runnable lock + * @since 3.0 + */ + private Object fRunnableLock; + /** + * Redraw runnable state + * @since 3.0 + */ + private bool fIsRunnablePosted= false; + /** + * Redraw runnable + * @since 3.0 + */ + private Runnable fRunnable; + private void fRunnable_init() { + fRunnable = new class() Runnable { + public void run() { + synchronized (fRunnableLock) { + fIsRunnablePosted= false; + } + redraw(); + } + }; + } + /* @since 3.2 */ + private MouseHandler fMouseHandler; + + + /** + * Constructs a new vertical ruler column. + */ + public this() { + fInternalListener= new InternalListener(); + fRunnableLock= new Object(); + fRunnable_init(); + } + + /** + * Sets the foreground color of this column. + * + * @param foreground the foreground color + */ + public void setForeground(Color foreground) { + fForeground= foreground; + } + + /** + * Returns the foreground color being used to print the line numbers. + * + * @return the configured foreground color + * @since 3.0 + */ + protected Color getForeground() { + return fForeground; + } + + /** + * Sets the background color of this column. + * + * @param background the background color + */ + public void setBackground(Color background) { + fBackground= background; + if (fCanvas !is null && !fCanvas.isDisposed()) + fCanvas.setBackground(getBackground(fCanvas.getDisplay())); + } + + /** + * Returns the System background color for list widgets. + * + * @param display the display + * @return the System background color for list widgets + */ + protected Color getBackground(Display display) { + if (fBackground is null) + return display.getSystemColor(DWT.COLOR_LIST_BACKGROUND); + return fBackground; + } + + /* + * @see IVerticalRulerColumn#getControl() + */ + public Control getControl() { + return fCanvas; + } + + /* + * @see IVerticalRuleColumnr#getWidth + */ + public int getWidth() { + return fIndentation[0]; + } + + /** + * Computes the number of digits to be displayed. Returns + * true if the number of digits changed compared + * to the previous call of this method. If the method is called + * for the first time, the return value is also true. + * + * @return whether the number of digits has been changed + * @since 3.0 + */ + protected bool updateNumberOfDigits() { + if (fCachedTextViewer is null) + return false; + + int digits= computeNumberOfDigits(); + + if (fCachedNumberOfDigits !is digits) { + fCachedNumberOfDigits= digits; + return true; + } + + return false; + } + + /** + * Does the real computation of the number of digits. Subclasses may override this method if + * they need extra space on the line number ruler. + * + * @return the number of digits to be displayed on the line number ruler. + */ + protected int computeNumberOfDigits() { + IDocument document= fCachedTextViewer.getDocument(); + int lines= document is null ? 0 : document.getNumberOfLines(); + + int digits= 2; + while (lines > Math.pow(cast(real)10.0, cast(uint)digits) -1) { + ++digits; + } + return digits; + } + + /** + * Layouts the enclosing viewer to adapt the layout to changes of the + * size of the individual components. + * + * @param redraw true if this column can be redrawn + */ + protected void layout(bool redraw) { + if (!redraw) { + fRelayoutRequired= true; + return; + } + + fRelayoutRequired= false; + if ( cast(ITextViewerExtension)fCachedTextViewer ) { + ITextViewerExtension extension= cast(ITextViewerExtension) fCachedTextViewer; + Control control= extension.getControl(); + if ( cast(Composite)control && !control.isDisposed()) { + Composite composite= cast(Composite) control; + composite.layout(true); + } + } + } + + /** + * Computes the indentations for the given font and stores them in + * fIndentation. + */ + protected void computeIndentations() { + if (fCanvas is null || fCanvas.isDisposed()) + return; + + GC gc= new GC(fCanvas); + try { + + gc.setFont(fCanvas.getFont()); + + fIndentation= new int[fCachedNumberOfDigits + 1]; + + char[] nines= new char[fCachedNumberOfDigits]; + Arrays.fill(nines, '9'); + String nineString= new_String(nines); + Point p= gc.stringExtent(nineString); + fIndentation[0]= p.x; + + for (int i= 1; i <= fCachedNumberOfDigits; i++) { + p= gc.stringExtent(nineString.substring(0, i)); + fIndentation[i]= fIndentation[0] - p.x; + } + + } finally { + gc.dispose(); + } + } + + /* + * @see IVerticalRulerColumn#createControl(CompositeRuler, Composite) + */ + public Control createControl(CompositeRuler parentRuler, Composite parentControl) { + + fParentRuler= parentRuler; + fCachedTextViewer= parentRuler.getTextViewer(); + fCachedTextWidget= fCachedTextViewer.getTextWidget(); + + fCanvas= new class(parentControl, DWT.NO_FOCUS ) Canvas { + this(Composite c, int s ){ + super(c,s); + } + /* + * @see dwt.widgets.Control#addMouseListener(dwt.events.MouseListener) + * @since 3.4 + */ + public void addMouseListener(MouseListener listener) { + // see bug 40889, bug 230073 and AnnotationRulerColumn#isPropagatingMouseListener() + if (listener is fMouseHandler) + super.addMouseListener(listener); + else { + TypedListener typedListener= null; + if (listener !is null) + typedListener= new TypedListener(listener); + addListener(DWT.MouseDoubleClick, typedListener); + } + } + }; + fCanvas.setBackground(getBackground(fCanvas.getDisplay())); + fCanvas.setForeground(fForeground); + + fCanvas.addPaintListener(new class() PaintListener { + public void paintControl(PaintEvent event) { + if (fCachedTextViewer !is null) + doubleBufferPaint(event.gc); + } + }); + + fCanvas.addDisposeListener(new class() DisposeListener { + public void widgetDisposed(DisposeEvent e) { + handleDispose(); + fCachedTextViewer= null; + fCachedTextWidget= null; + } + }); + + fMouseHandler= new MouseHandler(); + fCanvas.addMouseListener(fMouseHandler); + fCanvas.addMouseMoveListener(fMouseHandler); + + if (fCachedTextViewer !is null) { + + fCachedTextViewer.addViewportListener(fInternalListener); + fCachedTextViewer.addTextListener(fInternalListener); + + if (fFont is null) { + if (fCachedTextWidget !is null && !fCachedTextWidget.isDisposed()) + fFont= fCachedTextWidget.getFont(); + } + } + + if (fFont !is null) + fCanvas.setFont(fFont); + + updateNumberOfDigits(); + computeIndentations(); + return fCanvas; + } + + /** + * Disposes the column's resources. + */ + protected void handleDispose() { + + if (fCachedTextViewer !is null) { + fCachedTextViewer.removeViewportListener(fInternalListener); + fCachedTextViewer.removeTextListener(fInternalListener); + } + + if (fBuffer !is null) { + fBuffer.dispose(); + fBuffer= null; + } + } + + /** + * Double buffer drawing. + * + * @param dest the GC to draw into + */ + private void doubleBufferPaint(GC dest) { + + Point size= fCanvas.getSize(); + + if (size.x <= 0 || size.y <= 0) + return; + + if (fBuffer !is null) { + Rectangle r= fBuffer.getBounds(); + if (r.width !is size.x || r.height !is size.y) { + fBuffer.dispose(); + fBuffer= null; + } + } + if (fBuffer is null) + fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y); + + GC gc= new GC(fBuffer); + gc.setFont(fCanvas.getFont()); + if (fForeground !is null) + gc.setForeground(fForeground); + + try { + gc.setBackground(getBackground(fCanvas.getDisplay())); + gc.fillRectangle(0, 0, size.x, size.y); + + ILineRange visibleLines= JFaceTextUtil.getVisibleModelLines(fCachedTextViewer); + if (visibleLines is null) + return; + fScrollPos= fCachedTextWidget.getTopPixel(); + doPaint(gc, visibleLines); + } finally { + gc.dispose(); + } + + dest.drawImage(fBuffer, 0, 0); + } + + /** + * Returns the view port height in lines. + * + * @return the view port height in lines + * @deprecated as of 3.2 the number of lines in the viewport cannot be computed because + * StyledText supports variable line heights + */ + protected int getVisibleLinesInViewport() { + return getVisibleLinesInViewport(fCachedTextWidget); + } + + + /** + * Returns true if the viewport displays the entire viewer contents, i.e. the + * viewer is not vertically scrollable. + * + * @return true if the viewport displays the entire contents, false otherwise + * @since 3.2 + */ + protected final bool isViewerCompletelyShown() { + return JFaceTextUtil.isShowingEntireContents(fCachedTextWidget); + } + + /** + * Draws the ruler column. + * + * @param gc the GC to draw into + * @param visibleLines the visible model lines + * @since 3.2 + */ + void doPaint(GC gc, ILineRange visibleLines) { + Display display= fCachedTextWidget.getDisplay(); + + // draw diff info + int y= -JFaceTextUtil.getHiddenTopLinePixels(fCachedTextWidget); + + int lastLine= end(visibleLines); + for (int line= visibleLines.getStartLine(); line < lastLine; line++) { + int widgetLine= JFaceTextUtil.modelLineToWidgetLine(fCachedTextViewer, line); + if (widgetLine is -1) + continue; + + int lineHeight= fCachedTextWidget.getLineHeight(fCachedTextWidget.getOffsetAtLine(widgetLine)); + paintLine(line, y, lineHeight, gc, display); + y += lineHeight; + } + } + + /* @since 3.2 */ + private static int end(ILineRange range) { + return range.getStartLine() + range.getNumberOfLines(); + } + + /** + * Computes the string to be printed for line. The default implementation returns + * Integer.toString(line + 1). + * + * @param line the line number for which the line number string is generated + * @return the string to be printed on the line number bar for line + * @since 3.0 + */ + protected String createDisplayString(int line) { + return Integer.toString(line + 1); + } + + /** + * Returns the difference between the baseline of the widget and the + * baseline as specified by the font for gc. When drawing + * line numbers, the returned bias should be added to obtain text lined up + * on the correct base line of the text widget. + * + * @param gc the GC to get the font metrics from + * @param widgetLine the widget line + * @return the baseline bias to use when drawing text that is lined up with + * fCachedTextWidget + * @since 3.2 + */ + private int getBaselineBias(GC gc, int widgetLine) { + /* + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=62951 + * widget line height may be more than the font height used for the + * line numbers, since font styles (bold, italics...) can have larger + * font metrics than the simple font used for the numbers. + */ + int offset= fCachedTextWidget.getOffsetAtLine(widgetLine); + int widgetBaseline= fCachedTextWidget.getBaseline(offset); + + FontMetrics fm= gc.getFontMetrics(); + int fontBaseline= fm.getAscent() + fm.getLeading(); + int baselineBias= widgetBaseline - fontBaseline; + return Math.max(0, baselineBias); + } + + /** + * Paints the line. After this method is called the line numbers are painted on top + * of the result of this method. + * + * @param line the line of the document which the ruler is painted for + * @param y the y-coordinate of the box being painted for line, relative to gc + * @param lineheight the height of one line (and therefore of the box being painted) + * @param gc the drawing context the client may choose to draw on. + * @param display the display the drawing occurs on + * @since 3.0 + */ + protected void paintLine(int line, int y, int lineheight, GC gc, Display display) { + int widgetLine= JFaceTextUtil.modelLineToWidgetLine(fCachedTextViewer, line); + + String s= createDisplayString(line); + int indentation= fIndentation[s.length]; + int baselineBias= getBaselineBias(gc, widgetLine); + gc.drawString(s, indentation, y + baselineBias, true); + } + + /** + * Triggers a redraw in the display thread. + * + * @since 3.0 + */ + protected final void postRedraw() { + if (fCanvas !is null && !fCanvas.isDisposed()) { + Display d= fCanvas.getDisplay(); + if (d !is null) { + synchronized (fRunnableLock) { + if (fIsRunnablePosted) + return; + fIsRunnablePosted= true; + } + d.asyncExec(fRunnable); + } + } + } + + /* + * @see IVerticalRulerColumn#redraw() + */ + public void redraw() { + + if (fRelayoutRequired) { + layout(true); + return; + } + + if (fCachedTextViewer !is null && fCanvas !is null && !fCanvas.isDisposed()) { + GC gc= new GC(fCanvas); + doubleBufferPaint(gc); + gc.dispose(); + } + } + + /* + * @see IVerticalRulerColumn#setModel(IAnnotationModel) + */ + public void setModel(IAnnotationModel model) { + } + + /* + * @see IVerticalRulerColumn#setFont(Font) + */ + public void setFont(Font font) { + fFont= font; + if (fCanvas !is null && !fCanvas.isDisposed()) { + fCanvas.setFont(fFont); + updateNumberOfDigits(); + computeIndentations(); + } + } + + /** + * Returns the parent (composite) ruler of this ruler column. + * + * @return the parent ruler + * @since 3.0 + */ + protected CompositeRuler getParentRuler() { + return fParentRuler; + } + + + /** + * Returns the number of lines in the view port. + * + * @param textWidget + * @return the number of lines visible in the view port -1 if there's no client area + * @deprecated this method should not be used - it relies on the widget using a uniform line height + */ + static int getVisibleLinesInViewport(StyledText textWidget) { + if (textWidget !is null) { + Rectangle clArea= textWidget.getClientArea(); + if (!clArea.isEmpty()) { + int firstPixel= 0; + int lastPixel= clArea.height - 1; // XXX what about margins? don't take trims as they include scrollbars + int first= JFaceTextUtil.getLineIndex(textWidget, firstPixel); + int last= JFaceTextUtil.getLineIndex(textWidget, lastPixel); + return last - first; + } + } + return -1; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/LineRange.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/LineRange.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.LineRange; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Default implementation of {@link ILineRange}. + * + * @since 3.0 + */ +public final class LineRange : ILineRange { + + private int fStartLine; + private int fNumberOfLines; + + /** + * Creates a new line range with the given specification. + * + * @param startLine the start line + * @param numberOfLines the number of lines + */ + public this(int startLine, int numberOfLines) { + fStartLine= startLine; + fNumberOfLines= numberOfLines; + } + + /* + * @see dwtx.jface.text.source.ILineRange#getStartLine() + */ + public int getStartLine() { + return fStartLine; + } + + /* + * @see dwtx.jface.text.source.ILineRange#getNumberOfLines() + */ + public int getNumberOfLines() { + return fNumberOfLines; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/MatchingCharacterPainter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/MatchingCharacterPainter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,341 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.MatchingCharacterPainter; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + + + +import dwt.custom.StyledText; +import dwt.events.PaintEvent; +import dwt.events.PaintListener; +import dwt.graphics.Color; +import dwt.graphics.GC; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IPaintPositionManager; +import dwtx.jface.text.IPainter; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextViewerExtension5; +import dwtx.jface.text.Position; +import dwtx.jface.text.Region; + +/** + * Highlights the peer character matching the character near the caret position. + * This painter can be configured with an + * {@link dwtx.jface.text.source.ICharacterPairMatcher}. + *

                        + * Clients instantiate and configure object of this class.

                        + * + * @since 2.1 + */ +public final class MatchingCharacterPainter : IPainter, PaintListener { + + /** Indicates whether this painter is active */ + private bool fIsActive= false; + /** The source viewer this painter is associated with */ + private ISourceViewer fSourceViewer; + /** The viewer's widget */ + private StyledText fTextWidget; + /** The color in which to highlight the peer character */ + private Color fColor; + /** The paint position manager */ + private IPaintPositionManager fPaintPositionManager; + /** The strategy for finding matching characters */ + private ICharacterPairMatcher fMatcher; + /** The position tracking the matching characters */ + private Position fPairPosition; + /** The anchor indicating whether the character is left or right of the caret */ + private int fAnchor; + + + /** + * Creates a new MatchingCharacterPainter for the given source viewer using + * the given character pair matcher. The character matcher is not adopted by + * this painter. Thus, it is not disposed. However, this painter requires + * exclusive access to the given pair matcher. + * + * @param sourceViewer + * @param matcher + */ + public this(ISourceViewer sourceViewer, ICharacterPairMatcher matcher) { + fPairPosition= new Position(0, 0); + fSourceViewer= sourceViewer; + fMatcher= matcher; + fTextWidget= sourceViewer.getTextWidget(); + } + + /** + * Sets the color in which to highlight the match character. + * + * @param color the color + */ + public void setColor(Color color) { + fColor= color; + } + + /* + * @see dwtx.jface.text.IPainter#dispose() + */ + public void dispose() { + if (fMatcher !is null) { + fMatcher.clear(); + fMatcher= null; + } + + fColor= null; + fTextWidget= null; + } + + /* + * @see dwtx.jface.text.IPainter#deactivate(bool) + */ + public void deactivate(bool redraw) { + if (fIsActive) { + fIsActive= false; + fTextWidget.removePaintListener(this); + if (fPaintPositionManager !is null) + fPaintPositionManager.unmanagePosition(fPairPosition); + if (redraw) + handleDrawRequest(null); + } + } + + /* + * @see dwt.events.PaintListener#paintControl(dwt.events.PaintEvent) + */ + public void paintControl(PaintEvent event) { + if (fTextWidget !is null) + handleDrawRequest(event.gc); + } + + /** + * Handles a redraw request. + * + * @param gc the GC to draw into. + */ + private void handleDrawRequest(GC gc) { + + if (fPairPosition.isDeleted) + return; + + int offset= fPairPosition.getOffset(); + int length= fPairPosition.getLength(); + if (length < 1) + return; + + if ( cast(ITextViewerExtension5)fSourceViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) fSourceViewer; + IRegion widgetRange= extension.modelRange2WidgetRange(new Region(offset, length)); + if (widgetRange is null) + return; + + try { + // don't draw if the pair position is really hidden and widgetRange just + // marks the coverage around it. + IDocument doc= fSourceViewer.getDocument(); + int startLine= doc.getLineOfOffset(offset); + int endLine= doc.getLineOfOffset(offset + length); + if (extension.modelLine2WidgetLine(startLine) is -1 || extension.modelLine2WidgetLine(endLine) is -1) + return; + } catch (BadLocationException e) { + return; + } + + offset= widgetRange.getOffset(); + length= widgetRange.getLength(); + + } else { + IRegion region= fSourceViewer.getVisibleRegion(); + if (region.getOffset() > offset || region.getOffset() + region.getLength() < offset + length) + return; + offset -= region.getOffset(); + } + + if (ICharacterPairMatcher.RIGHT is fAnchor) + draw(gc, offset, 1); + else + draw(gc, offset + length -1, 1); + } + + /** + * Highlights the given widget region. + * + * @param gc the GC to draw into + * @param offset the offset of the widget region + * @param length the length of the widget region + */ + private void draw(GC gc, int offset, int length) { + if (gc !is null) { + + gc.setForeground(fColor); + + Rectangle bounds; + if (length > 0) + bounds= fTextWidget.getTextBounds(offset, offset + length - 1); + else { + Point loc= fTextWidget.getLocationAtOffset(offset); + bounds= new Rectangle(loc.x, loc.y, 1, fTextWidget.getLineHeight(offset)); + } + + // draw box around line segment + gc.drawRectangle(bounds.x, bounds.y, bounds.width - 1, bounds.height - 1); + + // draw box around character area +// int widgetBaseline= fTextWidget.getBaseline(); +// FontMetrics fm= gc.getFontMetrics(); +// int fontBaseline= fm.getAscent() + fm.getLeading(); +// int fontBias= widgetBaseline - fontBaseline; + +// gc.drawRectangle(left.x, left.y + fontBias, right.x - left.x - 1, fm.getHeight() - 1); + + } else { + fTextWidget.redrawRange(offset, length, true); + } + } + + /* + * @see dwtx.jface.text.IPainter#paint(int) + */ + public void paint(int reason) { + + IDocument document= fSourceViewer.getDocument(); + if (document is null) { + deactivate(false); + return; + } + + Point selection= fSourceViewer.getSelectedRange(); + if (selection.y > 0) { + deactivate(true); + return; + } + + IRegion pair= fMatcher.match(document, selection.x); + if (pair is null) { + deactivate(true); + return; + } + + if (fIsActive) { + + if (IPainter.CONFIGURATION is reason) { + + // redraw current highlighting + handleDrawRequest(null); + + } else if (pair.getOffset() !is fPairPosition.getOffset() || + pair.getLength() !is fPairPosition.getLength() || + fMatcher.getAnchor() !is fAnchor) { + + // otherwise only do something if position is different + + // remove old highlighting + handleDrawRequest(null); + // update position + fPairPosition.isDeleted_= false; + fPairPosition.offset= pair.getOffset(); + fPairPosition.length= pair.getLength(); + fAnchor= fMatcher.getAnchor(); + // apply new highlighting + handleDrawRequest(null); + + } + } else { + + fIsActive= true; + + fPairPosition.isDeleted_= false; + fPairPosition.offset= pair.getOffset(); + fPairPosition.length= pair.getLength(); + fAnchor= fMatcher.getAnchor(); + + fTextWidget.addPaintListener(this); + fPaintPositionManager.managePosition(fPairPosition); + handleDrawRequest(null); + } + } + + /* + * @see dwtx.jface.text.IPainter#setPositionManager(dwtx.jface.text.IPaintPositionManager) + */ + public void setPositionManager(IPaintPositionManager manager) { + fPaintPositionManager= manager; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/OverviewRuler.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/OverviewRuler.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,1442 @@ +/******************************************************************************* + * 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 + * 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.text.source.OverviewRuler; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + + + + + +import dwt.DWT; +import dwt.custom.StyledText; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.events.MouseAdapter; +import dwt.events.MouseEvent; +import dwt.events.MouseMoveListener; +import dwt.events.MouseTrackAdapter; +import dwt.events.PaintEvent; +import dwt.events.PaintListener; +import dwt.graphics.Color; +import dwt.graphics.Cursor; +import dwt.graphics.GC; +import dwt.graphics.Image; +import dwt.graphics.Point; +import dwt.graphics.RGB; +import dwt.graphics.Rectangle; +import dwt.widgets.Canvas; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextListener; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.ITextViewerExtension5; +import dwtx.jface.text.JFaceTextUtil; +import dwtx.jface.text.Position; +import dwtx.jface.text.Region; +import dwtx.jface.text.TextEvent; +import dwtx.jface.text.source.projection.AnnotationBag; + + +/** + * Ruler presented next to a source viewer showing all annotations of the + * viewer's annotation model in a compact format. The ruler has the same height + * as the source viewer. + *

                        + * Clients usually instantiate and configure objects of this class.

                        + * + * @since 2.1 + */ +public class OverviewRuler : IOverviewRuler { + + /** + * Internal listener class. + */ + class InternalListener : ITextListener, IAnnotationModelListener, IAnnotationModelListenerExtension { + + /* + * @see ITextListener#textChanged + */ + public void textChanged(TextEvent e) { + if (fTextViewer !is null && e.getDocumentEvent() is null && e.getViewerRedrawState()) { + // handle only changes of visible document + redraw(); + } + } + + /* + * @see IAnnotationModelListener#modelChanged(IAnnotationModel) + */ + public void modelChanged(IAnnotationModel model) { + update(); + } + + /* + * @see dwtx.jface.text.source.IAnnotationModelListenerExtension#modelChanged(dwtx.jface.text.source.AnnotationModelEvent) + * @since 3.3 + */ + public void modelChanged(AnnotationModelEvent event) { + if (!event.isValid()) + return; + + if (event.isWorldChange()) { + update(); + return; + } + + Annotation[] annotations= event.getAddedAnnotations(); + int length= annotations.length; + for (int i= 0; i < length; i++) { + if (!skip(annotations[i].getType())) { + update(); + return; + } + } + + annotations= event.getRemovedAnnotations(); + length= annotations.length; + for (int i= 0; i < length; i++) { + if (!skip(annotations[i].getType())) { + update(); + return; + } + } + + annotations= event.getChangedAnnotations(); + length= annotations.length; + for (int i= 0; i < length; i++) { + if (!skip(annotations[i].getType())) { + update(); + return; + } + } + + } + } + + /** + * Enumerates the annotations of a specified type and characteristics + * of the associated annotation model. + */ + class FilterIterator : Iterator { + + final static int TEMPORARY= 1 << 1; + final static int PERSISTENT= 1 << 2; + final static int IGNORE_BAGS= 1 << 3; + + private Iterator fIterator; + private Object fType; + private Annotation fNext; + private int fStyle; + + /** + * Creates a new filter iterator with the given specification. + * + * @param annotationType the annotation type + * @param style the style + */ + public this(Object annotationType, int style) { + fType= annotationType; + fStyle= style; + if (fModel !is null) { + fIterator= fModel.getAnnotationIterator(); + skip(); + } + } + + /** + * Creates a new filter iterator with the given specification. + * + * @param annotationType the annotation type + * @param style the style + * @param iterator the iterator + */ + public this(Object annotationType, int style, Iterator iterator) { + fType= annotationType; + fStyle= style; + fIterator= iterator; + skip(); + } + + private void skip() { + + bool temp= (fStyle & TEMPORARY) !is 0; + bool pers= (fStyle & PERSISTENT) !is 0; + bool ignr= (fStyle & IGNORE_BAGS) !is 0; + + while (fIterator.hasNext()) { + Annotation next= cast(Annotation) fIterator.next(); + + if (next.isMarkedDeleted()) + continue; + + if (ignr && ( cast(AnnotationBag)next )) + continue; + + fNext= next; + Object annotationType= stringcast(next.getType()); + if (fType is null || fType.opEquals(annotationType) || !fConfiguredAnnotationTypes.contains(annotationType) && isSubtype(annotationType)) { + if (temp && pers) return; + if (pers && next.isPersistent()) return; + if (temp && !next.isPersistent()) return; + } + } + fNext= null; + } + + private bool isSubtype(Object annotationType) { + if ( cast(IAnnotationAccessExtension)fAnnotationAccess ) { + IAnnotationAccessExtension extension= cast(IAnnotationAccessExtension) fAnnotationAccess; + return extension.isSubtype(annotationType, fType); + } + return cast(bool) fType.opEquals(annotationType); + } + + /* + * @see Iterator#hasNext() + */ + public bool hasNext() { + return fNext !is null; + } + /* + * @see Iterator#next() + */ + public Object next() { + try { + return fNext; + } finally { + if (fIterator !is null) + skip(); + } + } + /* + * @see Iterator#remove() + */ + public void remove() { + throw new UnsupportedOperationException(); + } + } + + /** + * The painter of the overview ruler's header. + */ + class HeaderPainter : PaintListener { + + private Color fIndicatorColor; + private Color fSeparatorColor; + + /** + * Creates a new header painter. + */ + public this() { + fSeparatorColor= fHeader.getDisplay().getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW); + } + + /** + * Sets the header color. + * + * @param color the header color + */ + public void setColor(Color color) { + fIndicatorColor= color; + } + + private void drawBevelRect(GC gc, int x, int y, int w, int h, Color topLeft, Color bottomRight) { + gc.setForeground(topLeft is null ? fSeparatorColor : topLeft); + gc.drawLine(x, y, x + w -1, y); + gc.drawLine(x, y, x, y + h -1); + + gc.setForeground(bottomRight is null ? fSeparatorColor : bottomRight); + gc.drawLine(x + w, y, x + w, y + h); + gc.drawLine(x, y + h, x + w, y + h); + } + + public void paintControl(PaintEvent e) { + if (fIndicatorColor is null) + return; + + Point s= fHeader.getSize(); + + e.gc.setBackground(fIndicatorColor); + Rectangle r= new Rectangle(INSET, (s.y - (2*ANNOTATION_HEIGHT)) / 2, s.x - (2*INSET), 2*ANNOTATION_HEIGHT); + e.gc.fillRectangle(r); + Display d= fHeader.getDisplay(); + if (d !is null) +// drawBevelRect(e.gc, r.x, r.y, r.width -1, r.height -1, d.getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW), d.getSystemColor(DWT.COLOR_WIDGET_HIGHLIGHT_SHADOW)); + drawBevelRect(e.gc, r.x, r.y, r.width -1, r.height -1, null, null); + + e.gc.setForeground(fSeparatorColor); + e.gc.setLineWidth(0); // NOTE: 0 means width is 1 but with optimized performance + e.gc.drawLine(0, s.y -1, s.x -1, s.y -1); + } + } + + private static const int INSET= 2; + private static const int ANNOTATION_HEIGHT= 4; + private static bool ANNOTATION_HEIGHT_SCALABLE= true; + + + /** The model of the overview ruler */ + private IAnnotationModel fModel; + /** The view to which this ruler is connected */ + private ITextViewer fTextViewer; + /** The ruler's canvas */ + private Canvas fCanvas; + /** The ruler's header */ + private Canvas fHeader; + /** The buffer for double buffering */ + private Image fBuffer; + /** The internal listener */ + private InternalListener fInternalListener; + /** The width of this vertical ruler */ + private int fWidth; + /** The hit detection cursor */ + private Cursor fHitDetectionCursor; + /** The last cursor */ + private Cursor fLastCursor; + /** The line of the last mouse button activity */ + private int fLastMouseButtonActivityLine= -1; + /** The actual annotation height */ + private int fAnnotationHeight= -1; + /** The annotation access */ + private IAnnotationAccess fAnnotationAccess; + /** The header painter */ + private HeaderPainter fHeaderPainter; + /** + * The list of annotation types to be shown in this ruler. + * @since 3.0 + */ + private Set fConfiguredAnnotationTypes; + /** + * The list of annotation types to be shown in the header of this ruler. + * @since 3.0 + */ + private Set fConfiguredHeaderAnnotationTypes; + /** The mapping between annotation types and colors */ + private Map fAnnotationTypes2Colors; + /** The color manager */ + private ISharedTextColors fSharedTextColors; + /** + * All available annotation types sorted by layer. + * + * @since 3.0 + */ + private List fAnnotationsSortedByLayer; + /** + * All available layers sorted by layer. + * This list may contain duplicates. + * @since 3.0 + */ + private List fLayersSortedByLayer; + /** + * Map of allowed annotation types. + * An allowed annotation type maps to true, a disallowed + * to false. + * @since 3.0 + */ + private Map fAllowedAnnotationTypes; + /** + * Map of allowed header annotation types. + * An allowed annotation type maps to true, a disallowed + * to false. + * @since 3.0 + */ + private Map fAllowedHeaderAnnotationTypes; + /** + * The cached annotations. + * @since 3.0 + */ + private List fCachedAnnotations; + + /** + * Redraw runnable lock + * @since 3.3 + */ + private Object fRunnableLock; + /** + * Redraw runnable state + * @since 3.3 + */ + private bool fIsRunnablePosted= false; + /** + * Redraw runnable + * @since 3.3 + */ + private Runnable fRunnable; + /** + * Tells whether temporary annotations are drawn with + * a separate color. This color will be computed by + * discoloring the original annotation color. + * + * @since 3.4 + */ + private bool fIsTemporaryAnnotationDiscolored; + + + /** + * Constructs a overview ruler of the given width using the given annotation access and the given + * color manager. + *

                        Note: As of 3.4, temporary annotations are no longer discolored. + * Use {@link #OverviewRuler(IAnnotationAccess, int, ISharedTextColors, bool)} if you + * want to keep the old behavior.

                        + * + * @param annotationAccess the annotation access + * @param width the width of the vertical ruler + * @param sharedColors the color manager + */ + public this(IAnnotationAccess annotationAccess, int width, ISharedTextColors sharedColors) { + this(annotationAccess, width, sharedColors, false); + } + + /** + * Constructs a overview ruler of the given width using the given annotation + * access and the given color manager. + * + * @param annotationAccess the annotation access + * @param width the width of the vertical ruler + * @param sharedColors the color manager + * @param discolorTemporaryAnnotation true if temporary annotations should be discolored + * @since 3.4 + */ + public this(IAnnotationAccess annotationAccess, int width, ISharedTextColors sharedColors, bool discolorTemporaryAnnotation) { + // DWT instance init + fInternalListener= new InternalListener(); + fConfiguredAnnotationTypes= new HashSet(); + fConfiguredHeaderAnnotationTypes= new HashSet(); + fAnnotationTypes2Colors= new HashMap(); + fAnnotationsSortedByLayer= new ArrayList(); + fLayersSortedByLayer= new ArrayList(); + fAllowedAnnotationTypes= new HashMap(); + fAllowedHeaderAnnotationTypes= new HashMap(); + fCachedAnnotations= new ArrayList(); + fRunnableLock= new Object(); + fRunnable= dgRunnable( { + synchronized (fRunnableLock) { + fIsRunnablePosted= false; + } + redraw(); + updateHeader(); + }); + + fAnnotationAccess= annotationAccess; + fWidth= width; + fSharedTextColors= sharedColors; + fIsTemporaryAnnotationDiscolored= discolorTemporaryAnnotation; + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfo#getControl() + */ + public Control getControl() { + return fCanvas; + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerInfo#getWidth() + */ + public int getWidth() { + return fWidth; + } + + /* + * @see dwtx.jface.text.source.IVerticalRuler#setModel(dwtx.jface.text.source.IAnnotationModel) + */ + public void setModel(IAnnotationModel model) { + if (model !is fModel || model !is null) { + + if (fModel !is null) + fModel.removeAnnotationModelListener(fInternalListener); + + fModel= model; + + if (fModel !is null) + fModel.addAnnotationModelListener(fInternalListener); + + update(); + } + } + + /* + * @see dwtx.jface.text.source.IVerticalRuler#createControl(dwt.widgets.Composite, dwtx.jface.text.ITextViewer) + */ + public Control createControl(Composite parent, ITextViewer textViewer) { + + fTextViewer= textViewer; + + fHitDetectionCursor= new Cursor(parent.getDisplay(), DWT.CURSOR_HAND); + + fHeader= new Canvas(parent, DWT.NONE); + + if ( cast(IAnnotationAccessExtension)fAnnotationAccess ) { + fHeader.addMouseTrackListener(new class() MouseTrackAdapter { + /* + * @see dwt.events.MouseTrackAdapter#mouseHover(dwt.events.MouseEvent) + * @since 3.3 + */ + public void mouseEnter(MouseEvent e) { + updateHeaderToolTipText(); + } + }); + } + + fCanvas= new Canvas(parent, DWT.NO_BACKGROUND); + + fCanvas.addPaintListener(new class() PaintListener { + public void paintControl(PaintEvent event) { + if (fTextViewer !is null) + doubleBufferPaint(event.gc); + } + }); + + fCanvas.addDisposeListener(new class() DisposeListener { + public void widgetDisposed(DisposeEvent event) { + handleDispose(); + fTextViewer= null; + } + }); + + fCanvas.addMouseListener(new class() MouseAdapter { + public void mouseDown(MouseEvent event) { + handleMouseDown(event); + } + }); + + fCanvas.addMouseMoveListener(new class() MouseMoveListener { + public void mouseMove(MouseEvent event) { + handleMouseMove(event); + } + }); + + if (fTextViewer !is null) + fTextViewer.addTextListener(fInternalListener); + + return fCanvas; + } + + /** + * Disposes the ruler's resources. + */ + private void handleDispose() { + + if (fTextViewer !is null) { + fTextViewer.removeTextListener(fInternalListener); + fTextViewer= null; + } + + if (fModel !is null) + fModel.removeAnnotationModelListener(fInternalListener); + + if (fBuffer !is null) { + fBuffer.dispose(); + fBuffer= null; + } + + if (fHitDetectionCursor !is null) { + fHitDetectionCursor.dispose(); + fHitDetectionCursor= null; + } + + fConfiguredAnnotationTypes.clear(); + fAllowedAnnotationTypes.clear(); + fConfiguredHeaderAnnotationTypes.clear(); + fAllowedHeaderAnnotationTypes.clear(); + fAnnotationTypes2Colors.clear(); + fAnnotationsSortedByLayer.clear(); + fLayersSortedByLayer.clear(); + } + + /** + * Double buffer drawing. + * + * @param dest the GC to draw into + */ + private void doubleBufferPaint(GC dest) { + + Point size= fCanvas.getSize(); + + if (size.x <= 0 || size.y <= 0) + return; + + if (fBuffer !is null) { + Rectangle r= fBuffer.getBounds(); + if (r.width !is size.x || r.height !is size.y) { + fBuffer.dispose(); + fBuffer= null; + } + } + if (fBuffer is null) + fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y); + + GC gc= new GC(fBuffer); + try { + gc.setBackground(fCanvas.getBackground()); + gc.fillRectangle(0, 0, size.x, size.y); + + cacheAnnotations(); + + if ( cast(ITextViewerExtension5)fTextViewer ) + doPaint1(gc); + else + doPaint(gc); + + } finally { + gc.dispose(); + } + + dest.drawImage(fBuffer, 0, 0); + } + + /** + * Draws this overview ruler. + * + * @param gc the GC to draw into + */ + private void doPaint(GC gc) { + + Rectangle r= new Rectangle(0, 0, 0, 0); + int yy, hh= ANNOTATION_HEIGHT; + + IDocument document= fTextViewer.getDocument(); + IRegion visible= fTextViewer.getVisibleRegion(); + + StyledText textWidget= fTextViewer.getTextWidget(); + int maxLines= textWidget.getLineCount(); + + Point size= fCanvas.getSize(); + int writable= JFaceTextUtil.computeLineHeight(textWidget, 0, maxLines, maxLines); + + if (size.y > writable) + size.y= Math.max(writable - fHeader.getSize().y, 0); + + for (Iterator iterator= fAnnotationsSortedByLayer.iterator(); iterator.hasNext();) { + Object annotationType= iterator.next(); + + if (skip(annotationType)) + continue; + + int[] style= [ FilterIterator.PERSISTENT, FilterIterator.TEMPORARY ]; + for (int t=0; t < style.length; t++) { + + Iterator e= new FilterIterator(annotationType, style[t], fCachedAnnotations.iterator()); + Color fill= getFillColor(annotationType, style[t] is FilterIterator.TEMPORARY); + Color stroke= getStrokeColor(annotationType, style[t] is FilterIterator.TEMPORARY); + + for (int i= 0; e.hasNext(); i++) { + + Annotation a= cast(Annotation) e.next(); + Position p= fModel.getPosition(a); + + if (p is null || !p.overlapsWith(visible.getOffset(), visible.getLength())) + continue; + + int annotationOffset= Math.max(p.getOffset(), visible.getOffset()); + int annotationEnd= Math.min(p.getOffset() + p.getLength(), visible.getOffset() + visible.getLength()); + int annotationLength= annotationEnd - annotationOffset; + + try { + if (ANNOTATION_HEIGHT_SCALABLE) { + int numbersOfLines= document.getNumberOfLines(annotationOffset, annotationLength); + // don't count empty trailing lines + IRegion lastLine= document.getLineInformationOfOffset(annotationOffset + annotationLength); + if (lastLine.getOffset() is annotationOffset + annotationLength) { + numbersOfLines -= 2; + hh= (numbersOfLines * size.y) / maxLines + ANNOTATION_HEIGHT; + if (hh < ANNOTATION_HEIGHT) + hh= ANNOTATION_HEIGHT; + } else + hh= ANNOTATION_HEIGHT; + } + fAnnotationHeight= hh; + + int startLine= textWidget.getLineAtOffset(annotationOffset - visible.getOffset()); + yy= Math.min((startLine * size.y) / maxLines, size.y - hh); + + if (fill !is null) { + gc.setBackground(fill); + gc.fillRectangle(INSET, yy, size.x-(2*INSET), hh); + } + + if (stroke !is null) { + gc.setForeground(stroke); + r.x= INSET; + r.y= yy; + r.width= size.x - (2 * INSET); + r.height= hh; + gc.setLineWidth(0); // NOTE: 0 means width is 1 but with optimized performance + gc.drawRectangle(r); + } + } catch (BadLocationException x) { + } + } + } + } + } + + private void cacheAnnotations() { + fCachedAnnotations.clear(); + if (fModel !is null) { + Iterator iter= fModel.getAnnotationIterator(); + while (iter.hasNext()) { + Annotation annotation= cast(Annotation) iter.next(); + + if (annotation.isMarkedDeleted()) + continue; + + if (skip(annotation.getType())) + continue; + + fCachedAnnotations.add(annotation); + } + } + } + + /** + * Draws this overview ruler. Uses ITextViewerExtension5 for + * its implementation. Will replace doPaint(GC). + * + * @param gc the GC to draw into + */ + private void doPaint1(GC gc) { + + Rectangle r= new Rectangle(0, 0, 0, 0); + int yy, hh= ANNOTATION_HEIGHT; + + ITextViewerExtension5 extension= cast(ITextViewerExtension5) fTextViewer; + IDocument document= fTextViewer.getDocument(); + StyledText textWidget= fTextViewer.getTextWidget(); + + int maxLines= textWidget.getLineCount(); + Point size= fCanvas.getSize(); + int writable= JFaceTextUtil.computeLineHeight(textWidget, 0, maxLines, maxLines); + if (size.y > writable) + size.y= Math.max(writable - fHeader.getSize().y, 0); + + for (Iterator iterator= fAnnotationsSortedByLayer.iterator(); iterator.hasNext();) { + Object annotationType= iterator.next(); + + if (skip(annotationType)) + continue; + + int[] style= [ FilterIterator.PERSISTENT, FilterIterator.TEMPORARY ]; + for (int t=0; t < style.length; t++) { + + Iterator e= new FilterIterator(annotationType, style[t], fCachedAnnotations.iterator()); + Color fill= getFillColor(annotationType, style[t] is FilterIterator.TEMPORARY); + Color stroke= getStrokeColor(annotationType, style[t] is FilterIterator.TEMPORARY); + + for (int i= 0; e.hasNext(); i++) { + + Annotation a= cast(Annotation) e.next(); + Position p= fModel.getPosition(a); + + if (p is null) + continue; + + IRegion widgetRegion= extension.modelRange2WidgetRange(new Region(p.getOffset(), p.getLength())); + if (widgetRegion is null) + continue; + + try { + if (ANNOTATION_HEIGHT_SCALABLE) { + int numbersOfLines= document.getNumberOfLines(p.getOffset(), p.getLength()); + // don't count empty trailing lines + IRegion lastLine= document.getLineInformationOfOffset(p.getOffset() + p.getLength()); + if (lastLine.getOffset() is p.getOffset() + p.getLength()) { + numbersOfLines -= 2; + hh= (numbersOfLines * size.y) / maxLines + ANNOTATION_HEIGHT; + if (hh < ANNOTATION_HEIGHT) + hh= ANNOTATION_HEIGHT; + } else + hh= ANNOTATION_HEIGHT; + } + fAnnotationHeight= hh; + + int startLine= textWidget.getLineAtOffset(widgetRegion.getOffset()); + yy= Math.min((startLine * size.y) / maxLines, size.y - hh); + + if (fill !is null) { + gc.setBackground(fill); + gc.fillRectangle(INSET, yy, size.x-(2*INSET), hh); + } + + if (stroke !is null) { + gc.setForeground(stroke); + r.x= INSET; + r.y= yy; + r.width= size.x - (2 * INSET); + r.height= hh; + gc.setLineWidth(0); // NOTE: 0 means width is 1 but with optimized performance + gc.drawRectangle(r); + } + } catch (BadLocationException x) { + } + } + } + } + } + + /* + * @see dwtx.jface.text.source.IVerticalRuler#update() + */ + public void update() { + if (fCanvas !is null && !fCanvas.isDisposed()) { + Display d= fCanvas.getDisplay(); + if (d !is null) { + synchronized (fRunnableLock) { + if (fIsRunnablePosted) + return; + fIsRunnablePosted= true; + } + d.asyncExec(fRunnable); + } + } + } + + /** + * Redraws the overview ruler. + */ + private void redraw() { + if (fTextViewer is null || fModel is null) + return; + + if (fCanvas !is null && !fCanvas.isDisposed()) { + GC gc= new GC(fCanvas); + doubleBufferPaint(gc); + gc.dispose(); + } + } + + /** + * Translates a given y-coordinate of this ruler into the corresponding + * document lines. The number of lines depends on the concrete scaling + * given as the ration between the height of this ruler and the length + * of the document. + * + * @param y_coordinate the y-coordinate + * @return the corresponding document lines + */ + private int[] toLineNumbers(int y_coordinate) { + + StyledText textWidget= fTextViewer.getTextWidget(); + int maxLines= textWidget.getContent().getLineCount(); + + int rulerLength= fCanvas.getSize().y; + int writable= JFaceTextUtil.computeLineHeight(textWidget, 0, maxLines, maxLines); + + if (rulerLength > writable) + rulerLength= Math.max(writable - fHeader.getSize().y, 0); + + if (y_coordinate >= writable || y_coordinate >= rulerLength) + return [-1, -1]; + + int[] lines= new int[2]; + + int pixel0= Math.max(y_coordinate - 1, 0); + int pixel1= Math.min(rulerLength, y_coordinate + 1); + rulerLength= Math.max(rulerLength, 1); + + lines[0]= (pixel0 * maxLines) / rulerLength; + lines[1]= (pixel1 * maxLines) / rulerLength; + + if ( cast(ITextViewerExtension5)fTextViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) fTextViewer; + lines[0]= extension.widgetLine2ModelLine(lines[0]); + lines[1]= extension.widgetLine2ModelLine(lines[1]); + } else { + try { + IRegion visible= fTextViewer.getVisibleRegion(); + int lineNumber= fTextViewer.getDocument().getLineOfOffset(visible.getOffset()); + lines[0] += lineNumber; + lines[1] += lineNumber; + } catch (BadLocationException x) { + } + } + + return lines; + } + + /** + * Returns the position of the first annotation found in the given line range. + * + * @param lineNumbers the line range + * @return the position of the first found annotation + */ + private Position getAnnotationPosition(int[] lineNumbers) { + if (lineNumbers[0] is -1) + return null; + + Position found= null; + + try { + IDocument d= fTextViewer.getDocument(); + IRegion line= d.getLineInformation(lineNumbers[0]); + + int start= line.getOffset(); + + line= d.getLineInformation(lineNumbers[lineNumbers.length - 1]); + int end= line.getOffset() + line.getLength(); + + for (int i= fAnnotationsSortedByLayer.size() -1; i >= 0; i--) { + + Object annotationType= fAnnotationsSortedByLayer.get(i); + + Iterator e= new FilterIterator(annotationType, FilterIterator.PERSISTENT | FilterIterator.TEMPORARY); + while (e.hasNext() && found is null) { + Annotation a= cast(Annotation) e.next(); + if (a.isMarkedDeleted()) + continue; + + if (skip(a.getType())) + continue; + + Position p= fModel.getPosition(a); + if (p is null) + continue; + + int posOffset= p.getOffset(); + int posEnd= posOffset + p.getLength(); + IRegion region= d.getLineInformationOfOffset(posEnd); + // trailing empty lines don't count + if (posEnd > posOffset && region.getOffset() is posEnd) { + posEnd--; + region= d.getLineInformationOfOffset(posEnd); + } + + if (posOffset <= end && posEnd >= start) + found= p; + } + } + } catch (BadLocationException x) { + } + + return found; + } + + /** + * Returns the line which corresponds best to one of + * the underlying annotations at the given y-coordinate. + * + * @param lineNumbers the line numbers + * @return the best matching line or -1 if no such line can be found + */ + private int findBestMatchingLineNumber(int[] lineNumbers) { + if (lineNumbers is null || lineNumbers.length < 1) + return -1; + + try { + Position pos= getAnnotationPosition(lineNumbers); + if (pos is null) + return -1; + return fTextViewer.getDocument().getLineOfOffset(pos.getOffset()); + } catch (BadLocationException ex) { + return -1; + } + } + + /** + * Handles mouse clicks. + * + * @param event the mouse button down event + */ + private void handleMouseDown(MouseEvent event) { + if (fTextViewer !is null) { + int[] lines= toLineNumbers(event.y); + Position p= getAnnotationPosition(lines); + if (p is null && event.button is 1) { + try { + p= new Position(fTextViewer.getDocument().getLineInformation(lines[0]).getOffset(), 0); + } catch (BadLocationException e) { + // do nothing + } + } + if (p !is null) { + fTextViewer.revealRange(p.getOffset(), p.getLength()); + fTextViewer.setSelectedRange(p.getOffset(), p.getLength()); + } + fTextViewer.getTextWidget().setFocus(); + } + fLastMouseButtonActivityLine= toDocumentLineNumber(event.y); + } + + /** + * Handles mouse moves. + * + * @param event the mouse move event + */ + private void handleMouseMove(MouseEvent event) { + if (fTextViewer !is null) { + int[] lines= toLineNumbers(event.y); + Position p= getAnnotationPosition(lines); + Cursor cursor= (p !is null ? fHitDetectionCursor : null); + if (cursor !is fLastCursor) { + fCanvas.setCursor(cursor); + fLastCursor= cursor; + } + } + } + + /* + * @see dwtx.jface.text.source.IOverviewRuler#addAnnotationType(java.lang.Object) + */ + public void addAnnotationType(Object annotationType) { + fConfiguredAnnotationTypes.add(annotationType); + fAllowedAnnotationTypes.clear(); + } + + /* + * @see dwtx.jface.text.source.IOverviewRuler#removeAnnotationType(java.lang.Object) + */ + public void removeAnnotationType(Object annotationType) { + fConfiguredAnnotationTypes.remove(annotationType); + fAllowedAnnotationTypes.clear(); + } + + /* + * @see dwtx.jface.text.source.IOverviewRuler#setAnnotationTypeLayer(java.lang.Object, int) + */ + public void setAnnotationTypeLayer(Object annotationType, int layer) { + int j= fAnnotationsSortedByLayer.indexOf(annotationType); + if (j !is -1) { + fAnnotationsSortedByLayer.remove(j); + fLayersSortedByLayer.remove(j); + } + + if (layer >= 0) { + int i= 0; + int size= fLayersSortedByLayer.size(); + while (i < size && layer >= (cast(Integer)fLayersSortedByLayer.get(i)).intValue()) + i++; + Integer layerObj= new Integer(layer); + fLayersSortedByLayer.add(i, layerObj); + fAnnotationsSortedByLayer.add(i, annotationType); + } + } + + /* + * @see dwtx.jface.text.source.IOverviewRuler#setAnnotationTypeColor(java.lang.Object, dwt.graphics.Color) + */ + public void setAnnotationTypeColor(Object annotationType, Color color) { + if (color !is null) + fAnnotationTypes2Colors.put(annotationType, color); + else + fAnnotationTypes2Colors.remove(annotationType); + } + + /** + * Returns whether the given annotation type should be skipped by the drawing routine. + * + * @param annotationType the annotation type + * @return true if annotation of the given type should be skipped + */ + private bool skip(Object annotationType) { + return !contains(annotationType, fAllowedAnnotationTypes, fConfiguredAnnotationTypes); + } + private bool skip(String annotationType) { + return !contains(stringcast(annotationType), fAllowedAnnotationTypes, fConfiguredAnnotationTypes); + } + + /** + * Returns whether the given annotation type should be skipped by the drawing routine of the header. + * + * @param annotationType the annotation type + * @return true if annotation of the given type should be skipped + * @since 3.0 + */ + private bool skipInHeader(Object annotationType) { + return !contains(annotationType, fAllowedHeaderAnnotationTypes, fConfiguredHeaderAnnotationTypes); + } + + /** + * Returns whether the given annotation type is mapped to true + * in the given allowed map or covered by the configured + * set. + * + * @param annotationType the annotation type + * @param allowed the map with allowed annotation types mapped to booleans + * @param configured the set with configured annotation types + * @return true if annotation is contained, false + * otherwise + * @since 3.0 + */ + private bool contains(Object annotationType, Map allowed, Set configured) { + Boolean cached= cast(Boolean) allowed.get(annotationType); + if (cached !is null) + return cached.booleanValue(); + + bool covered= isCovered(annotationType, configured); + allowed.put(annotationType, covered ? Boolean.TRUE : Boolean.FALSE); + return covered; + } + + /** + * Computes whether the annotations of the given type are covered by the given configured + * set. This is the case if either the type of the annotation or any of its + * super types is contained in the configured set. + * + * @param annotationType the annotation type + * @param configured the set with configured annotation types + * @return true if annotation is covered, false + * otherwise + * @since 3.0 + */ + private bool isCovered(Object annotationType, Set configured) { + if ( cast(IAnnotationAccessExtension)fAnnotationAccess ) { + IAnnotationAccessExtension extension= cast(IAnnotationAccessExtension) fAnnotationAccess; + Iterator e= configured.iterator(); + while (e.hasNext()) { + if (extension.isSubtype(annotationType,e.next())) + return true; + } + return false; + } + return configured.contains(annotationType); + } + + /** + * Returns a specification of a color that lies between the given + * foreground and background color using the given scale factor. + * + * @param fg the foreground color + * @param bg the background color + * @param scale the scale factor + * @return the interpolated color + */ + private static RGB interpolate(RGB fg, RGB bg, double scale) { + return new RGB( + cast(int) ((1.0-scale) * fg.red + scale * bg.red), + cast(int) ((1.0-scale) * fg.green + scale * bg.green), + cast(int) ((1.0-scale) * fg.blue + scale * bg.blue) + ); + } + + /** + * Returns the grey value in which the given color would be drawn in grey-scale. + * + * @param rgb the color + * @return the grey-scale value + */ + private static double greyLevel(RGB rgb) { + if (rgb.red is rgb.green && rgb.green is rgb.blue) + return rgb.red; + return (0.299 * rgb.red + 0.587 * rgb.green + 0.114 * rgb.blue + 0.5); + } + + /** + * Returns whether the given color is dark or light depending on the colors grey-scale level. + * + * @param rgb the color + * @return true if the color is dark, false if it is light + */ + private static bool isDark(RGB rgb) { + return greyLevel(rgb) > 128; + } + + /** + * Returns a color based on the color configured for the given annotation type and the given scale factor. + * + * @param annotationType the annotation type + * @param scale the scale factor + * @return the computed color + */ + private Color getColor(Object annotationType, double scale) { + Color base= findColor(annotationType); + if (base is null) + return null; + + RGB baseRGB= base.getRGB(); + RGB background= fCanvas.getBackground().getRGB(); + + bool darkBase= isDark(baseRGB); + bool darkBackground= isDark(background); + if (darkBase && darkBackground) + background= new RGB(255, 255, 255); + else if (!darkBase && !darkBackground) + background= new RGB(0, 0, 0); + + return fSharedTextColors.getColor(interpolate(baseRGB, background, scale)); + } + + /** + * Returns the color for the given annotation type + * + * @param annotationType the annotation type + * @return the color + * @since 3.0 + */ + private Color findColor(Object annotationType) { + Color color= cast(Color) fAnnotationTypes2Colors.get(annotationType); + if (color !is null) + return color; + + if ( cast(IAnnotationAccessExtension)fAnnotationAccess ) { + IAnnotationAccessExtension extension= cast(IAnnotationAccessExtension) fAnnotationAccess; + Object[] superTypes= extension.getSupertypes(annotationType); + if (superTypes !is null) { + for (int i= 0; i < superTypes.length; i++) { + color= cast(Color) fAnnotationTypes2Colors.get(superTypes[i]); + if (color !is null) + return color; + } + } + } + + return null; + } + + /** + * Returns the stroke color for the given annotation type and characteristics. + * + * @param annotationType the annotation type + * @param temporary true if for temporary annotations + * @return the stroke color + */ + private Color getStrokeColor(Object annotationType, bool temporary) { + return getColor(annotationType, temporary && fIsTemporaryAnnotationDiscolored ? 0.5 : 0.2); + } + + /** + * Returns the fill color for the given annotation type and characteristics. + * + * @param annotationType the annotation type + * @param temporary true if for temporary annotations + * @return the fill color + */ + private Color getFillColor(Object annotationType, bool temporary) { + return getColor(annotationType, temporary && fIsTemporaryAnnotationDiscolored ? 0.9 : 0.75); + } + + /* + * @see IVerticalRulerInfo#getLineOfLastMouseButtonActivity() + */ + public int getLineOfLastMouseButtonActivity() { + if (fLastMouseButtonActivityLine >= fTextViewer.getDocument().getNumberOfLines()) + fLastMouseButtonActivityLine= -1; + return fLastMouseButtonActivityLine; + } + + /* + * @see IVerticalRulerInfo#toDocumentLineNumber(int) + */ + public int toDocumentLineNumber(int y_coordinate) { + + if (fTextViewer is null || y_coordinate is -1) + return -1; + + int[] lineNumbers= toLineNumbers(y_coordinate); + int bestLine= findBestMatchingLineNumber(lineNumbers); + if (bestLine is -1 && lineNumbers.length > 0) + return lineNumbers[0]; + return bestLine; + } + + /* + * @see dwtx.jface.text.source.IVerticalRuler#getModel() + */ + public IAnnotationModel getModel() { + return fModel; + } + + /* + * @see dwtx.jface.text.source.IOverviewRuler#getAnnotationHeight() + */ + public int getAnnotationHeight() { + return fAnnotationHeight; + } + + /* + * @see dwtx.jface.text.source.IOverviewRuler#hasAnnotation(int) + */ + public bool hasAnnotation(int y) { + return findBestMatchingLineNumber(toLineNumbers(y)) !is -1; + } + + /* + * @see dwtx.jface.text.source.IOverviewRuler#getHeaderControl() + */ + public Control getHeaderControl() { + return fHeader; + } + + /* + * @see dwtx.jface.text.source.IOverviewRuler#addHeaderAnnotationType(java.lang.Object) + */ + public void addHeaderAnnotationType(Object annotationType) { + fConfiguredHeaderAnnotationTypes.add(annotationType); + fAllowedHeaderAnnotationTypes.clear(); + } + + /* + * @see dwtx.jface.text.source.IOverviewRuler#removeHeaderAnnotationType(java.lang.Object) + */ + public void removeHeaderAnnotationType(Object annotationType) { + fConfiguredHeaderAnnotationTypes.remove(annotationType); + fAllowedHeaderAnnotationTypes.clear(); + } + + /** + * Updates the header of this ruler. + */ + private void updateHeader() { + if (fHeader is null || fHeader.isDisposed()) + return; + + fHeader.setToolTipText(null); + + Object colorType= null; + outer: for (int i= fAnnotationsSortedByLayer.size() -1; i >= 0; i--) { + Object annotationType= fAnnotationsSortedByLayer.get(i); + if (skipInHeader(annotationType) || skip(annotationType)) + continue; + + Iterator e= new FilterIterator(annotationType, FilterIterator.PERSISTENT | FilterIterator.TEMPORARY | FilterIterator.IGNORE_BAGS, fCachedAnnotations.iterator()); + while (e.hasNext()) { + if (e.next() !is null) { + colorType= annotationType; + break outer; + } + } + } + + Color color= null; + if (colorType !is null) + color= findColor(colorType); + + if (color is null) { + if (fHeaderPainter !is null) + fHeaderPainter.setColor(null); + } else { + if (fHeaderPainter is null) { + fHeaderPainter= new HeaderPainter(); + fHeader.addPaintListener(fHeaderPainter); + } + fHeaderPainter.setColor(color); + } + + fHeader.redraw(); + + } + + /** + * Updates the header tool tip text of this ruler. + */ + private void updateHeaderToolTipText() { + if (fHeader is null || fHeader.isDisposed()) + return; + + if (fHeader.getToolTipText() !is null) + return; + + String overview= ""; //$NON-NLS-1$ + + for (int i= fAnnotationsSortedByLayer.size() -1; i >= 0; i--) { + + Object annotationType= fAnnotationsSortedByLayer.get(i); + + if (skipInHeader(annotationType) || skip(annotationType)) + continue; + + int count= 0; + String annotationTypeLabel= null; + + Iterator e= new FilterIterator(annotationType, FilterIterator.PERSISTENT | FilterIterator.TEMPORARY | FilterIterator.IGNORE_BAGS, fCachedAnnotations.iterator()); + while (e.hasNext()) { + Annotation annotation= cast(Annotation)e.next(); + if (annotation !is null) { + if (annotationTypeLabel is null) + annotationTypeLabel= (cast(IAnnotationAccessExtension)fAnnotationAccess).getTypeLabel(annotation); + count++; + } + } + + if (annotationTypeLabel !is null) { + if (overview.length() > 0) + overview ~= "\n"; //$NON-NLS-1$ + overview ~= JFaceTextMessages.getFormattedString("OverviewRulerHeader.toolTipTextEntry", stringcast(annotationTypeLabel), new Integer(count) ); //$NON-NLS-1$ + } + } + + if (overview.length() > 0) + fHeader.setToolTipText(overview); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/OverviewRulerHoverManager.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/OverviewRulerHoverManager.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,157 @@ +/******************************************************************************* + * 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 + * 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.text.source.OverviewRulerHoverManager; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport + + +import dwt.dwthelper.utils; + + + +import dwt.custom.StyledText; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.ScrollBar; +import dwtx.jface.text.IInformationControlCreator; + +/** + * This manager controls the layout, content, and visibility of an information + * control in reaction to mouse hover events issued by the overview ruler of a + * source viewer. + * + * @since 2.1 + */ +class OverviewRulerHoverManager : AnnotationBarHoverManager { + + /** + * Creates an overview hover manager with the given parameters. In addition, + * the hovers anchor is RIGHT and the margin is 5 points to the right. + * + * @param ruler the overview ruler this manager connects to + * @param sourceViewer the source viewer this manager connects to + * @param annotationHover the annotation hover providing the information to be displayed + * @param creator the information control creator + */ + public this(IOverviewRuler ruler, ISourceViewer sourceViewer, IAnnotationHover annotationHover, IInformationControlCreator creator) { + super(ruler, sourceViewer, annotationHover, creator); + setAnchor(ANCHOR_LEFT); + StyledText textWidget= sourceViewer.getTextWidget(); + if (textWidget !is null) { + ScrollBar verticalBar= textWidget.getVerticalBar(); + if (verticalBar !is null) + setMargins(verticalBar.getSize().x, 5); + } + } + + /* + * @see AbstractHoverInformationControlManager#computeInformation() + */ + protected void computeInformation() { + Point location= getHoverEventLocation(); + int line= getVerticalRulerInfo().toDocumentLineNumber(location.y); + IAnnotationHover hover= getAnnotationHover(); + + IInformationControlCreator controlCreator= null; + if ( cast(IAnnotationHoverExtension)hover ) + controlCreator= (cast(IAnnotationHoverExtension)hover).getHoverControlCreator(); + setCustomInformationControlCreator(controlCreator); + + setInformation(hover.getHoverInfo(getSourceViewer(), line), computeArea(location.y)); + } + + /** + * Determines graphical area covered for which the hover is valid. + * + * @param y y-coordinate in the vertical ruler + * @return the graphical extend where the hover is valid + */ + private Rectangle computeArea(int y) { + // This is OK (see constructor) + IOverviewRuler overviewRuler= cast(IOverviewRuler) getVerticalRulerInfo(); + + int hover_height= overviewRuler.getAnnotationHeight(); + int hover_width= getVerticalRulerInfo().getControl().getSize().x; + + // Calculate y-coordinate for hover + int hover_y= y; + bool hasAnnotation= true; + while (hasAnnotation && hover_y > y - hover_height) { + hover_y--; + hasAnnotation= overviewRuler.hasAnnotation(hover_y); + } + hover_y++; + + return new Rectangle(0, hover_y, hover_width, hover_height); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/SourceViewer.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/SourceViewer.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,1161 @@ +/******************************************************************************* + * 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 + * 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.text.source.SourceViewer; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + +import dwt.DWT; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Canvas; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Layout; +import dwtx.jface.internal.text.NonDeletingPositionUpdater; +import dwtx.jface.internal.text.StickyHoverManager; +import dwtx.jface.text.AbstractHoverInformationControlManager; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.BadPositionCategoryException; +import dwtx.jface.text.DocumentRewriteSession; +import dwtx.jface.text.DocumentRewriteSessionType; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentExtension4; +import dwtx.jface.text.IPositionUpdater; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.IRewriteTarget; +import dwtx.jface.text.ISlaveDocumentManager; +import dwtx.jface.text.ISlaveDocumentManagerExtension; +import dwtx.jface.text.ITextViewerExtension2; +import dwtx.jface.text.ITextViewerExtension8; +import dwtx.jface.text.Position; +import dwtx.jface.text.Region; +import dwtx.jface.text.TextViewer; +import dwtx.jface.text.contentassist.IContentAssistant; +import dwtx.jface.text.contentassist.IContentAssistantExtension4; +import dwtx.jface.text.formatter.FormattingContext; +import dwtx.jface.text.formatter.FormattingContextProperties; +import dwtx.jface.text.formatter.IContentFormatter; +import dwtx.jface.text.formatter.IContentFormatterExtension; +import dwtx.jface.text.formatter.IFormattingContext; +import dwtx.jface.text.hyperlink.IHyperlinkDetector; +import dwtx.jface.text.information.IInformationPresenter; +import dwtx.jface.text.presentation.IPresentationReconciler; +import dwtx.jface.text.projection.ChildDocument; +import dwtx.jface.text.quickassist.IQuickAssistAssistant; +import dwtx.jface.text.quickassist.IQuickAssistInvocationContext; +import dwtx.jface.text.reconciler.IReconciler; + +/** + * DWT based implementation of + * {@link dwtx.jface.text.source.ISourceViewer} and its extension + * interfaces. The same rules apply as for + * {@link dwtx.jface.text.TextViewer}. A source viewer uses an + * IVerticalRuler as its annotation presentation area. The + * vertical ruler is a small strip shown left of the viewer's text widget. A + * source viewer uses an IOverviewRuler as its presentation area + * for the annotation overview. The overview ruler is a small strip shown right + * of the viewer's text widget. + *

                        + * Clients are supposed to instantiate a source viewer and subsequently to + * communicate with it exclusively using the ISourceViewer and + * its extension interfaces.

                        + *

                        + * Clients may subclass this class but should expect some breakage by future releases.

                        + */ +public class SourceViewer : TextViewer , ISourceViewer, ISourceViewerExtension, ISourceViewerExtension2, ISourceViewerExtension3, ISourceViewerExtension4 { + + + /** + * Layout of a source viewer. Vertical ruler, text widget, and overview ruler are shown side by side. + */ + protected class RulerLayout : Layout { + + /** The gap between the text viewer and the vertical ruler. */ + protected int fGap; + + /** + * Creates a new ruler layout with the given gap between text viewer and vertical ruler. + * + * @param gap the gap between text viewer and vertical ruler + */ + public this(int gap) { + fGap= gap; + } + + /* + * @see Layout#computeSize(Composite, int, int, bool) + */ + protected Point computeSize(Composite composite, int wHint, int hHint, bool flushCache) { + Control[] children= composite.getChildren(); + Point s= children[children.length - 1].computeSize(DWT.DEFAULT, DWT.DEFAULT, flushCache); + if (fVerticalRuler !is null && fIsVerticalRulerVisible) + s.x += fVerticalRuler.getWidth() + fGap; + return s; + } + + /* + * @see Layout#layout(Composite, bool) + */ + protected void layout(Composite composite, bool flushCache) { + Rectangle clArea= composite.getClientArea(); + Rectangle trim= getTextWidget().computeTrim(0, 0, 0, 0); + int topTrim= - trim.y; + int scrollbarHeight= trim.height - topTrim; // scrollbar is only under the client area + + int x= clArea.x; + int width= clArea.width; + + if (fOverviewRuler !is null && fIsOverviewRulerVisible) { + int overviewRulerWidth= fOverviewRuler.getWidth(); + fOverviewRuler.getControl().setBounds(clArea.x + clArea.width - overviewRulerWidth - 1, clArea.y + scrollbarHeight, overviewRulerWidth, clArea.height - 3*scrollbarHeight); + fOverviewRuler.getHeaderControl().setBounds(clArea.x + clArea.width - overviewRulerWidth - 1, clArea.y, overviewRulerWidth, scrollbarHeight); + + width -= overviewRulerWidth + fGap; + } + + if (fVerticalRuler !is null && fIsVerticalRulerVisible) { + int verticalRulerWidth= fVerticalRuler.getWidth(); + final Control verticalRulerControl= fVerticalRuler.getControl(); + int oldWidth= verticalRulerControl.getBounds().width; + verticalRulerControl.setBounds(clArea.x, clArea.y + topTrim, verticalRulerWidth, clArea.height - scrollbarHeight - topTrim); + if (flushCache && getVisualAnnotationModel() !is null && oldWidth is verticalRulerWidth) + verticalRulerControl.redraw(); + + x += verticalRulerWidth + fGap; + width -= verticalRulerWidth + fGap; + } + + getTextWidget().setBounds(x, clArea.y, width, clArea.height); + } + } + + /** + * The size of the gap between the vertical ruler and the text widget + * (value 2). + *

                        + * Note: As of 3.2, the text editor framework is no longer using 2 as + * gap but 1, see {{@link #GAP_SIZE_1 }. + *

                        + */ + protected final static int GAP_SIZE= 2; + /** + * The size of the gap between the vertical ruler and the text widget + * (value 1). + * @since 3.2 + */ + protected final static int GAP_SIZE_1= 1; + /** + * Partial name of the position category to manage remembered selections. + * @since 3.0 + */ + protected final static String _SELECTION_POSITION_CATEGORY= "__selection_category"; //$NON-NLS-1$ + /** + * Key of the model annotation model inside the visual annotation model. + * @since 3.0 + */ + private static Object MODEL_ANNOTATION_MODEL_; + protected static Object MODEL_ANNOTATION_MODEL(){ + if( MODEL_ANNOTATION_MODEL_ is null ){ + synchronized(SourceViewer.classinfo ){ + if( MODEL_ANNOTATION_MODEL_ is null ){ + MODEL_ANNOTATION_MODEL_ = new Object(); + } + } + } + return MODEL_ANNOTATION_MODEL_; + } + + /** The viewer's content assistant */ + protected IContentAssistant fContentAssistant; + /** + * The viewer's facade to its content assistant. + * @since 3.4 + */ + private ContentAssistantFacade fContentAssistantFacade; + /** + * Flag indicating whether the viewer's content assistant is installed. + * @since 2.0 + */ + protected bool fContentAssistantInstalled; + /** + * This viewer's quick assist assistant. + * @since 3.2 + */ + protected IQuickAssistAssistant fQuickAssistAssistant; + /** + * Flag indicating whether this viewer's quick assist assistant is installed. + * @since 3.2 + */ + protected bool fQuickAssistAssistantInstalled; + /** The viewer's content formatter */ + protected IContentFormatter fContentFormatter; + /** The viewer's model reconciler */ + protected IReconciler fReconciler; + /** The viewer's presentation reconciler */ + protected IPresentationReconciler fPresentationReconciler; + /** The viewer's annotation hover */ + protected IAnnotationHover fAnnotationHover; + /** + * Stack of saved selections in the underlying document + * @since 3.0 + */ + protected const Stack fSelections; + /** + * Position updater for saved selections + * @since 3.0 + */ + protected IPositionUpdater fSelectionUpdater= null; + /** + * Position category used by the selection updater + * @since 3.0 + */ + protected String fSelectionCategory; + /** + * The viewer's overview ruler annotation hover + * @since 3.0 + */ + protected IAnnotationHover fOverviewRulerAnnotationHover; + /** + * The viewer's information presenter + * @since 2.0 + */ + protected IInformationPresenter fInformationPresenter; + + /** Visual vertical ruler */ + private IVerticalRuler fVerticalRuler; + /** Visibility of vertical ruler */ + private bool fIsVerticalRulerVisible; + /** The DWT widget used when supporting a vertical ruler */ + private Composite fComposite; + /** The vertical ruler's annotation model */ + private IAnnotationModel fVisualAnnotationModel; + /** The viewer's range indicator to be shown in the vertical ruler */ + private Annotation fRangeIndicator; + /** The viewer's vertical ruler hovering controller */ + private AnnotationBarHoverManager fVerticalRulerHoveringController; + /** + * The viewer's overview ruler hovering controller + * @since 2.1 + */ + private AbstractHoverInformationControlManager fOverviewRulerHoveringController; + + /** + * The overview ruler. + * @since 2.1 + */ + private IOverviewRuler fOverviewRuler; + /** + * The visibility of the overview ruler + * @since 2.1 + */ + private bool fIsOverviewRulerVisible; + + + /** + * Constructs a new source viewer. The vertical ruler is initially visible. + * The viewer has not yet been initialized with a source viewer configuration. + * + * @param parent the parent of the viewer's control + * @param ruler the vertical ruler used by this source viewer + * @param styles the DWT style bits for the viewer's control, + * if DWT.WRAP is set then a custom document adapter needs to be provided, see {@link #createDocumentAdapter()} + */ + public this(Composite parent, IVerticalRuler ruler, int styles) { + this(parent, ruler, null, false, styles); + } + + /** + * Constructs a new source viewer. The vertical ruler is initially visible. + * The overview ruler visibility is controlled by the value of showAnnotationsOverview. + * The viewer has not yet been initialized with a source viewer configuration. + * + * @param parent the parent of the viewer's control + * @param verticalRuler the vertical ruler used by this source viewer + * @param overviewRuler the overview ruler + * @param showAnnotationsOverview true if the overview ruler should be visible, false otherwise + * @param styles the DWT style bits for the viewer's control, + * if DWT.WRAP is set then a custom document adapter needs to be provided, see {@link #createDocumentAdapter()} + * @since 2.1 + */ + public this(Composite parent, IVerticalRuler verticalRuler, IOverviewRuler overviewRuler, bool showAnnotationsOverview, int styles) { + fSelections= new Stack(); + super(); + + fVerticalRuler= verticalRuler; + fIsVerticalRulerVisible= (verticalRuler !is null); + fOverviewRuler= overviewRuler; + fIsOverviewRulerVisible= (showAnnotationsOverview && overviewRuler !is null); + + createControl(parent, styles); + } + + /* + * @see TextViewer#createControl(Composite, int) + */ + protected void createControl(Composite parent, int styles) { + + if (fVerticalRuler !is null || fOverviewRuler !is null) { + styles= (styles & ~DWT.BORDER); + fComposite= new Canvas(parent, DWT.NONE); + fComposite.setLayout(createLayout()); + parent= fComposite; + } + + super.createControl(parent, styles); + + if (fVerticalRuler !is null) + fVerticalRuler.createControl(fComposite, this); + if (fOverviewRuler !is null) + fOverviewRuler.createControl(fComposite, this); + } + + /** + * Creates the layout used for this viewer. + * Subclasses may override this method. + * + * @return the layout used for this viewer + * @since 3.0 + */ + protected Layout createLayout() { + return new RulerLayout(GAP_SIZE_1); + } + + /* + * @see TextViewer#getControl() + */ + public Control getControl() { + if (fComposite !is null) + return fComposite; + return super.getControl(); + } + + /* + * @see ISourceViewer#setAnnotationHover(IAnnotationHover) + */ + public void setAnnotationHover(IAnnotationHover annotationHover) { + fAnnotationHover= annotationHover; + } + + /** + * Sets the overview ruler's annotation hover of this source viewer. + * The annotation hover provides the information to be displayed in a hover + * popup window if requested over the overview rulers area. The annotation + * hover is assumed to be line oriented. + * + * @param annotationHover the hover to be used, null is a valid argument + * @since 3.0 + */ + public void setOverviewRulerAnnotationHover(IAnnotationHover annotationHover) { + fOverviewRulerAnnotationHover= annotationHover; + } + + /* + * @see ISourceViewer#configure(SourceViewerConfiguration) + */ + public void configure(SourceViewerConfiguration configuration) { + + if (getTextWidget() is null) + return; + + setDocumentPartitioning(configuration.getConfiguredDocumentPartitioning(this)); + + // install content type independent plug-ins + fPresentationReconciler= configuration.getPresentationReconciler(this); + if (fPresentationReconciler !is null) + fPresentationReconciler.install(this); + + fReconciler= configuration.getReconciler(this); + if (fReconciler !is null) + fReconciler.install(this); + + fContentAssistant= configuration.getContentAssistant(this); + if (fContentAssistant !is null) { + fContentAssistant.install(this); + if ( cast(IContentAssistantExtension4)fContentAssistant && cast(IContentAssistantExtension4)fContentAssistant ) + fContentAssistantFacade= new ContentAssistantFacade(fContentAssistant); + fContentAssistantInstalled= true; + } + + fQuickAssistAssistant= configuration.getQuickAssistAssistant(this); + if (fQuickAssistAssistant !is null) { + fQuickAssistAssistant.install(this); + fQuickAssistAssistantInstalled= true; + } + + fContentFormatter= configuration.getContentFormatter(this); + + fInformationPresenter= configuration.getInformationPresenter(this); + if (fInformationPresenter !is null) + fInformationPresenter.install(this); + + setUndoManager(configuration.getUndoManager(this)); + + getTextWidget().setTabs(configuration.getTabWidth(this)); + + setAnnotationHover(configuration.getAnnotationHover(this)); + setOverviewRulerAnnotationHover(configuration.getOverviewRulerAnnotationHover(this)); + + setHoverControlCreator(configuration.getInformationControlCreator(this)); + + setHyperlinkPresenter(configuration.getHyperlinkPresenter(this)); + IHyperlinkDetector[] hyperlinkDetectors= configuration.getHyperlinkDetectors(this); + int eventStateMask= configuration.getHyperlinkStateMask(this); + setHyperlinkDetectors(hyperlinkDetectors, eventStateMask); + + // install content type specific plug-ins + String[] types= configuration.getConfiguredContentTypes(this); + for (int i= 0; i < types.length; i++) { + + String t= types[i]; + + setAutoEditStrategies(configuration.getAutoEditStrategies(this, t), t); + setTextDoubleClickStrategy(configuration.getDoubleClickStrategy(this, t), t); + + int[] stateMasks= configuration.getConfiguredTextHoverStateMasks(this, t); + if (stateMasks !is null) { + for (int j= 0; j < stateMasks.length; j++) { + int stateMask= stateMasks[j]; + setTextHover(configuration.getTextHover(this, t, stateMask), t, stateMask); + } + } else { + setTextHover(configuration.getTextHover(this, t), t, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK); + } + + String[] prefixes= configuration.getIndentPrefixes(this, t); + if (prefixes !is null && prefixes.length > 0) + setIndentPrefixes(prefixes, t); + + prefixes= configuration.getDefaultPrefixes(this, t); + if (prefixes !is null && prefixes.length > 0) + setDefaultPrefixes(prefixes, t); + } + + activatePlugins(); + } + + /** + * After this method has been executed the caller knows that any installed annotation hover has been installed. + */ + protected void ensureAnnotationHoverManagerInstalled() { + if (fVerticalRuler !is null && (fAnnotationHover !is null || !isVerticalRulerOnlyShowingAnnotations()) && fVerticalRulerHoveringController is null && fHoverControlCreator !is null) { + fVerticalRulerHoveringController= new AnnotationBarHoverManager(fVerticalRuler, this, fAnnotationHover, fHoverControlCreator); + fVerticalRulerHoveringController.install(fVerticalRuler.getControl()); + fVerticalRulerHoveringController.getInternalAccessor().setInformationControlReplacer(new StickyHoverManager(this)); + } + } + + /** + * After this method has been executed the caller knows that any installed overview hover has been installed. + */ + protected void ensureOverviewHoverManagerInstalled() { + if (fOverviewRuler !is null && fOverviewRulerAnnotationHover !is null && fOverviewRulerHoveringController is null && fHoverControlCreator !is null) { + fOverviewRulerHoveringController= new OverviewRulerHoverManager(fOverviewRuler, this, fOverviewRulerAnnotationHover, fHoverControlCreator); + fOverviewRulerHoveringController.install(fOverviewRuler.getControl()); + fOverviewRulerHoveringController.getInternalAccessor().setInformationControlReplacer(new StickyHoverManager(this)); + } + } + + /* + * @see dwtx.jface.text.TextViewer#setHoverEnrichMode(dwtx.jface.text.ITextViewerExtension8.EnrichMode) + * @since 3.4 + */ + public void setHoverEnrichMode(ITextViewerExtension8_EnrichMode mode) { + super.setHoverEnrichMode(mode); + if (fVerticalRulerHoveringController !is null) + fVerticalRulerHoveringController.getInternalAccessor().setHoverEnrichMode(mode); + if (fOverviewRulerHoveringController !is null) + fOverviewRulerHoveringController.getInternalAccessor().setHoverEnrichMode(mode); + } + + /* + * @see TextViewer#activatePlugins() + */ + public void activatePlugins() { + ensureAnnotationHoverManagerInstalled(); + ensureOverviewHoverManagerInstalled(); + super.activatePlugins(); + } + + /* + * @see ISourceViewer#setDocument(IDocument, IAnnotationModel) + */ + public void setDocument(IDocument document) { + setDocument(document, null, -1, -1); + } + + /* + * @see ISourceViewer#setDocument(IDocument, IAnnotationModel, int, int) + */ + public void setDocument(IDocument document, int visibleRegionOffset, int visibleRegionLength) { + setDocument(document, null, visibleRegionOffset, visibleRegionLength); + } + + /* + * @see ISourceViewer#setDocument(IDocument, IAnnotationModel) + */ + public void setDocument(IDocument document, IAnnotationModel annotationModel) { + setDocument(document, annotationModel, -1, -1); + } + + /** + * Creates the visual annotation model on top of the given annotation model. + * + * @param annotationModel the wrapped annotation model + * @return the visual annotation model on top of the given annotation model + * @since 3.0 + */ + protected IAnnotationModel createVisualAnnotationModel(IAnnotationModel annotationModel) { + IAnnotationModelExtension model= new AnnotationModel(); + model.addAnnotationModel(MODEL_ANNOTATION_MODEL, annotationModel); + return cast(IAnnotationModel) model; + } + + /** + * Disposes the visual annotation model. + * + * @since 3.1 + */ + protected void disposeVisualAnnotationModel() { + if (fVisualAnnotationModel !is null) { + if (getDocument() !is null) + fVisualAnnotationModel.disconnect(getDocument()); + + if ( cast(IAnnotationModelExtension)fVisualAnnotationModel ) + (cast(IAnnotationModelExtension)fVisualAnnotationModel).removeAnnotationModel(MODEL_ANNOTATION_MODEL); + + fVisualAnnotationModel= null; + } + } + + /* + * @see ISourceViewer#setDocument(IDocument, IAnnotationModel, int, int) + */ + public void setDocument(IDocument document, IAnnotationModel annotationModel, int modelRangeOffset, int modelRangeLength) { + disposeVisualAnnotationModel(); + + if (annotationModel !is null && document !is null) { + fVisualAnnotationModel= createVisualAnnotationModel(annotationModel); + fVisualAnnotationModel.connect(document); + } + + if (modelRangeOffset is -1 && modelRangeLength is -1) + super.setDocument(document); + else + super.setDocument(document, modelRangeOffset, modelRangeLength); + + if (fVerticalRuler !is null) + fVerticalRuler.setModel(fVisualAnnotationModel); + + if (fOverviewRuler !is null) + fOverviewRuler.setModel(fVisualAnnotationModel); + } + + /* + * @see ISourceViewer#getAnnotationModel() + */ + public IAnnotationModel getAnnotationModel() { + if ( cast(IAnnotationModelExtension)fVisualAnnotationModel ) { + IAnnotationModelExtension extension= cast(IAnnotationModelExtension) fVisualAnnotationModel; + return extension.getAnnotationModel(MODEL_ANNOTATION_MODEL); + } + return null; + } + + /* + * @see dwtx.jface.text.source.ISourceViewerExtension3#getQuickAssistAssistant() + * @since 3.2 + */ + public IQuickAssistAssistant getQuickAssistAssistant() { + return fQuickAssistAssistant; + } + + /** + * {@inheritDoc} + * + * @since 3.4 + */ + public final ContentAssistantFacade getContentAssistantFacade() { + return fContentAssistantFacade; + } + + /* + * @see dwtx.jface.text.source.ISourceViewerExtension3#getQuickAssistInvocationContext() + * @since 3.2 + */ + public IQuickAssistInvocationContext getQuickAssistInvocationContext() { + Point selection= getSelectedRange(); + return new TextInvocationContext(this, selection.x, selection.x); + } + + /* + * @see dwtx.jface.text.source.ISourceViewerExtension2#getVisualAnnotationModel() + * @since 3.0 + */ + public IAnnotationModel getVisualAnnotationModel() { + return fVisualAnnotationModel; + } + + /* + * @see dwtx.jface.text.source.ISourceViewerExtension2#unconfigure() + * @since 3.0 + */ + public void unconfigure() { + clearRememberedSelection(); + + if (fPresentationReconciler !is null) { + fPresentationReconciler.uninstall(); + fPresentationReconciler= null; + } + + if (fReconciler !is null) { + fReconciler.uninstall(); + fReconciler= null; + } + + if (fContentAssistant !is null) { + fContentAssistant.uninstall(); + fContentAssistantInstalled= false; + fContentAssistant= null; + if (fContentAssistantFacade !is null) + fContentAssistantFacade= null; + } + + if (fQuickAssistAssistant !is null) { + fQuickAssistAssistant.uninstall(); + fQuickAssistAssistantInstalled= false; + fQuickAssistAssistant= null; + } + + fContentFormatter= null; + + if (fInformationPresenter !is null) { + fInformationPresenter.uninstall(); + fInformationPresenter= null; + } + + fAutoIndentStrategies= null; + fDoubleClickStrategies= null; + fTextHovers= null; + fIndentChars= null; + fDefaultPrefixChars= null; + + if (fVerticalRulerHoveringController !is null) { + fVerticalRulerHoveringController.dispose(); + fVerticalRulerHoveringController= null; + } + + if (fOverviewRulerHoveringController !is null) { + fOverviewRulerHoveringController.dispose(); + fOverviewRulerHoveringController= null; + } + + if (fUndoManager !is null) { + fUndoManager.disconnect(); + fUndoManager= null; + } + + setHyperlinkDetectors(null, DWT.NONE); + } + + /* + * @see dwtx.jface.text.TextViewer#handleDispose() + */ + protected void handleDispose() { + unconfigure(); + + disposeVisualAnnotationModel(); + + fVerticalRuler= null; + + fOverviewRuler= null; + + // http://dev.eclipse.org/bugs/show_bug.cgi?id=15300 + fComposite= null; + + super.handleDispose(); + } + + /* + * @see ITextOperationTarget#canDoOperation(int) + */ + public bool canDoOperation(int operation) { + + if (getTextWidget() is null || (!redraws() && operation !is FORMAT)) + return false; + + if (operation is CONTENTASSIST_PROPOSALS) + return fContentAssistant !is null && fContentAssistantInstalled && isEditable(); + + if (operation is CONTENTASSIST_CONTEXT_INFORMATION) + return fContentAssistant !is null && fContentAssistantInstalled && isEditable(); + + if (operation is QUICK_ASSIST) + return fQuickAssistAssistant !is null && fQuickAssistAssistantInstalled && isEditable(); + + if (operation is INFORMATION) + return fInformationPresenter !is null; + + if (operation is FORMAT) { + return fContentFormatter !is null && isEditable(); + } + + return super.canDoOperation(operation); + } + + /** + * Creates a new formatting context for a format operation. + *

                        + * After the use of the context, clients are required to call + * its dispose method. + * + * @return The new formatting context + * @since 3.0 + */ + protected IFormattingContext createFormattingContext() { + return new FormattingContext(); + } + + /** + * Remembers and returns the current selection. The saved selection can be restored + * by calling restoreSelection(). + * + * @return the current selection + * @see dwtx.jface.text.ITextViewer#getSelectedRange() + * @since 3.0 + */ + protected Point rememberSelection() { + + final Point selection= getSelectedRange(); + final IDocument document= getDocument(); + + if (fSelections.isEmpty()) { + fSelectionCategory= _SELECTION_POSITION_CATEGORY ~ Integer.toString(toHash()); + fSelectionUpdater= new NonDeletingPositionUpdater(fSelectionCategory); + document.addPositionCategory(fSelectionCategory); + document.addPositionUpdater(fSelectionUpdater); + } + + try { + + final Position position= new Position(selection.x, selection.y); + document.addPosition(fSelectionCategory, position); + fSelections.push(position); + + } catch (BadLocationException exception) { + // Should not happen + } catch (BadPositionCategoryException exception) { + // Should not happen + } + + return selection; + } + + /** + * Restores a previously saved selection in the document. + *

                        + * If no selection was previously saved, nothing happens. + * + * @since 3.0 + */ + protected void restoreSelection() { + + if (!fSelections.isEmpty()) { + + final IDocument document= getDocument(); + final Position position= cast(Position) fSelections.pop(); + + try { + document.removePosition(fSelectionCategory, position); + Point currentSelection= getSelectedRange(); + if (currentSelection is null || currentSelection.x !is position.getOffset() || currentSelection.y !is position.getLength()) + setSelectedRange(position.getOffset(), position.getLength()); + + if (fSelections.isEmpty()) + clearRememberedSelection(); + } catch (BadPositionCategoryException exception) { + // Should not happen + } + } + } + + protected void clearRememberedSelection() { + if (!fSelections.isEmpty()) + fSelections.clear(); + + IDocument document= getDocument(); + if (document !is null && fSelectionUpdater !is null) { + document.removePositionUpdater(fSelectionUpdater); + try { + document.removePositionCategory(fSelectionCategory); + } catch (BadPositionCategoryException e) { + // ignore + } + } + fSelectionUpdater= null; + fSelectionCategory= null; + } + + /* + * @see ITextOperationTarget#doOperation(int) + */ + public void doOperation(int operation) { + + if (getTextWidget() is null || (!redraws() && operation !is FORMAT)) + return; + + switch (operation) { + case CONTENTASSIST_PROPOSALS: + fContentAssistant.showPossibleCompletions(); + return; + case CONTENTASSIST_CONTEXT_INFORMATION: + fContentAssistant.showContextInformation(); + return; + case QUICK_ASSIST: + // FIXME: must find a way to post to the status line + /* String msg= */ fQuickAssistAssistant.showPossibleQuickAssists(); + // setStatusLineErrorMessage(msg); + return; + case INFORMATION: + fInformationPresenter.showInformation(); + return; + case FORMAT: + { + final Point selection= rememberSelection(); + final IRewriteTarget target= getRewriteTarget(); + final IDocument document= getDocument(); + IFormattingContext context= null; + DocumentRewriteSession rewriteSession= null; + + if ( cast(IDocumentExtension4)document ) { + IDocumentExtension4 extension= cast(IDocumentExtension4) document; + DocumentRewriteSessionType type= selection.y is 0 || selection.y > 1000 ? DocumentRewriteSessionType.SEQUENTIAL : DocumentRewriteSessionType.UNRESTRICTED_SMALL; + rewriteSession= extension.startRewriteSession(type); + } else { + setRedraw(false); + target.beginCompoundChange(); + } + + try { + + final String rememberedContents= document.get(); + + try { + + if ( cast(IContentFormatterExtension)fContentFormatter ) { + final IContentFormatterExtension extension= cast(IContentFormatterExtension) fContentFormatter; + context= createFormattingContext(); + if (selection.y is 0) { + context.setProperty(stringcast(FormattingContextProperties.CONTEXT_DOCUMENT), Boolean.TRUE); + } else { + context.setProperty(stringcast(FormattingContextProperties.CONTEXT_DOCUMENT), Boolean.FALSE); + context.setProperty(stringcast(FormattingContextProperties.CONTEXT_REGION), new Region(selection.x, selection.y)); + } + extension.format(document, context); + } else { + IRegion r; + if (selection.y is 0) { + IRegion coverage= getModelCoverage(); + r= coverage is null ? new Region(0, 0) : coverage; + } else { + r= new Region(selection.x, selection.y); + } + fContentFormatter.format(document, r); + } + + updateSlaveDocuments(document); + + } catch (RuntimeException x) { + // fire wall for https://bugs.eclipse.org/bugs/show_bug.cgi?id=47472 + // if something went wrong we undo the changes we just did + // TODO to be removed after 3.0 M8 + document.set(rememberedContents); + throw x; + } + + } finally { + + if ( cast(IDocumentExtension4)document ) { + IDocumentExtension4 extension= cast(IDocumentExtension4) document; + extension.stopRewriteSession(rewriteSession); + } else { + target.endCompoundChange(); + setRedraw(true); + } + + restoreSelection(); + if (context !is null) + context.dispose(); + } + return; + } + default: + super.doOperation(operation); + } + } + + /** + * Updates all slave documents of the given document. This default implementation calls updateSlaveDocument + * for their current visible range. Subclasses may reimplement. + * + * @param masterDocument the master document + * @since 3.0 + */ + protected void updateSlaveDocuments(IDocument masterDocument) { + ISlaveDocumentManager manager= getSlaveDocumentManager(); + if ( cast(ISlaveDocumentManagerExtension)manager ) { + ISlaveDocumentManagerExtension extension= cast(ISlaveDocumentManagerExtension) manager; + IDocument[] slaves= extension.getSlaveDocuments(masterDocument); + if (slaves !is null) { + for (int i= 0; i < slaves.length; i++) { + if ( auto child = cast(ChildDocument)slaves[i] ) { + Position p= child.getParentDocumentRange(); + try { + + if (!updateSlaveDocument(child, p.getOffset(), p.getLength())) + child.repairLineInformation(); + + } catch (BadLocationException e) { + // ignore + } + } + } + } + } + } + + /* + * @see ITextOperationTargetExtension#enableOperation(int, bool) + * @since 2.0 + */ + public void enableOperation(int operation, bool enable) { + + switch (operation) { + case CONTENTASSIST_PROPOSALS: + case CONTENTASSIST_CONTEXT_INFORMATION: { + + if (fContentAssistant is null) + return; + + if (enable) { + if (!fContentAssistantInstalled) { + fContentAssistant.install(this); + fContentAssistantInstalled= true; + } + } else if (fContentAssistantInstalled) { + fContentAssistant.uninstall(); + fContentAssistantInstalled= false; + } + break; + } + case QUICK_ASSIST: { + + if (fQuickAssistAssistant is null) + return; + + if (enable) { + if (!fQuickAssistAssistantInstalled) { + fQuickAssistAssistant.install(this); + fQuickAssistAssistantInstalled= true; + } + } else if (fContentAssistantInstalled) { + fQuickAssistAssistant.uninstall(); + fContentAssistantInstalled= false; + } + } + } + } + + /* + * @see ISourceViewer#setRangeIndicator(Annotation) + */ + public void setRangeIndicator(Annotation rangeIndicator) { + fRangeIndicator= rangeIndicator; + } + + /* + * @see ISourceViewer#setRangeIndication(int, int, bool) + */ + public void setRangeIndication(int start, int length, bool moveCursor) { + + if (moveCursor) { + setSelectedRange(start, 0); + revealRange(start, length); + } + + if (fRangeIndicator !is null && cast(IAnnotationModelExtension)fVisualAnnotationModel ) { + IAnnotationModelExtension extension= cast(IAnnotationModelExtension) fVisualAnnotationModel; + extension.modifyAnnotationPosition(fRangeIndicator, new Position(start, length)); + } + } + + /* + * @see ISourceViewer#getRangeIndication() + */ + public IRegion getRangeIndication() { + if (fRangeIndicator !is null && fVisualAnnotationModel !is null) { + Position position= fVisualAnnotationModel.getPosition(fRangeIndicator); + if (position !is null) + return new Region(position.getOffset(), position.getLength()); + } + + return null; + } + + /* + * @see ISourceViewer#removeRangeIndication() + */ + public void removeRangeIndication() { + if (fRangeIndicator !is null && fVisualAnnotationModel !is null) + fVisualAnnotationModel.removeAnnotation(fRangeIndicator); + } + + /* + * @see ISourceViewer#showAnnotations(bool) + */ + public void showAnnotations(bool show) { + bool old= fIsVerticalRulerVisible; + + fIsVerticalRulerVisible= (fVerticalRuler !is null && (show || !isVerticalRulerOnlyShowingAnnotations())); + if (old !is fIsVerticalRulerVisible && fComposite !is null && !fComposite.isDisposed()) + fComposite.layout(); + + if (fIsVerticalRulerVisible && show) + ensureAnnotationHoverManagerInstalled(); + else if (fVerticalRulerHoveringController !is null) { + fVerticalRulerHoveringController.dispose(); + fVerticalRulerHoveringController= null; + } + } + + /** + * Tells whether the vertical ruler only acts as annotation ruler. + * + * @return true if the vertical ruler only show annotations + * @since 3.3 + */ + private bool isVerticalRulerOnlyShowingAnnotations() { + if ( cast(VerticalRuler)fVerticalRuler ) + return true; + + if ( cast(CompositeRuler)fVerticalRuler ) { + Iterator iter= (cast(CompositeRuler)fVerticalRuler).getDecoratorIterator(); + return iter.hasNext() && cast(AnnotationRulerColumn)iter.next() && !iter.hasNext(); + } + return false; + } + + /** + * Returns the vertical ruler of this viewer. + * + * @return the vertical ruler of this viewer + * @since 3.0 + */ + protected final IVerticalRuler getVerticalRuler() { + return fVerticalRuler; + } + + /* + * @see dwtx.jface.text.source.ISourceViewerExtension#showAnnotationsOverview(bool) + * @since 2.1 + */ + public void showAnnotationsOverview(bool show) { + bool old= fIsOverviewRulerVisible; + fIsOverviewRulerVisible= (show && fOverviewRuler !is null); + if (old !is fIsOverviewRulerVisible) { + if (fComposite !is null && !fComposite.isDisposed()) + fComposite.layout(); + if (fIsOverviewRulerVisible) { + ensureOverviewHoverManagerInstalled(); + } else if (fOverviewRulerHoveringController !is null) { + fOverviewRulerHoveringController.dispose(); + fOverviewRulerHoveringController= null; + } + } + } + + /* + * @see dwtx.jface.text.source.ISourceViewer#getCurrentAnnotationHover() + * @since 3.2 + */ + public IAnnotationHover getCurrentAnnotationHover() { + if (fVerticalRulerHoveringController is null) + return null; + return fVerticalRulerHoveringController.getCurrentAnnotationHover(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/SourceViewerConfiguration.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/SourceViewerConfiguration.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,486 @@ +/******************************************************************************* + * 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.text.source.SourceViewerConfiguration; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.dwtxhelper.Collection; + +import dwt.DWT; +import dwt.graphics.RGB; +import dwt.widgets.Shell; +import dwtx.jface.text.DefaultAutoIndentStrategy; +import dwtx.jface.text.DefaultInformationControl; +import dwtx.jface.text.DefaultTextDoubleClickStrategy; +import dwtx.jface.text.IAutoEditStrategy; +import dwtx.jface.text.IAutoIndentStrategy; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentExtension3; +import dwtx.jface.text.IInformationControl; +import dwtx.jface.text.IInformationControlCreator; +import dwtx.jface.text.ITextDoubleClickStrategy; +import dwtx.jface.text.ITextHover; +import dwtx.jface.text.ITextViewerExtension2; +import dwtx.jface.text.IUndoManager; +import dwtx.jface.text.TextViewerUndoManager; +import dwtx.jface.text.contentassist.IContentAssistant; +import dwtx.jface.text.formatter.IContentFormatter; +import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; +import dwtx.jface.text.hyperlink.IHyperlinkDetector; +import dwtx.jface.text.hyperlink.IHyperlinkPresenter; +import dwtx.jface.text.hyperlink.URLHyperlinkDetector; +import dwtx.jface.text.information.IInformationPresenter; +import dwtx.jface.text.presentation.IPresentationReconciler; +import dwtx.jface.text.presentation.PresentationReconciler; +import dwtx.jface.text.quickassist.IQuickAssistAssistant; +import dwtx.jface.text.reconciler.IReconciler; + + +/** + * This class bundles the configuration space of a source viewer. Instances of + * this class are passed to the configure method of + * ISourceViewer. + *

                        + * Each method in this class get as argument the source viewer for which it + * should provide a particular configuration setting such as a presentation + * reconciler. Based on its specific knowledge about the returned object, the + * configuration might share such objects or compute them according to some + * rules.

                        + *

                        + * Clients should subclass and override just those methods which must be + * specific to their needs.

                        + * + * @see dwtx.jface.text.source.ISourceViewer + */ +public class SourceViewerConfiguration { + + + /** + * Creates a new source viewer configuration that behaves according to + * specification of this class' methods. + */ + public this() { +// super(); + } + + /** + * Returns the visual width of the tab character. This implementation always + * returns 4. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @return the tab width + */ + public int getTabWidth(ISourceViewer sourceViewer) { + return 4; + } + + /** + * Returns the undo manager for the given source viewer. This implementation + * always returns a new instance of DefaultUndoManager whose + * history length is set to 25. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @return an undo manager or null if no undo/redo should not be supported + */ + public IUndoManager getUndoManager(ISourceViewer sourceViewer) { + return new TextViewerUndoManager(25); + } + + /** + * Returns the reconciler ready to be used with the given source viewer. + * This implementation always returns null. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @return a reconciler or null if reconciling should not be supported + */ + public IReconciler getReconciler(ISourceViewer sourceViewer) { + return null; + } + + /** + * Returns the presentation reconciler ready to be used with the given source viewer. + * + * @param sourceViewer the source viewer + * @return the presentation reconciler or null if presentation reconciling should not be supported + */ + public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) { + PresentationReconciler reconciler= new PresentationReconciler(); + reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer)); + return reconciler; + } + + /** + * Returns the content formatter ready to be used with the given source viewer. + * This implementation always returns null. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @return a content formatter or null if formatting should not be supported + */ + public IContentFormatter getContentFormatter(ISourceViewer sourceViewer) { + return null; + } + + /** + * Returns the content assistant ready to be used with the given source viewer. + * This implementation always returns null. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @return a content assistant or null if content assist should not be supported + */ + public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) { + return null; + } + + /** + * Returns the quick assist assistant ready to be used with the given + * source viewer. + * This implementation always returns null. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @return a quick assist assistant or null if quick assist should not be supported + * @since 3.2 + */ + public IQuickAssistAssistant getQuickAssistAssistant(ISourceViewer sourceViewer) { + return null; + } + + /** + * Returns the auto indentation strategy ready to be used with the given source viewer + * when manipulating text of the given content type. This implementation always + * returns an new instance of DefaultAutoIndentStrategy. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @param contentType the content type for which the strategy is applicable + * @return the auto indent strategy or null if automatic indentation is not to be enabled + * @deprecated since 3.1 use {@link #getAutoEditStrategies(ISourceViewer, String)} instead + */ + public IAutoIndentStrategy getAutoIndentStrategy(ISourceViewer sourceViewer, String contentType) { + return new DefaultAutoIndentStrategy(); + } + + /** + * Returns the auto edit strategies ready to be used with the given source viewer + * when manipulating text of the given content type. For backward compatibility, this implementation always + * returns an array containing the result of {@link #getAutoIndentStrategy(ISourceViewer, String)}. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @param contentType the content type for which the strategies are applicable + * @return the auto edit strategies or null if automatic editing is not to be enabled + * @since 3.1 + */ + public IAutoEditStrategy[] getAutoEditStrategies(ISourceViewer sourceViewer, String contentType) { + return [ getAutoIndentStrategy(sourceViewer, contentType) ]; + } + + /** + * Returns the default prefixes to be used by the line-prefix operation + * in the given source viewer for text of the given content type. This implementation always + * returns null. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @param contentType the content type for which the prefix is applicable + * @return the default prefixes or null if the prefix operation should not be supported + * @since 2.0 + */ + public String[] getDefaultPrefixes(ISourceViewer sourceViewer, String contentType) { + return null; + } + + /** + * Returns the double-click strategy ready to be used in this viewer when double clicking + * onto text of the given content type. This implementation always returns a new instance of + * DefaultTextDoubleClickStrategy. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @param contentType the content type for which the strategy is applicable + * @return a double-click strategy or null if double clicking should not be supported + */ + public ITextDoubleClickStrategy getDoubleClickStrategy(ISourceViewer sourceViewer, String contentType) { + return new DefaultTextDoubleClickStrategy(); + } + + /** + * Returns the prefixes to be used by the line-shift operation. This implementation + * always returns new String[] { "\t", " ", "" }. + *

                        + * Note: This default is incorrect but cannot be changed in order not + * to break any existing clients. Subclasses should overwrite this method and + * use {@link #getIndentPrefixesForTab(int)} if applicable. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @param contentType the content type for which the prefix is applicable + * @return the prefixes or null if the prefix operation should not be supported + */ + public String[] getIndentPrefixes(ISourceViewer sourceViewer, String contentType) { + return [ "\t", " ", "" ]; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + /** + * Computes and returns the indent prefixes for tab indentation + * which is represented as tabSizeInSpaces. + * + * @param tabWidth the display tab width + * @return the indent prefixes + * @see #getIndentPrefixes(ISourceViewer, String) + * @since 3.3 + */ + protected String[] getIndentPrefixesForTab(int tabWidth) { + String[] indentPrefixes= new String[tabWidth + 2]; + for (int i= 0; i <= tabWidth; i++) { + char[] spaceChars= new char[i]; + Arrays.fill(spaceChars, ' '); + String spaces= new_String(spaceChars); + if (i < tabWidth) + indentPrefixes[i]= spaces ~ '\t'; + else + indentPrefixes[i]= new_String(spaces); + } + indentPrefixes[tabWidth + 1]= ""; //$NON-NLS-1$ + return indentPrefixes; + } + + /** + * Returns the annotation hover which will provide the information to be + * shown in a hover popup window when requested for the given + * source viewer. This implementation always returns null. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @return an annotation hover or null if no hover support should be installed + */ + public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) { + return null; + } + + /** + * Returns the annotation hover which will provide the information to be + * shown in a hover popup window when requested for the overview ruler + * of the given source viewer.This implementation always returns the general + * annotation hover returned by getAnnotationHover. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @return an annotation hover or null if no hover support should be installed + * @since 3.0 + */ + public IAnnotationHover getOverviewRulerAnnotationHover(ISourceViewer sourceViewer) { + return getAnnotationHover(sourceViewer); + } + + /** + * Returns the DWT event state masks for which text hover are configured for + * the given content type. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @param contentType the content type + * @return an int array with the configured DWT event state masks + * or null if text hovers are not supported for the given content type + * @since 2.1 + */ + public int[] getConfiguredTextHoverStateMasks(ISourceViewer sourceViewer, String contentType) { + return null; + } + + /** + * Returns the text hover which will provide the information to be shown + * in a text hover popup window when requested for the given source viewer and + * the given content type. This implementation always returns + * null. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @param contentType the content type + * @param stateMask the DWT event state mask + * @return a text hover or null if no hover support should be installed + * @since 2.1 + */ + public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType, int stateMask) { + if (stateMask is ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK) + return getTextHover(sourceViewer, contentType); + return null; + } + + /** + * Returns the text hover which will provide the information to be shown + * in a text hover popup window when requested for the given source viewer and + * the given content type. This implementation always returns + * null. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @param contentType the content type + * @return a text hover or null if no hover support should be installed + */ + public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) { + return null; + } + + /** + * Returns the information control creator. The creator is a factory creating information + * controls for the given source viewer. This implementation always returns a creator for + * DefaultInformationControl instances. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @return the information control creator or null if no information support should be installed + * @since 2.0 + */ + public IInformationControlCreator getInformationControlCreator(ISourceViewer sourceViewer) { + return new class() IInformationControlCreator { + public IInformationControl createInformationControl(Shell parent) { + return new DefaultInformationControl(parent); + } + }; + } + + /** + * Returns the information presenter which will determine and shown + * information requested for the current cursor position. This implementation + * always returns null. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @return an information presenter null if no information presenter should be installed + * @since 2.0 + */ + public dwtx.jface.text.information.IInformationPresenter.IInformationPresenter getInformationPresenter(ISourceViewer sourceViewer) { + return null; + } + + /** + * Returns all configured content types for the given source viewer. This list + * tells the caller which content types must be configured for the given source + * viewer, i.e. for which content types the given source viewer's functionalities + * must be specified. This implementation always returns + * new String[] { IDocument.DEFAULT_CONTENT_TYPE }. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @return the configured content types for the given viewer + */ + public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) { + return [ IDocument.DEFAULT_CONTENT_TYPE ]; + } + + /** + * Returns the configured partitioning for the given source viewer. The partitioning is + * used when the querying content types from the source viewer's input document. This + * implementation always returns IDocumentExtension3.DEFAULT_PARTITIONING. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @return the configured partitioning + * @see #getConfiguredContentTypes(ISourceViewer) + * @since 3.0 + */ + public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer) { + return IDocumentExtension3.DEFAULT_PARTITIONING; + } + + /** + * Returns the hyperlink detectors which be used to detect hyperlinks + * in the given source viewer. This + * implementation always returns an array with an URL hyperlink detector. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @return an array with hyperlink detectors or null if no hyperlink support should be installed + * @since 3.1 + */ + public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) { + if (sourceViewer is null) + return null; + + return [ new URLHyperlinkDetector() ]; + } + + /** + * Returns the hyperlink presenter for the given source viewer. + * This implementation always returns the {@link DefaultHyperlinkPresenter}. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @return the hyperlink presenter or null if no hyperlink support should be installed + * @since 3.1 + */ + public IHyperlinkPresenter getHyperlinkPresenter(ISourceViewer sourceViewer) { + return new DefaultHyperlinkPresenter(new RGB(0, 0, 255)); + } + + /** + * Returns the DWT event state mask which in combination + * with the left mouse button activates hyperlinking. + * This implementation always returns the {@link DWT#MOD1}. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @return the DWT event state mask to activate hyperlink mode + * @since 3.1 + */ + public int getHyperlinkStateMask(ISourceViewer sourceViewer) { + return DWT.MOD1; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/TextInvocationContext.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/TextInvocationContext.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,124 @@ +/******************************************************************************* + * 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 + * 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.text.source.TextInvocationContext; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.quickassist.IQuickAssistInvocationContext; + + +/** + * Text quick assist invocation context. + *

                        + * Clients may extend this class to add additional context information. + *

                        + * + * @since 3.3 + */ +public class TextInvocationContext : IQuickAssistInvocationContext { + + private ISourceViewer fSourceViewer; + private int fOffset; + private int fLength; + + public this(ISourceViewer sourceViewer, int offset, int length) { + fSourceViewer= sourceViewer; + fOffset= offset; + fLength= length; + } + + /* + * @see dwtx.jface.text.quickassist.IQuickAssistInvocationContext#getOffset() + */ + public int getOffset() { + return fOffset; + } + + /* + * @see dwtx.jface.text.quickassist.IQuickAssistInvocationContext#getLength() + */ + public int getLength() { + return fLength; + } + + /* + * @see dwtx.jface.text.quickassist.IQuickAssistInvocationContext#getSourceViewer() + */ + public ISourceViewer getSourceViewer() { + return fSourceViewer; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/VerticalRuler.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/VerticalRuler.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,664 @@ +/******************************************************************************* + * 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 + * 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.text.source.VerticalRuler; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.dwtxhelper.Collection; + +import dwt.DWT; +import dwt.custom.StyledText; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.events.MouseEvent; +import dwt.events.MouseListener; +import dwt.events.PaintEvent; +import dwt.events.PaintListener; +import dwt.graphics.Font; +import dwt.graphics.GC; +import dwt.graphics.Image; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Canvas; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextListener; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.ITextViewerExtension5; +import dwtx.jface.text.IViewportListener; +import dwtx.jface.text.JFaceTextUtil; +import dwtx.jface.text.Position; +import dwtx.jface.text.Region; +import dwtx.jface.text.TextEvent; + + +/** + * A vertical ruler which is connected to a text viewer. Single column standard + * implementation of {@link dwtx.jface.text.source.IVerticalRuler}. + *

                        + * The same can be achieved by using CompositeRuler configured + * with an AnnotationRulerColumn. Clients may use this class as + * is. + * + * @see dwtx.jface.text.ITextViewer + */ +public final class VerticalRuler : IVerticalRuler, IVerticalRulerExtension { + + /** + * Internal listener class. + */ + class InternalListener : IViewportListener, IAnnotationModelListener, ITextListener { + + /* + * @see IViewportListener#viewportChanged(int) + */ + public void viewportChanged(int verticalPosition) { + if (verticalPosition !is fScrollPos) + redraw(); + } + + /* + * @see IAnnotationModelListener#modelChanged(IAnnotationModel) + */ + public void modelChanged(IAnnotationModel model) { + update(); + } + + /* + * @see ITextListener#textChanged(TextEvent) + */ + public void textChanged(TextEvent e) { + if (fTextViewer !is null && e.getViewerRedrawState()) + redraw(); + } + } + + /** The vertical ruler's text viewer */ + private ITextViewer fTextViewer; + /** The ruler's canvas */ + private Canvas fCanvas; + /** The vertical ruler's model */ + private IAnnotationModel fModel; + /** Cache for the actual scroll position in pixels */ + private int fScrollPos; + /** The buffer for double buffering */ + private Image fBuffer; + /** The line of the last mouse button activity */ + private int fLastMouseButtonActivityLine= -1; + /** The internal listener */ + private InternalListener fInternalListener; + /** The width of this vertical ruler */ + private int fWidth; + /** + * The annotation access of this vertical ruler + * @since 3.0 + */ + private IAnnotationAccess fAnnotationAccess; + + /** + * Constructs a vertical ruler with the given width. + * + * @param width the width of the vertical ruler + */ + public this(int width) { + this(width, null); + } + + /** + * Constructs a vertical ruler with the given width and the given annotation + * access. + * + * @param width the width of the vertical ruler + * @param annotationAcccess the annotation access + * @since 3.0 + */ + public this(int width, IAnnotationAccess annotationAcccess) { + + fInternalListener= new InternalListener(); + + fWidth= width; + fAnnotationAccess= annotationAcccess; + } + + /* + * @see IVerticalRuler#getControl() + */ + public Control getControl() { + return fCanvas; + } + + /* + * @see IVerticalRuler#createControl(Composite, ITextViewer) + */ + public Control createControl(Composite parent, ITextViewer textViewer) { + + fTextViewer= textViewer; + + fCanvas= new Canvas(parent, DWT.NO_BACKGROUND); + + fCanvas.addPaintListener(new class() PaintListener { + public void paintControl(PaintEvent event) { + if (fTextViewer !is null) + doubleBufferPaint(event.gc); + } + }); + + fCanvas.addDisposeListener(new class() DisposeListener { + public void widgetDisposed(DisposeEvent e) { + handleDispose(); + fTextViewer= null; + } + }); + + fCanvas.addMouseListener(new class() MouseListener { + public void mouseUp(MouseEvent event) { + } + + public void mouseDown(MouseEvent event) { + fLastMouseButtonActivityLine= toDocumentLineNumber(event.y); + } + + public void mouseDoubleClick(MouseEvent event) { + fLastMouseButtonActivityLine= toDocumentLineNumber(event.y); + } + }); + + if (fTextViewer !is null) { + fTextViewer.addViewportListener(fInternalListener); + fTextViewer.addTextListener(fInternalListener); + } + + return fCanvas; + } + + /** + * Disposes the ruler's resources. + */ + private void handleDispose() { + + if (fTextViewer !is null) { + fTextViewer.removeViewportListener(fInternalListener); + fTextViewer.removeTextListener(fInternalListener); + fTextViewer= null; + } + + if (fModel !is null) + fModel.removeAnnotationModelListener(fInternalListener); + + if (fBuffer !is null) { + fBuffer.dispose(); + fBuffer= null; + } + } + + + /** + * Double buffer drawing. + * + * @param dest the GC to draw into + */ + private void doubleBufferPaint(GC dest) { + + Point size= fCanvas.getSize(); + + if (size.x <= 0 || size.y <= 0) + return; + + if (fBuffer !is null) { + Rectangle r= fBuffer.getBounds(); + if (r.width !is size.x || r.height !is size.y) { + fBuffer.dispose(); + fBuffer= null; + } + } + if (fBuffer is null) + fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y); + + GC gc= new GC(fBuffer); + gc.setFont(fTextViewer.getTextWidget().getFont()); + try { + gc.setBackground(fCanvas.getBackground()); + gc.fillRectangle(0, 0, size.x, size.y); + + if ( cast(ITextViewerExtension5)fTextViewer ) + doPaint1(gc); + else + doPaint(gc); + + } finally { + gc.dispose(); + } + + dest.drawImage(fBuffer, 0, 0); + } + + /** + * Returns the document offset of the upper left corner of the + * widgets view port, possibly including partially visible lines. + * + * @return the document offset of the upper left corner including partially visible lines + * @since 2.0 + */ + private int getInclusiveTopIndexStartOffset() { + + StyledText textWidget= fTextViewer.getTextWidget(); + if (textWidget !is null && !textWidget.isDisposed()) { + int top= JFaceTextUtil.getPartialTopIndex(fTextViewer); + try { + IDocument document= fTextViewer.getDocument(); + return document.getLineOffset(top); + } catch (BadLocationException x) { + } + } + + return -1; + } + + + + /** + * Draws the vertical ruler w/o drawing the Canvas background. + * + * @param gc the GC to draw into + */ + protected void doPaint(GC gc) { + + if (fModel is null || fTextViewer is null) + return; + + IAnnotationAccessExtension annotationAccessExtension= null; + if ( cast(IAnnotationAccessExtension)fAnnotationAccess ) + annotationAccessExtension= cast(IAnnotationAccessExtension) fAnnotationAccess; + + StyledText styledText= fTextViewer.getTextWidget(); + IDocument doc= fTextViewer.getDocument(); + + int topLeft= getInclusiveTopIndexStartOffset(); + int bottomRight= fTextViewer.getBottomIndexEndOffset(); + int viewPort= bottomRight - topLeft; + + Point d= fCanvas.getSize(); + fScrollPos= styledText.getTopPixel(); + + int topLine= -1, bottomLine= -1; + try { + IRegion region= fTextViewer.getVisibleRegion(); + topLine= doc.getLineOfOffset(region.getOffset()); + bottomLine= doc.getLineOfOffset(region.getOffset() + region.getLength()); + } catch (BadLocationException x) { + return; + } + + // draw Annotations + Rectangle r= new Rectangle(0, 0, 0, 0); + int maxLayer= 1; // loop at least once though layers. + + for (int layer= 0; layer < maxLayer; layer++) { + Iterator iter= fModel.getAnnotationIterator(); + while (iter.hasNext()) { + IAnnotationPresentation annotationPresentation= null; + Annotation annotation= cast(Annotation) iter.next(); + + int lay= IAnnotationAccessExtension.DEFAULT_LAYER; + if (annotationAccessExtension !is null) + lay= annotationAccessExtension.getLayer(annotation); + else if ( cast(IAnnotationPresentation)annotation ) { + annotationPresentation= cast(IAnnotationPresentation)annotation; + lay= annotationPresentation.getLayer(); + } + maxLayer= Math.max(maxLayer, lay+1); // dynamically update layer maximum + if (lay !is layer) // wrong layer: skip annotation + continue; + + Position position= fModel.getPosition(annotation); + if (position is null) + continue; + + if (!position.overlapsWith(topLeft, viewPort)) + continue; + + try { + + int offset= position.getOffset(); + int length= position.getLength(); + + int startLine= doc.getLineOfOffset(offset); + if (startLine < topLine) + startLine= topLine; + + int endLine= startLine; + if (length > 0) + endLine= doc.getLineOfOffset(offset + length - 1); + if (endLine > bottomLine) + endLine= bottomLine; + + startLine -= topLine; + endLine -= topLine; + + r.x= 0; + r.y= JFaceTextUtil.computeLineHeight(styledText, 0, startLine, startLine) - fScrollPos; + + r.width= d.x; + int lines= endLine - startLine; + + r.height= JFaceTextUtil.computeLineHeight(styledText, startLine, endLine + 1, (lines+1)); + + if (r.y < d.y && annotationAccessExtension !is null) // annotation within visible area + annotationAccessExtension.paint(annotation, gc, fCanvas, r); + else if (annotationPresentation !is null) + annotationPresentation.paint(gc, fCanvas, r); + + } catch (BadLocationException e) { + } + } + } + } + + /** + * Draws the vertical ruler w/o drawing the Canvas background. Uses + * ITextViewerExtension5 for its implementation. Will replace + * doPaint(GC). + * + * @param gc the GC to draw into + */ + protected void doPaint1(GC gc) { + + if (fModel is null || fTextViewer is null) + return; + + IAnnotationAccessExtension annotationAccessExtension= null; + if ( cast(IAnnotationAccessExtension)fAnnotationAccess ) + annotationAccessExtension= cast(IAnnotationAccessExtension) fAnnotationAccess; + + ITextViewerExtension5 extension= cast(ITextViewerExtension5) fTextViewer; + StyledText textWidget= fTextViewer.getTextWidget(); + + fScrollPos= textWidget.getTopPixel(); + Point dimension= fCanvas.getSize(); + + // draw Annotations + Rectangle r= new Rectangle(0, 0, 0, 0); + int maxLayer= 1; // loop at least once through layers. + + for (int layer= 0; layer < maxLayer; layer++) { + Iterator iter= fModel.getAnnotationIterator(); + while (iter.hasNext()) { + IAnnotationPresentation annotationPresentation= null; + Annotation annotation= cast(Annotation) iter.next(); + + int lay= IAnnotationAccessExtension.DEFAULT_LAYER; + if (annotationAccessExtension !is null) + lay= annotationAccessExtension.getLayer(annotation); + else if ( cast(IAnnotationPresentation)annotation ) { + annotationPresentation= cast(IAnnotationPresentation)annotation; + lay= annotationPresentation.getLayer(); + } + maxLayer= Math.max(maxLayer, lay+1); // dynamically update layer maximum + if (lay !is layer) // wrong layer: skip annotation + continue; + + Position position= fModel.getPosition(annotation); + if (position is null) + continue; + + IRegion widgetRegion= extension.modelRange2WidgetRange(new Region(position.getOffset(), position.getLength())); + if (widgetRegion is null) + continue; + + int startLine= extension.widgetLineOfWidgetOffset(widgetRegion.getOffset()); + if (startLine is -1) + continue; + + int endLine= extension.widgetLineOfWidgetOffset(widgetRegion.getOffset() + Math.max(widgetRegion.getLength() -1, 0)); + if (endLine is -1) + continue; + + r.x= 0; + r.y= JFaceTextUtil.computeLineHeight(textWidget, 0, startLine, startLine) - fScrollPos; + + r.width= dimension.x; + int lines= endLine - startLine; + + r.height= JFaceTextUtil.computeLineHeight(textWidget, startLine, endLine + 1, lines+1); + + if (r.y < dimension.y && annotationAccessExtension !is null) // annotation within visible area + annotationAccessExtension.paint(annotation, gc, fCanvas, r); + else if (annotationPresentation !is null) + annotationPresentation.paint(gc, fCanvas, r); + } + } + } + + /** + * Thread-safe implementation. + * Can be called from any thread. + */ + /* + * @see IVerticalRuler#update() + */ + public void update() { + if (fCanvas !is null && !fCanvas.isDisposed()) { + Display d= fCanvas.getDisplay(); + if (d !is null) { + d.asyncExec(new class() Runnable { + public void run() { + redraw(); + } + }); + } + } + } + + /** + * Redraws the vertical ruler. + */ + private void redraw() { + if (fCanvas !is null && !fCanvas.isDisposed()) { + GC gc= new GC(fCanvas); + doubleBufferPaint(gc); + gc.dispose(); + } + } + + /* + * @see IVerticalRuler#setModel(IAnnotationModel) + */ + public void setModel(IAnnotationModel model) { + if (model !is fModel) { + + if (fModel !is null) + fModel.removeAnnotationModelListener(fInternalListener); + + fModel= model; + + if (fModel !is null) + fModel.addAnnotationModelListener(fInternalListener); + + update(); + } + } + + /* + * @see IVerticalRuler#getModel() + */ + public IAnnotationModel getModel() { + return fModel; + } + + /* + * @see IVerticalRulerInfo#getWidth() + */ + public int getWidth() { + return fWidth; + } + + /* + * @see IVerticalRulerInfo#getLineOfLastMouseButtonActivity() + */ + public int getLineOfLastMouseButtonActivity() { + IDocument doc= fTextViewer.getDocument(); + if (doc is null || fLastMouseButtonActivityLine >= fTextViewer.getDocument().getNumberOfLines()) + fLastMouseButtonActivityLine= -1; + return fLastMouseButtonActivityLine; + } + + /* + * @see IVerticalRulerInfo#toDocumentLineNumber(int) + */ + public int toDocumentLineNumber(int y_coordinate) { + if (fTextViewer is null || y_coordinate is -1) + return -1; + + StyledText text= fTextViewer.getTextWidget(); + int line= text.getLineIndex(y_coordinate); + + if (line is text.getLineCount() - 1) { + // check whether y_coordinate exceeds last line + if (y_coordinate > text.getLinePixel(line + 1)) + return -1; + } + + return widgetLine2ModelLine(fTextViewer, line); + } + + /** + * Returns the line of the viewer's document that corresponds to the given widget line. + * + * @param viewer the viewer + * @param widgetLine the widget line + * @return the corresponding line of the viewer's document + * @since 2.1 + */ + protected final static int widgetLine2ModelLine(ITextViewer viewer, int widgetLine) { + + if ( cast(ITextViewerExtension5)viewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) viewer; + return extension.widgetLine2ModelLine(widgetLine); + } + + try { + IRegion r= viewer.getVisibleRegion(); + IDocument d= viewer.getDocument(); + return widgetLine += d.getLineOfOffset(r.getOffset()); + } catch (BadLocationException x) { + } + return widgetLine; + } + + /* + * @see IVerticalRulerExtension#setFont(Font) + * @since 2.0 + */ + public void setFont(Font font) { + } + + /* + * @see IVerticalRulerExtension#setLocationOfLastMouseButtonActivity(int, int) + * @since 2.0 + */ + public void setLocationOfLastMouseButtonActivity(int x, int y) { + fLastMouseButtonActivityLine= toDocumentLineNumber(y); + } + + /** + * Adds the given mouse listener. + * + * @param listener the listener to be added + * @deprecated will be removed + * @since 2.0 + */ + public void addMouseListener(MouseListener listener) { + if (fCanvas !is null && !fCanvas.isDisposed()) + fCanvas.addMouseListener(listener); + } + + /** + * Removes the given mouse listener. + * + * @param listener the listener to be removed + * @deprecated will be removed + * @since 2.0 + */ + public void removeMouseListener(MouseListener listener) { + if (fCanvas !is null && !fCanvas.isDisposed()) + fCanvas.removeMouseListener(listener); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/VerticalRulerEvent.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/VerticalRulerEvent.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.VerticalRulerEvent; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.VisualAnnotationModel; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * An event sent to {@link dwtx.jface.text.source.IVerticalRulerListener} instances when annotation + * related event occurs on the vertical ruler. + * + * @since 3.0 + */ +public class VerticalRulerEvent { + + private Annotation fAnnotation; + + /** + * Creates a new event. + * + * @param annotation the annotation concerned, or null + */ + public this(Annotation annotation) { + fAnnotation= annotation; + } + + /** + * @return the concerned annotation or null + */ + public Annotation getSelectedAnnotation() { + return fAnnotation; + } + + /** + * @param annotation the concerned annotation, or null + */ + public void setSelectedAnnotation(Annotation annotation) { + fAnnotation= annotation; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/VisualAnnotationModel.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/VisualAnnotationModel.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,211 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.VisualAnnotationModel; + +import dwtx.jface.text.source.ISharedTextColors; // packageimport +import dwtx.jface.text.source.ILineRange; // packageimport +import dwtx.jface.text.source.IAnnotationPresentation; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport +import dwtx.jface.text.source.TextInvocationContext; // packageimport +import dwtx.jface.text.source.LineChangeHover; // packageimport +import dwtx.jface.text.source.IChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationMap; // packageimport +import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationHover; // packageimport +import dwtx.jface.text.source.ContentAssistantFacade; // packageimport +import dwtx.jface.text.source.IAnnotationAccess; // packageimport +import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport +import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport +import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport +import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport +import dwtx.jface.text.source.ILineDifferExtension; // packageimport +import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport +import dwtx.jface.text.source.ISourceViewer; // packageimport +import dwtx.jface.text.source.AnnotationModel; // packageimport +import dwtx.jface.text.source.ILineDifferExtension2; // packageimport +import dwtx.jface.text.source.IAnnotationModelListener; // packageimport +import dwtx.jface.text.source.IVerticalRuler; // packageimport +import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport +import dwtx.jface.text.source.SourceViewer; // packageimport +import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport +import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport +import dwtx.jface.text.source.CompositeRuler; // packageimport +import dwtx.jface.text.source.ImageUtilities; // packageimport +import dwtx.jface.text.source.IAnnotationModel; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport +import dwtx.jface.text.source.ILineDiffInfo; // packageimport +import dwtx.jface.text.source.VerticalRulerEvent; // packageimport +import dwtx.jface.text.source.ChangeRulerColumn; // packageimport +import dwtx.jface.text.source.ILineDiffer; // packageimport +import dwtx.jface.text.source.AnnotationModelEvent; // packageimport +import dwtx.jface.text.source.AnnotationColumn; // packageimport +import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport +import dwtx.jface.text.source.AbstractRulerColumn; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension; // packageimport +import dwtx.jface.text.source.AnnotationMap; // packageimport +import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport +import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport +import dwtx.jface.text.source.LineRange; // packageimport +import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport +import dwtx.jface.text.source.VerticalRuler; // packageimport +import dwtx.jface.text.source.JFaceTextMessages; // packageimport +import dwtx.jface.text.source.IOverviewRuler; // packageimport +import dwtx.jface.text.source.Annotation; // packageimport +import dwtx.jface.text.source.IVerticalRulerListener; // packageimport +import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport +import dwtx.jface.text.source.AnnotationPainter; // packageimport +import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport +import dwtx.jface.text.source.OverviewRuler; // packageimport +import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.dwtxhelper.Collection; + + +import dwtx.jface.text.IDocument; +import dwtx.jface.text.Position; + + + +/** + * Annotation model for visual annotations. Assume a viewer's input element is annotated with + * some semantic annotation such as a breakpoint and that it is simultaneously shown in multiple + * viewers. A source viewer, e.g., supports visual range indication for which it utilizes + * annotations. The range indicating annotation is specific to the visual presentation + * of the input element in this viewer and thus should only be visible in this viewer. The + * breakpoints however are independent from the input element's presentation and thus should + * be shown in all viewers in which the element is shown. As a viewer supports one vertical + * ruler which is based on one annotation model, there must be a visual annotation model for + * each viewer which all wrap the same element specific model annotation model. + */ +class VisualAnnotationModel : AnnotationModel , IAnnotationModelListener { + + /** The wrapped model annotation model */ + private IAnnotationModel fModel; + + /** + * Constructs a visual annotation model which wraps the given + * model based annotation model + * + * @param modelAnnotationModel the model based annotation model + */ + public this(IAnnotationModel modelAnnotationModel) { + fModel= modelAnnotationModel; + } + + /** + * Returns the visual annotation model's wrapped model based annotation model. + * + * @return the model based annotation model + */ + public IAnnotationModel getModelAnnotationModel() { + return fModel; + } + + /* + * @see IAnnotationModel#addAnnotationModelListener(IAnnotationModelListener) + */ + public void addAnnotationModelListener(IAnnotationModelListener listener) { + + if (fModel !is null && fAnnotationModelListeners.isEmpty()) + fModel.addAnnotationModelListener(this); + + super.addAnnotationModelListener(listener); + } + + /* + * @see IAnnotationModel#connect(IDocument) + */ + public void connect(IDocument document) { + super.connect(document); + if (fModel !is null) + fModel.connect(document); + } + + /* + * @see IAnnotationModel#disconnect(IDocument) + */ + public void disconnect(IDocument document) { + super.disconnect(document); + if (fModel !is null) + fModel.disconnect(document); + } + + /* + * @see IAnnotationModel#getAnnotationIterator() + */ + public Iterator getAnnotationIterator() { + + if (fModel is null) + return super.getAnnotationIterator(); + + ArrayList a= new ArrayList(20); + + Iterator e= fModel.getAnnotationIterator(); + while (e.hasNext()) + a.add(e.next()); + + e= super.getAnnotationIterator(); + while (e.hasNext()) + a.add(e.next()); + + return a.iterator(); + } + + /* + * @see IAnnotationModel#getPosition(Annotation) + */ + public Position getPosition(Annotation annotation) { + + Position p= cast(Position) getAnnotationMap().get(annotation); + if (p !is null) + return p; + + if (fModel !is null) + return fModel.getPosition(annotation); + + return null; + } + + /* + * @see IAnnotationModelListener#modelChanged(IAnnotationModel) + */ + public void modelChanged(IAnnotationModel model) { + if (model is fModel) { + Iterator iter= (new ArrayList(fAnnotationModelListeners)).iterator(); + while (iter.hasNext()) { + IAnnotationModelListener l= cast(IAnnotationModelListener)iter.next(); + l.modelChanged(this); + } + } + } + + /* + * @see IAnnotationModel#removeAnnotationModelListener(IAnnotationModelListener) + */ + public void removeAnnotationModelListener(IAnnotationModelListener listener) { + super.removeAnnotationModelListener(listener); + + if (fModel !is null && fAnnotationModelListeners.isEmpty()) + fModel.removeAnnotationModelListener(this); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/projection/AnnotationBag.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/projection/AnnotationBag.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,102 @@ +/******************************************************************************* + * 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 + * 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.text.source.projection.AnnotationBag; + +import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport +import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport +import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport +import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport +import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport +import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport +import dwtx.jface.text.source.projection.IProjectionListener; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + +import dwtx.jface.text.source.Annotation; + +/** + * A bag of annotations. + *

                        + * This class is not intended to be subclassed. + *

                        + * + * @since 3.0 + * @noextend This class is not intended to be subclassed by clients. + */ +public class AnnotationBag : Annotation { + + private Set fAnnotations; + + /** + * Creates a new annotation bag. + * + * @param type the annotation type + */ + public this(String type) { + super(type, false, null); + } + + /** + * Adds the given annotation to the annotation bag. + * + * @param annotation the annotation to add + */ + public void add(Annotation annotation) { + if (fAnnotations is null) + fAnnotations= new HashSet(2); + fAnnotations.add(annotation); + } + + /** + * Removes the given annotation from the annotation bag. + * + * @param annotation the annotation to remove + */ + public void remove(Annotation annotation) { + if (fAnnotations !is null) { + fAnnotations.remove(annotation); + if (fAnnotations.isEmpty()) + fAnnotations= null; + } + } + + /** + * Returns whether the annotation bag is empty. + * + * @return true if the annotation bag is empty, false otherwise + */ + public bool isEmpty() { + return fAnnotations is null; + } + + /** + * Returns an iterator for all annotation inside this + * annotation bag or null if the bag is empty. + * + * @return an iterator for all annotations in the bag or null + * @since 3.1 + */ + public Iterator iterator() { + if (!isEmpty()) + return fAnnotations.iterator(); + return null; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/projection/IProjectionListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/projection/IProjectionListener.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.projection.IProjectionListener; + +import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport +import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport +import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport +import dwtx.jface.text.source.projection.AnnotationBag; // packageimport +import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport +import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport +import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Implementers registered with a + * {@link dwtx.jface.text.source.projection.ProjectionViewer} get + * informed when the projection mode of the viewer gets enabled and when it gets + * disabled. + * + * @since 3.0 + */ +public interface IProjectionListener { + + /** + * Tells this listener that projection has been enabled. + */ + void projectionEnabled(); + + /** + * Tells this listener that projection has been disabled. + */ + void projectionDisabled(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/projection/IProjectionPosition.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/projection/IProjectionPosition.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.source.projection.IProjectionPosition; + +import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport +import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport +import dwtx.jface.text.source.projection.AnnotationBag; // packageimport +import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport +import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport +import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport +import dwtx.jface.text.source.projection.IProjectionListener; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; + + +/** + * An IProjectionPosition is a position that is associated with a + * ProjectionAnnotation and that is able to compute its collapsed + * regions. That is, if a Position implements this interface, + * ProjectionViewer will delegate to the + * {@link #computeProjectionRegions(IDocument) computeProjectionRegions} method + * when determining the document regions that should be collapsed for a certain + * ProjectionAnnotation. + * + * @since 3.1 + */ +public interface IProjectionPosition { + + /** + * Returns an array of regions that should be collapsed when the annotation + * belonging to this position is collapsed. May return null instead of + * an empty array. + * + * @param document the document that this position is attached to + * @return the foldable regions for this position + * @throws BadLocationException if accessing the document fails + */ + IRegion[] computeProjectionRegions(IDocument document) ; + + /** + * Returns the offset of the caption (the anchor region) of this projection + * position. The returned offset is relative to the receivers offset into + * the document. + * + * @param document the document that this position is attached to + * @return the caption offset relative to the position's offset + * @throws BadLocationException if accessing the document fails + */ + int computeCaptionOffset(IDocument document) ; + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/projection/ProjectionAnnotation.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/projection/ProjectionAnnotation.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,191 @@ +/******************************************************************************* + * 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 + * 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.text.source.projection.ProjectionAnnotation; + +import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport +import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport +import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport +import dwtx.jface.text.source.projection.AnnotationBag; // packageimport +import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport +import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport +import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport +import dwtx.jface.text.source.projection.IProjectionListener; // packageimport + + +import dwt.dwthelper.utils; + + + + +import dwt.DWT; +import dwt.graphics.FontMetrics; +import dwt.graphics.GC; +import dwt.graphics.Image; +import dwt.graphics.Rectangle; +import dwt.widgets.Canvas; +import dwt.widgets.Display; +import dwtx.jface.resource.ImageDescriptor; +import dwtx.jface.text.source.Annotation; +import dwtx.jface.text.source.IAnnotationPresentation; +import dwtx.jface.text.source.ImageUtilities; + +/** + * Annotation used to represent the projection of a master document onto a + * {@link dwtx.jface.text.projection.ProjectionDocument}. A projection + * annotation can be either expanded or collapsed. If expanded it corresponds to + * a segment of the projection document. If collapsed, it represents a region of + * the master document that does not have a corresponding segment in the + * projection document. + *

                        + * Clients may subclass or use as is. + *

                        + * + * @since 3.0 + */ +public class ProjectionAnnotation : Annotation , IAnnotationPresentation { + + private static class DisplayDisposeRunnable : Runnable { + + public void run() { + if (fgCollapsedImage !is null) { + fgCollapsedImage.dispose(); + fgCollapsedImage= null; + } + if (fgExpandedImage !is null) { + fgExpandedImage.dispose(); + fgExpandedImage= null; + } + } + } + + /** + * The type of projection annotations. + */ + public static const String TYPE= "dwtx.projection"; //$NON-NLS-1$ + + + private static const int COLOR= DWT.COLOR_GRAY; + private static Image fgCollapsedImage; + private static Image fgExpandedImage; + + + /** The state of this annotation */ + private bool fIsCollapsed= false; + /** Indicates whether this annotation should be painted as range */ + private bool fIsRangeIndication= false; + + /** + * Creates a new expanded projection annotation. + */ + public this() { + this(false); + } + + /** + * Creates a new projection annotation. When isCollapsed + * is true the annotation is initially collapsed. + * + * @param isCollapsed true if the annotation should initially be collapsed, false otherwise + */ + public this(bool isCollapsed) { + super(TYPE, false, null); + fIsCollapsed= isCollapsed; + } + + /** + * Enables and disables the range indication for this annotation. + * + * @param rangeIndication the enable state for the range indication + */ + public void setRangeIndication(bool rangeIndication) { + fIsRangeIndication= rangeIndication; + } + + private void drawRangeIndication(GC gc, Canvas canvas, Rectangle r) { + final int MARGIN= 3; + + /* cap the height - at least on GTK, large numbers are converted to + * negatives at some point */ + int height= Math.min(r.y + r.height - MARGIN, canvas.getSize().y); + + gc.setForeground(canvas.getDisplay().getSystemColor(COLOR)); + gc.setLineWidth(0); // NOTE: 0 means width is 1 but with optimized performance + gc.drawLine(r.x + 4, r.y + 12, r.x + 4, height); + gc.drawLine(r.x + 4, height, r.x + r.width - MARGIN, height); + } + + /* + * @see dwtx.jface.text.source.IAnnotationPresentation#paint(dwt.graphics.GC, dwt.widgets.Canvas, dwt.graphics.Rectangle) + */ + public void paint(GC gc, Canvas canvas, Rectangle rectangle) { + Image image= getImage(canvas.getDisplay()); + if (image !is null) { + ImageUtilities.drawImage(image, gc, canvas, rectangle, DWT.CENTER, DWT.TOP); + if (fIsRangeIndication) { + FontMetrics fontMetrics= gc.getFontMetrics(); + int delta= (fontMetrics.getHeight() - image.getBounds().height)/2; + rectangle.y += delta; + rectangle.height -= delta; + drawRangeIndication(gc, canvas, rectangle); + } + } + } + + /* + * @see dwtx.jface.text.source.IAnnotationPresentation#getLayer() + */ + public int getLayer() { + return IAnnotationPresentation.DEFAULT_LAYER; + } + + private Image getImage(Display display) { + initializeImages(display); + return isCollapsed() ? fgCollapsedImage : fgExpandedImage; + } + + private void initializeImages(Display display) { + if (fgCollapsedImage is null) { + ImageDescriptor descriptor= ImageDescriptor.createFromFile( getImportData!("dwtx.jface.text.source.projection.collapsed.gif")); //$NON-NLS-1$ + fgCollapsedImage= descriptor.createImage(display); + descriptor= ImageDescriptor.createFromFile( getImportData!( "dwtx.jface.text.source.projection.expanded.gif")); //$NON-NLS-1$ + fgExpandedImage= descriptor.createImage(display); + + display.disposeExec(new DisplayDisposeRunnable()); + } + } + + /** + * Returns the state of this annotation. + * + * @return true if collapsed + */ + public bool isCollapsed() { + return fIsCollapsed; + } + + /** + * Marks this annotation as being collapsed. + */ + public void markCollapsed() { + fIsCollapsed= true; + } + + /** + * Marks this annotation as being unfolded. + */ + public void markExpanded() { + fIsCollapsed= false; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/projection/ProjectionAnnotationHover.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/projection/ProjectionAnnotationHover.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,204 @@ +/******************************************************************************* + * 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 + * 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.text.source.projection.ProjectionAnnotationHover; + +import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport +import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport +import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport +import dwtx.jface.text.source.projection.AnnotationBag; // packageimport +import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport +import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport +import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport +import dwtx.jface.text.source.projection.IProjectionListener; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + +import dwt.widgets.Shell; +import dwtx.jface.resource.JFaceResources; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IInformationControl; +import dwtx.jface.text.IInformationControlCreator; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.Position; +import dwtx.jface.text.information.IInformationProviderExtension2; +import dwtx.jface.text.source.IAnnotationHover; +import dwtx.jface.text.source.IAnnotationHoverExtension; +import dwtx.jface.text.source.IAnnotationModel; +import dwtx.jface.text.source.IAnnotationModelExtension; +import dwtx.jface.text.source.ILineRange; +import dwtx.jface.text.source.ISourceViewer; +import dwtx.jface.text.source.ISourceViewerExtension2; +import dwtx.jface.text.source.LineRange; + +/** + * Annotation hover for projection annotations. + * + * @since 3.0 + */ +class ProjectionAnnotationHover : IAnnotationHover, IAnnotationHoverExtension, IInformationProviderExtension2 { + + + private IInformationControlCreator fInformationControlCreator; + private IInformationControlCreator fInformationPresenterControlCreator; + + /** + * Sets the hover control creator for this projection annotation hover. + * + * @param creator the creator + */ + public void setHoverControlCreator(IInformationControlCreator creator) { + fInformationControlCreator= creator; + } + + /** + * Sets the information presenter control creator for this projection annotation hover. + * + * @param creator the creator + * @since 3.3 + */ + public void setInformationPresenterControlCreator(IInformationControlCreator creator) { + fInformationPresenterControlCreator= creator; + } + + /* + * @see dwtx.jface.text.source.IAnnotationHover#getHoverInfo(dwtx.jface.text.source.ISourceViewer, int) + */ + public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) { + // this is a no-op as semantics is defined by the implementation of the annotation hover extension + return null; + } + + /* + * @since 3.1 + */ + private bool isCaptionLine(ProjectionAnnotation annotation, Position position, IDocument document, int line) { + if (position.getOffset() > -1 && position.getLength() > -1) { + try { + int captionOffset; + if ( cast(IProjectionPosition)position ) + captionOffset= (cast(IProjectionPosition) position).computeCaptionOffset(document); + else + captionOffset= 0; + int startLine= document.getLineOfOffset(position.getOffset() + captionOffset); + return line is startLine; + } catch (BadLocationException x) { + } + } + return false; + } + + private String getProjectionTextAtLine(ISourceViewer viewer, int line, int numberOfLines) { + + IAnnotationModel model= null; + if ( cast(ISourceViewerExtension2)viewer ) { + ISourceViewerExtension2 viewerExtension= cast(ISourceViewerExtension2) viewer; + IAnnotationModel visual= viewerExtension.getVisualAnnotationModel(); + if ( cast(IAnnotationModelExtension)visual ) { + IAnnotationModelExtension modelExtension= cast(IAnnotationModelExtension) visual; + model= modelExtension.getAnnotationModel(ProjectionSupport.PROJECTION); + } + } + + if (model !is null) { + try { + IDocument document= viewer.getDocument(); + Iterator e= model.getAnnotationIterator(); + while (e.hasNext()) { + ProjectionAnnotation annotation= cast(ProjectionAnnotation) e.next(); + if (!annotation.isCollapsed()) + continue; + + Position position= model.getPosition(annotation); + if (position is null) + continue; + + if (isCaptionLine(annotation, position, document, line)) + return getText(document, position.getOffset(), position.getLength(), numberOfLines); + + } + } catch (BadLocationException x) { + } + } + + return null; + } + + private String getText(IDocument document, int offset, int length, int numberOfLines) { + int endOffset= offset + length; + + try { + int endLine= document.getLineOfOffset(offset) + Math.max(0, numberOfLines -1); + IRegion lineInfo= document.getLineInformation(endLine); + endOffset= Math.min(endOffset, lineInfo.getOffset() + lineInfo.getLength()); + } catch (BadLocationException x) { + } + + return document.get(offset, endOffset - offset); + } + + /* + * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverInfo(dwtx.jface.text.source.ISourceViewer, dwtx.jface.text.source.ILineRange, int) + */ + public Object getHoverInfo(ISourceViewer sourceViewer, ILineRange lineRange, int visibleLines) { + return stringcast(getProjectionTextAtLine(sourceViewer, lineRange.getStartLine(), visibleLines)); + } + + /* + * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverLineRange(dwtx.jface.text.source.ISourceViewer, int) + */ + public ILineRange getHoverLineRange(ISourceViewer viewer, int lineNumber) { + return new LineRange(lineNumber, 1); + } + + /* + * @see dwtx.jface.text.source.IAnnotationHoverExtension#canHandleMouseCursor() + */ + public bool canHandleMouseCursor() { + return false; + } + + /* + * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverControlCreator() + */ + public IInformationControlCreator getHoverControlCreator() { + if (fInformationControlCreator is null) { + fInformationControlCreator= new class() IInformationControlCreator { + public IInformationControl createInformationControl(Shell parent) { + return new SourceViewerInformationControl(parent, false, JFaceResources.TEXT_FONT, null); + } + }; + } + return fInformationControlCreator; + } + + /* + * @see dwtx.jface.text.information.IInformationProviderExtension2#getInformationPresenterControlCreator() + * @since 3.3 + */ + public IInformationControlCreator getInformationPresenterControlCreator() { + if (fInformationPresenterControlCreator is null) { + fInformationPresenterControlCreator= new class() IInformationControlCreator { + public IInformationControl createInformationControl(Shell parent) { + return new SourceViewerInformationControl(parent, true, JFaceResources.TEXT_FONT, null); + } + }; + } + return fInformationPresenterControlCreator; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/projection/ProjectionAnnotationModel.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/projection/ProjectionAnnotationModel.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,202 @@ +/******************************************************************************* + * 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 + * 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.text.source.projection.ProjectionAnnotationModel; + +import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport +import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport +import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport +import dwtx.jface.text.source.projection.AnnotationBag; // packageimport +import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport +import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport +import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport +import dwtx.jface.text.source.projection.IProjectionListener; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.Position; +import dwtx.jface.text.source.Annotation; +import dwtx.jface.text.source.AnnotationModel; + + +/** + * A projection annotation model. It provides methods for modifying the + * expansion state of the managed projection annotations. + *

                        + * Do not subclass. Use it as is. + *

                        + * + * @since 3.0 + * @noextend This class is not intended to be subclassed by clients. + */ +public class ProjectionAnnotationModel : AnnotationModel { + + + /** + * Creates a new, empty projection annotation model. + */ + public this() { + } + + /** + * Changes the state of the given annotation to collapsed. An appropriate + * annotation model change event is sent out. + * + * @param annotation the annotation + */ + public void collapse(Annotation annotation) { + if ( cast(ProjectionAnnotation)annotation ) { + ProjectionAnnotation projection= cast(ProjectionAnnotation) annotation; + if (!projection.isCollapsed()) { + projection.markCollapsed(); + modifyAnnotation(projection, true); + } + } + } + + /** + * Changes the state of the given annotation to expanded. An appropriate + * annotation model change event is sent out. + * + * @param annotation the annotation + */ + public void expand(Annotation annotation) { + if ( cast(ProjectionAnnotation)annotation ) { + ProjectionAnnotation projection= cast(ProjectionAnnotation) annotation; + if (projection.isCollapsed()) { + projection.markExpanded(); + modifyAnnotation(projection, true); + } + } + } + + /** + * Toggles the expansion state of the given annotation. An appropriate + * annotation model change event is sent out. + * + * @param annotation the annotation + */ + public void toggleExpansionState(Annotation annotation) { + if ( cast(ProjectionAnnotation)annotation ) { + ProjectionAnnotation projection= cast(ProjectionAnnotation) annotation; + + if (projection.isCollapsed()) + projection.markExpanded(); + else + projection.markCollapsed(); + + modifyAnnotation(projection, true); + } + } + + /** + * Expands all annotations that overlap with the given range and are collapsed. + * + * @param offset the range offset + * @param length the range length + * @return true if any annotation has been expanded, false otherwise + */ + public bool expandAll(int offset, int length) { + return expandAll(offset, length, true); + } + + /** + * Collapses all annotations that overlap with the given range and are collapsed. + * + * @param offset the range offset + * @param length the range length + * @return true if any annotation has been collapse, false + * otherwise + * @since 3.2 + */ + public bool collapseAll(int offset, int length) { + + bool collapsing= false; + + Iterator iterator= getAnnotationIterator(); + while (iterator.hasNext()) { + ProjectionAnnotation annotation= cast(ProjectionAnnotation) iterator.next(); + if (!annotation.isCollapsed()) { + Position position= getPosition(annotation); + if (position !is null && position.overlapsWith(offset, length) /* || is a delete at the boundary */ ) { + annotation.markCollapsed(); + modifyAnnotation(annotation, false); + collapsing= true; + } + } + } + + if (collapsing) + fireModelChanged(); + + return collapsing; + } + + /** + * Expands all annotations that overlap with the given range and are collapsed. Fires a model change event if + * requested. + * + * @param offset the offset of the range + * @param length the length of the range + * @param fireModelChanged true if a model change event + * should be fired, false otherwise + * @return true if any annotation has been expanded, false otherwise + */ + protected bool expandAll(int offset, int length, bool fireModelChanged_) { + + bool expanding= false; + + Iterator iterator= getAnnotationIterator(); + while (iterator.hasNext()) { + ProjectionAnnotation annotation= cast(ProjectionAnnotation) iterator.next(); + if (annotation.isCollapsed()) { + Position position= getPosition(annotation); + if (position !is null && position.overlapsWith(offset, length) /* || is a delete at the boundary */ ) { + annotation.markExpanded(); + modifyAnnotation(annotation, false); + expanding= true; + } + } + } + + if (expanding && fireModelChanged_) + fireModelChanged(); + + return expanding; + } + + /** + * Modifies the annotation model. + * + * @param deletions the list of deleted annotations + * @param additions the set of annotations to add together with their associated position + * @param modifications the list of modified annotations + */ + public void modifyAnnotations(Annotation[] deletions, Map additions, Annotation[] modifications) { + try { + replaceAnnotations(deletions, additions, false); + if (modifications !is null) { + for (int i= 0; i < modifications.length; i++) + modifyAnnotation(modifications[i], false); + } + } catch (BadLocationException x) { + } + fireModelChanged(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/projection/ProjectionRulerColumn.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/projection/ProjectionRulerColumn.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,249 @@ +/******************************************************************************* + * 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 + * 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.text.source.projection.ProjectionRulerColumn; + +import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport +import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport +import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport +import dwtx.jface.text.source.projection.AnnotationBag; // packageimport +import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport +import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport +import dwtx.jface.text.source.projection.IProjectionListener; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.dwtxhelper.Collection; + +import dwt.DWT; +import dwt.events.MouseEvent; +import dwt.events.MouseMoveListener; +import dwt.events.MouseTrackAdapter; +import dwt.graphics.Color; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.Position; +import dwtx.jface.text.source.AnnotationRulerColumn; +import dwtx.jface.text.source.CompositeRuler; +import dwtx.jface.text.source.IAnnotationAccess; +import dwtx.jface.text.source.IAnnotationModel; +import dwtx.jface.text.source.IAnnotationModelExtension; + + +/** + * A ruler column for controlling the behavior of a + * {@link dwtx.jface.text.source.projection.ProjectionViewer}. + * + * @since 3.0 + */ +class ProjectionRulerColumn : AnnotationRulerColumn { + + private ProjectionAnnotation fCurrentAnnotation; + + /** + * Creates a new projection ruler column. + * + * @param model the column's annotation model + * @param width the width in pixels + * @param annotationAccess the annotation access + */ + public this(IAnnotationModel model, int width, IAnnotationAccess annotationAccess) { + super(model, width, annotationAccess); + } + + /** + * Creates a new projection ruler column. + * + * @param width the width in pixels + * @param annotationAccess the annotation access + */ + public this(int width, IAnnotationAccess annotationAccess) { + super(width, annotationAccess); + } + + /* + * @see dwtx.jface.text.source.AnnotationRulerColumn#mouseClicked(int) + */ + protected void mouseClicked(int line) { + clearCurrentAnnotation(); + ProjectionAnnotation annotation= findAnnotation(line, true); + if (annotation !is null) { + ProjectionAnnotationModel model= cast(ProjectionAnnotationModel) getModel(); + model.toggleExpansionState(annotation); + } + } + + /** + * Returns the projection annotation of the column's annotation + * model that contains the given line. + * + * @param line the line + * @param exact true if the annotation range must match exactly + * @return the projection annotation containing the given line + */ + private ProjectionAnnotation findAnnotation(int line, bool exact) { + + ProjectionAnnotation previousAnnotation= null; + + IAnnotationModel model= getModel(); + if (model !is null) { + IDocument document= getCachedTextViewer().getDocument(); + + int previousDistance= Integer.MAX_VALUE; + + Iterator e= model.getAnnotationIterator(); + while (e.hasNext()) { + Object next= e.next(); + if ( cast(ProjectionAnnotation)next ) { + ProjectionAnnotation annotation= cast(ProjectionAnnotation) next; + Position p= model.getPosition(annotation); + if (p is null) + continue; + + int distance= getDistance(annotation, p, document, line); + if (distance is -1) + continue; + + if (!exact) { + if (distance < previousDistance) { + previousAnnotation= annotation; + previousDistance= distance; + } + } else if (distance is 0) { + previousAnnotation= annotation; + } + } + } + } + + return previousAnnotation; + } + + /** + * Returns the distance of the given line to the start line of the given position in the given document. The distance is + * -1 when the line is not included in the given position. + * + * @param annotation the annotation + * @param position the position + * @param document the document + * @param line the line + * @return -1 if line is not contained, a position number otherwise + */ + private int getDistance(ProjectionAnnotation annotation, Position position, IDocument document, int line) { + if (position.getOffset() > -1 && position.getLength() > -1) { + try { + int startLine= document.getLineOfOffset(position.getOffset()); + int endLine= document.getLineOfOffset(position.getOffset() + position.getLength()); + if (startLine <= line && line < endLine) { + if (annotation.isCollapsed()) { + int captionOffset; + if ( cast(IProjectionPosition)position ) + captionOffset= (cast(IProjectionPosition) position).computeCaptionOffset(document); + else + captionOffset= 0; + + int captionLine= document.getLineOfOffset(position.getOffset() + captionOffset); + if (startLine <= captionLine && captionLine < endLine) + return Math.abs(line - captionLine); + } + return line - startLine; + } + } catch (BadLocationException x) { + } + } + return -1; + } + + private bool clearCurrentAnnotation() { + if (fCurrentAnnotation !is null) { + fCurrentAnnotation.setRangeIndication(false); + fCurrentAnnotation= null; + return true; + } + return false; + } + + /* + * @see dwtx.jface.text.source.IVerticalRulerColumn#createControl(dwtx.jface.text.source.CompositeRuler, dwt.widgets.Composite) + */ + public Control createControl(CompositeRuler parentRuler, Composite parentControl) { + Control control= super.createControl(parentRuler, parentControl); + + // set background + Display display= parentControl.getDisplay(); + Color background= display.getSystemColor(DWT.COLOR_LIST_BACKGROUND); + control.setBackground(background); + + // install hover listener + control.addMouseTrackListener(new class() MouseTrackAdapter { + public void mouseExit(MouseEvent e) { + if (clearCurrentAnnotation()) + redraw(); + } + }); + + // install mouse move listener + control.addMouseMoveListener(new class() MouseMoveListener { + public void mouseMove(MouseEvent e) { + bool redraw_= false; + ProjectionAnnotation annotation= findAnnotation(toDocumentLineNumber(e.y), false); + if (annotation !is fCurrentAnnotation) { + if (fCurrentAnnotation !is null) { + fCurrentAnnotation.setRangeIndication(false); + redraw_= true; + } + fCurrentAnnotation= annotation; + if (fCurrentAnnotation !is null && !fCurrentAnnotation.isCollapsed()) { + fCurrentAnnotation.setRangeIndication(true); + redraw_= true; + } + } + if (redraw_) + redraw(); + } + }); + return control; + } + + /* + * @see dwtx.jface.text.source.AnnotationRulerColumn#setModel(dwtx.jface.text.source.IAnnotationModel) + */ + public void setModel(IAnnotationModel model) { + if ( cast(IAnnotationModelExtension)model ) { + IAnnotationModelExtension extension= cast(IAnnotationModelExtension) model; + model= extension.getAnnotationModel(ProjectionSupport.PROJECTION); + } + super.setModel(model); + } + + /* + * @see dwtx.jface.text.source.AnnotationRulerColumn#isPropagatingMouseListener() + */ + protected bool isPropagatingMouseListener() { + return false; + } + + /* + * @see dwtx.jface.text.source.AnnotationRulerColumn#hasAnnotation(int) + */ + protected bool hasAnnotation(int lineNumber) { + return findAnnotation(lineNumber, true) !is null; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/projection/ProjectionSummary.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/projection/ProjectionSummary.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,346 @@ +/******************************************************************************* + * 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 + * 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.text.source.projection.ProjectionSummary; + +import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport +import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport +import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport +import dwtx.jface.text.source.projection.AnnotationBag; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport +import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport +import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport +import dwtx.jface.text.source.projection.IProjectionListener; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport + + +import dwt.dwthelper.utils; +import tango.core.Thread; + +import dwtx.dwtxhelper.Collection; + + + + + +import dwtx.core.runtime.IProgressMonitor; +import dwtx.core.runtime.NullProgressMonitor; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ISynchronizable; +import dwtx.jface.text.Position; +import dwtx.jface.text.source.Annotation; +import dwtx.jface.text.source.IAnnotationAccess; +import dwtx.jface.text.source.IAnnotationAccessExtension; +import dwtx.jface.text.source.IAnnotationModel; +import dwtx.jface.text.source.IAnnotationModelExtension; + + +/** + * Strategy for managing annotation summaries for collapsed ranges. + * + * @since 3.0 + */ +class ProjectionSummary { + + private class Summarizer { + + Thread thread; + private bool fReset= true; + + /** + * Creates a new thread. + */ + public this() { + thread = new Thread( &run ); + fProgressMonitor= new NullProgressMonitor(); // might be given by client in the future + thread.isDaemon(true); + thread.start(); + } + + /** + * Resets the thread. + */ + public void reset() { + synchronized (fLock) { + fReset= true; + fProgressMonitor.setCanceled(true); + } + } + + /* + * @see java.lang.Thread#run() + */ + public void run() { + while (true) { + synchronized (fLock) { + if (!fReset) + break; + fReset= false; + fProgressMonitor.setCanceled(false); + } + internalUpdateSummaries(fProgressMonitor); + } + + synchronized (fLock) { + fSummarizer= null; + } + } + } + + + private ProjectionViewer fProjectionViewer; + private IAnnotationModel fAnnotationModel; + private IAnnotationAccess fAnnotationAccess; + private List fConfiguredAnnotationTypes; + + private Object fLock; + private IProgressMonitor fProgressMonitor; + private /+volatile+/ Summarizer fSummarizer; + + /** + * Creates a new projection summary. + * + * @param projectionViewer the projection viewer + * @param annotationAccess the annotation access + */ + public this(ProjectionViewer projectionViewer, IAnnotationAccess annotationAccess) { +// super(); + fLock= new Object(); + + fProjectionViewer= projectionViewer; + fAnnotationAccess= annotationAccess; + } + + /** + * Adds the given annotation type. For now on, annotations of that type are + * also reflected in their enclosing collapsed regions. + * + * @param annotationType the annotation type to add + */ + public void addAnnotationType(String annotationType) { + synchronized(fLock) { + if (fConfiguredAnnotationTypes is null) { + fConfiguredAnnotationTypes= new ArrayList(); + fConfiguredAnnotationTypes.add(annotationType); + } else if (!fConfiguredAnnotationTypes.contains(annotationType)) + fConfiguredAnnotationTypes.add(annotationType); + } + } + + /** + * Removes the given annotation. Annotation of that type are no + * longer reflected in their enclosing collapsed region. + * + * @param annotationType the annotation type to remove + */ + public void removeAnnotationType(String annotationType) { + synchronized (fLock) { + if (fConfiguredAnnotationTypes !is null) { + fConfiguredAnnotationTypes.remove(annotationType); + if (fConfiguredAnnotationTypes.size() is 0) + fConfiguredAnnotationTypes= null; + } + } + } + + /** + * Forces an updated of the annotation summary. + */ + public void updateSummaries() { + synchronized (fLock) { + if (fConfiguredAnnotationTypes !is null) { + if (fSummarizer is null) + fSummarizer= new Summarizer(); + fSummarizer.reset(); + } + } + } + + private void internalUpdateSummaries(IProgressMonitor monitor) { + + Object previousLockObject= null; + fAnnotationModel= fProjectionViewer.getVisualAnnotationModel(); + if (fAnnotationModel is null) + return; + + try { + + + IDocument document= fProjectionViewer.getDocument(); + if ( cast(ISynchronizable)document && cast(ISynchronizable)fAnnotationModel ) { + ISynchronizable sync= cast(ISynchronizable) fAnnotationModel; + previousLockObject= sync.getLockObject(); + sync.setLockObject((cast(ISynchronizable) document).getLockObject()); + } + + + removeSummaries(monitor); + + if (isCanceled(monitor)) + return; + + createSummaries(monitor); + + } finally { + + if ( cast(ISynchronizable)fAnnotationModel ) { + ISynchronizable sync= cast(ISynchronizable) fAnnotationModel; + sync.setLockObject(previousLockObject); + } + fAnnotationModel= null; + + } + } + + private bool isCanceled(IProgressMonitor monitor) { + return monitor !is null && monitor.isCanceled(); + } + + private void removeSummaries(IProgressMonitor monitor) { + IAnnotationModelExtension extension= null; + List bags= null; + + if ( cast(IAnnotationModelExtension)fAnnotationModel ) { + extension= cast(IAnnotationModelExtension) fAnnotationModel; + bags= new ArrayList(); + } + + Iterator e= fAnnotationModel.getAnnotationIterator(); + while (e.hasNext()) { + Annotation annotation= cast(Annotation) e.next(); + if ( cast(AnnotationBag)annotation ) { + if (bags is null) + fAnnotationModel.removeAnnotation(annotation); + else + bags.add(annotation); + } + + if (isCanceled(monitor)) + return; + } + + if (bags !is null && bags.size() > 0) { + Annotation[] deletions= new Annotation[bags.size()]; + bags.toArray(deletions); + if (!isCanceled(monitor)) + extension.replaceAnnotations(deletions, null); + } + } + + private void createSummaries(IProgressMonitor monitor) { + ProjectionAnnotationModel model= fProjectionViewer.getProjectionAnnotationModel(); + if (model is null) + return; + + Map additions= new HashMap(); + + Iterator e= model.getAnnotationIterator(); + while (e.hasNext()) { + ProjectionAnnotation projection= cast(ProjectionAnnotation) e.next(); + if (projection.isCollapsed()) { + Position position= model.getPosition(projection); + if (position !is null) { + IRegion[] summaryRegions= fProjectionViewer.computeCollapsedRegions(position); + if (summaryRegions !is null) { + Position summaryAnchor= fProjectionViewer.computeCollapsedRegionAnchor(position); + if (summaryAnchor !is null) + createSummary(additions, summaryRegions, summaryAnchor); + } + } + } + + if (isCanceled(monitor)) + return; + } + + if (additions.size() > 0) { + if ( cast(IAnnotationModelExtension)fAnnotationModel ) { + IAnnotationModelExtension extension= cast(IAnnotationModelExtension) fAnnotationModel; + if (!isCanceled(monitor)) + extension.replaceAnnotations(null, additions); + } else { + Iterator e1= additions.keySet().iterator(); + while (e1.hasNext()) { + AnnotationBag bag= cast(AnnotationBag) e1.next(); + Position position= cast(Position) additions.get(bag); + if (isCanceled(monitor)) + return; + fAnnotationModel.addAnnotation(bag, position); + } + } + } + } + + private void createSummary(Map additions, IRegion[] summaryRegions, Position summaryAnchor) { + + int size= 0; + Map map= null; + + synchronized (fLock) { + if (fConfiguredAnnotationTypes !is null) { + size= fConfiguredAnnotationTypes.size(); + map= new HashMap(); + for (int i= 0; i < size; i++) { + String type= stringcast( fConfiguredAnnotationTypes.get(i)); + map.put(type, new AnnotationBag(type)); + } + } + } + + if (map is null) + return; + + IAnnotationModel model= fProjectionViewer.getAnnotationModel(); + if (model is null) + return; + Iterator e= model.getAnnotationIterator(); + while (e.hasNext()) { + Annotation annotation= cast(Annotation) e.next(); + AnnotationBag bag= findBagForType(map, annotation.getType()); + if (bag !is null) { + Position position= model.getPosition(annotation); + if (includes(summaryRegions, position)) + bag.add(annotation); + } + } + + for (int i= 0; i < size; i++) { + AnnotationBag bag= cast(AnnotationBag) map.get(fConfiguredAnnotationTypes.get(i)); + if (!bag.isEmpty()) + additions.put(bag, new Position(summaryAnchor.getOffset(), summaryAnchor.getLength())); + } + } + + private AnnotationBag findBagForType(Map bagMap, String annotationType) { + AnnotationBag bag= cast(AnnotationBag) bagMap.get(annotationType); + if (bag is null && cast(IAnnotationAccessExtension)fAnnotationAccess ) { + IAnnotationAccessExtension extension= cast(IAnnotationAccessExtension) fAnnotationAccess; + Object[] superTypes= extension.getSupertypes(stringcast(annotationType)); + for (int i= 0; i < superTypes.length && bag is null; i++) { + bag= cast(AnnotationBag) bagMap.get(superTypes[i]); + } + } + return bag; + } + + private bool includes(IRegion[] regions, Position position) { + for (int i= 0; i < regions.length; i++) { + IRegion region= regions[i]; + if (position !is null && !position.isDeleted() + && region.getOffset() <= position.getOffset() && position.getOffset() + position.getLength() <= region.getOffset() + region.getLength()) + return true; + } + return false; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/projection/ProjectionSupport.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/projection/ProjectionSupport.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,399 @@ +/******************************************************************************* + * 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 + * 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.text.source.projection.ProjectionSupport; + +import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport +import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport +import dwtx.jface.text.source.projection.AnnotationBag; // packageimport +import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport +import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport +import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport +import dwtx.jface.text.source.projection.IProjectionListener; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + +import dwt.DWT; +import dwt.custom.StyledText; +import dwt.custom.StyledTextContent; +import dwt.graphics.Color; +import dwt.graphics.FontMetrics; +import dwt.graphics.GC; +import dwt.graphics.Point; +import dwt.graphics.RGB; +import dwt.widgets.Display; +import dwtx.jface.text.IInformationControlCreator; +import dwtx.jface.text.source.Annotation; +import dwtx.jface.text.source.AnnotationPainter; +import dwtx.jface.text.source.IAnnotationAccess; +import dwtx.jface.text.source.IAnnotationHover; +import dwtx.jface.text.source.IAnnotationModel; +import dwtx.jface.text.source.ISharedTextColors; +import dwtx.jface.text.source.ISourceViewer; + +/** + * Supports the configuration of projection capabilities a {@link dwtx.jface.text.source.projection.ProjectionViewer}. + *

                        + * This class is not intended to be subclassed. Clients are supposed to configure and use it as is.

                        + * + * @since 3.0 + * @noextend This class is not intended to be subclassed by clients. + */ +public class ProjectionSupport { + + /** + * Key of the projection annotation model inside the visual annotation + * model. Also internally used as key for the projection drawing strategy. + */ + private static Object PROJECTION_; + public static Object PROJECTION(){ + if( PROJECTION_ is null ){ + synchronized(ProjectionSupport.classinfo){ + if( PROJECTION_ is null ){ + PROJECTION_ = new Object(); + } + } + } + return PROJECTION_; + } + + private static class ProjectionAnnotationsPainter : AnnotationPainter { + + /** + * Creates a new painter indicating the location of collapsed regions. + * + * @param sourceViewer the source viewer for the painter + * @param access the annotation access + */ + public this(ISourceViewer sourceViewer, IAnnotationAccess access) { + super(sourceViewer, access); + } + + /* + * @see dwtx.jface.text.source.AnnotationPainter#findAnnotationModel(dwtx.jface.text.source.ISourceViewer) + */ + protected IAnnotationModel findAnnotationModel(ISourceViewer sourceViewer) { + if ( cast(ProjectionViewer)sourceViewer ) { + ProjectionViewer projectionViewer= cast(ProjectionViewer) sourceViewer; + return projectionViewer.getProjectionAnnotationModel(); + } + return null; + } + + /* + * @see dwtx.jface.text.source.AnnotationPainter#skip(dwtx.jface.text.source.Annotation) + */ + protected bool skip(Annotation annotation) { + if ( cast(ProjectionAnnotation)annotation ) + return !(cast(ProjectionAnnotation) annotation).isCollapsed(); + + return super.skip(annotation); + } + } + + private static class ProjectionDrawingStrategy : AnnotationPainter_IDrawingStrategy { + /* + * @see dwtx.jface.text.source.AnnotationPainter.IDrawingStrategy#draw(dwt.graphics.GC, dwt.custom.StyledText, int, int, dwt.graphics.Color) + */ + public void draw(Annotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) { + if ( cast(ProjectionAnnotation)annotation ) { + ProjectionAnnotation projectionAnnotation= cast(ProjectionAnnotation) annotation; + if (projectionAnnotation.isCollapsed()) { + + if (gc !is null) { + + StyledTextContent content= textWidget.getContent(); + int line= content.getLineAtOffset(offset); + int lineStart= content.getOffsetAtLine(line); + String text= content.getLine(line); + int lineLength= text is null ? 0 : text.length; + int lineEnd= lineStart + lineLength; + Point p= textWidget.getLocationAtOffset(lineEnd); + + Color c= gc.getForeground(); + gc.setForeground(color); + + FontMetrics metrics= gc.getFontMetrics(); + + // baseline: where the dots are drawn + int baseline= textWidget.getBaseline(offset); + // descent: number of pixels that the box extends over baseline + int descent= Math.min(2, textWidget.getLineHeight(offset) - baseline); + // ascent: so much does the box stand up from baseline + int ascent= metrics.getAscent(); + // leading: free space from line top to box upper line + int leading= baseline - ascent; + // height: height of the box + int height= ascent + descent; + + int width= metrics.getAverageCharWidth(); + gc.drawRectangle(p.x, p.y + leading, width, height); + int third= width/3; + int dotsVertical= p.y + baseline - 1; + gc.drawPoint(p.x + third, dotsVertical); + gc.drawPoint(p.x + width - third, dotsVertical); + + gc.setForeground(c); + + } else { + textWidget.redrawRange(offset, length, true); + } + } + } + } + } + + private class ProjectionListener : IProjectionListener { + + /* + * @see dwtx.jface.text.source.projection.IProjectionListener#projectionEnabled() + */ + public void projectionEnabled() { + doEnableProjection(); + } + + /* + * @see dwtx.jface.text.source.projection.IProjectionListener#projectionDisabled() + */ + public void projectionDisabled() { + doDisableProjection(); + } + } + + private ProjectionViewer fViewer; + private IAnnotationAccess fAnnotationAccess; + private ISharedTextColors fSharedTextColors; + private List fSummarizableTypes; + private IInformationControlCreator fInformationControlCreator; + private IInformationControlCreator fInformationPresenterControlCreator; + private ProjectionListener fProjectionListener; + private ProjectionAnnotationsPainter fPainter; + private ProjectionRulerColumn fColumn; + /** + * @since 3.1 + */ + private AnnotationPainter_IDrawingStrategy fDrawingStrategy; + + /** + * Creates new projection support for the given projection viewer. Initially, + * no annotation types are summarized. A default hover control creator and a + * default drawing strategy are used. + * + * @param viewer the projection viewer + * @param annotationAccess the annotation access + * @param sharedTextColors the shared text colors to use + */ + public this(ProjectionViewer viewer, IAnnotationAccess annotationAccess, ISharedTextColors sharedTextColors) { + fViewer= viewer; + fAnnotationAccess= annotationAccess; + fSharedTextColors= sharedTextColors; + } + + /** + * Marks the given annotation type to be considered when creating summaries for + * collapsed regions of the projection viewer. + *

                        + * A summary is an annotation that gets created out of all annotations with a + * type that has been registered through this method and that are inside the + * folded region. + *

                        + * + * @param annotationType the annotation type to consider + */ + public void addSummarizableAnnotationType(String annotationType) { + if (fSummarizableTypes is null) { + fSummarizableTypes= new ArrayList(); + fSummarizableTypes.add(annotationType); + } else if (!fSummarizableTypes.contains(annotationType)) + fSummarizableTypes.add(annotationType); + } + + /** + * Marks the given annotation type to be ignored when creating summaries for + * collapsed regions of the projection viewer. This method has only an effect + * when addSummarizableAnnotationType has been called before for + * the give annotation type. + *

                        + * A summary is an annotation that gets created out of all annotations with a + * type that has been registered through this method and that are inside the + * folded region. + *

                        + * + * @param annotationType the annotation type to remove + */ + public void removeSummarizableAnnotationType(String annotationType) { + if (fSummarizableTypes !is null) + fSummarizableTypes.remove(annotationType); + if (fSummarizableTypes.size() is 0) + fSummarizableTypes= null; + } + + /** + * Sets the hover control creator that is used for the annotation hovers + * that are shown in the projection viewer's projection ruler column. + * + * @param creator the hover control creator + */ + public void setHoverControlCreator(IInformationControlCreator creator) { + fInformationControlCreator= creator; + } + + /** + * Sets the information presenter control creator that is used for the annotation + * hovers that are shown in the projection viewer's projection ruler column. + * + * @param creator the information presenter control creator + * @since 3.3 + */ + public void setInformationPresenterControlCreator(IInformationControlCreator creator) { + fInformationPresenterControlCreator= creator; + } + + /** + * Sets the drawing strategy that the projection support's annotation + * painter uses to draw the indication of collapsed regions onto the + * projection viewer's text widget. When null is passed in, + * the drawing strategy is reset to the default. In order to avoid any + * representation use {@link dwtx.jface.text.source.AnnotationPainter.NullStrategy}. + * + * @param strategy the drawing strategy or null to reset the + * strategy to the default + * @since 3.1 + */ + public void setAnnotationPainterDrawingStrategy(AnnotationPainter_IDrawingStrategy strategy) { + fDrawingStrategy= strategy; + } + + /** + * Returns the drawing strategy to be used by the support's annotation painter. + * + * @return the drawing strategy to be used by the support's annotation painter + * @since 3.1 + */ + private AnnotationPainter_IDrawingStrategy getDrawingStrategy() { + if (fDrawingStrategy is null) + fDrawingStrategy= new ProjectionDrawingStrategy(); + return fDrawingStrategy; + } + + /** + * Installs this projection support on its viewer. + */ + public void install() { + fViewer.setProjectionSummary(createProjectionSummary()); + + fProjectionListener= new ProjectionListener(); + fViewer.addProjectionListener(fProjectionListener); + } + + /** + * Disposes this projection support. + */ + public void dispose() { + if (fProjectionListener !is null) { + fViewer.removeProjectionListener(fProjectionListener); + fProjectionListener= null; + } + } + + /** + * Enables projection mode. If not yet done, installs the projection ruler + * column in the viewer's vertical ruler and installs a painter that + * indicate the locations of collapsed regions. + * + */ + protected void doEnableProjection() { + + if (fPainter is null) { + fPainter= new ProjectionAnnotationsPainter(fViewer, fAnnotationAccess); + fPainter.addDrawingStrategy(PROJECTION, getDrawingStrategy()); + fPainter.addAnnotationType(stringcast(ProjectionAnnotation.TYPE), PROJECTION); + fPainter.setAnnotationTypeColor(stringcast(ProjectionAnnotation.TYPE), fSharedTextColors.getColor(getColor())); + fViewer.addPainter(fPainter); + } + + if (fColumn is null) { + fColumn= new ProjectionRulerColumn(9, fAnnotationAccess); + fColumn.addAnnotationType(stringcast(ProjectionAnnotation.TYPE)); + fColumn.setHover(createProjectionAnnotationHover()); + fViewer.addVerticalRulerColumn(fColumn); + } + + fColumn.setModel(fViewer.getVisualAnnotationModel()); + } + + /** + * Removes the projection ruler column and the painter from the projection + * viewer. + */ + protected void doDisableProjection() { + if (fPainter !is null) { + fViewer.removePainter(fPainter); + fPainter.dispose(); + fPainter= null; + } + + if (fColumn !is null) { + fViewer.removeVerticalRulerColumn(fColumn); + fColumn= null; + } + } + + private ProjectionSummary createProjectionSummary() { + ProjectionSummary summary= new ProjectionSummary(fViewer, fAnnotationAccess); + if (fSummarizableTypes !is null) { + int size= fSummarizableTypes.size(); + for (int i= 0; i < size; i++) + summary.addAnnotationType(stringcast(fSummarizableTypes.get(i))); + } + return summary; + } + + private IAnnotationHover createProjectionAnnotationHover() { + ProjectionAnnotationHover hover= new ProjectionAnnotationHover(); + hover.setHoverControlCreator(fInformationControlCreator); + hover.setInformationPresenterControlCreator(fInformationPresenterControlCreator); + return hover; + } + + /** + * Implements the contract of {@link dwtx.core.runtime.IAdaptable#getAdapter(java.lang.Class)} + * by forwarding the adapter requests to the given viewer. + * + * @param viewer the viewer + * @param required the required class of the adapter + * @return the adapter or null + * + */ + public Object getAdapter(ISourceViewer viewer, ClassInfo required) { + if (ProjectionAnnotationModel.classinfo ==/*eq*/ required) { + if ( cast(ProjectionViewer)viewer ) { + ProjectionViewer projectionViewer= cast(ProjectionViewer) viewer; + return projectionViewer.getProjectionAnnotationModel(); + } + } + return null; + } + + private RGB getColor() { + // TODO read out preference settings + Color c= Display.getDefault().getSystemColor(DWT.COLOR_DARK_GRAY); + return c.getRGB(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/projection/ProjectionViewer.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/projection/ProjectionViewer.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,1836 @@ +/******************************************************************************* + * 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 + * 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.text.source.projection.ProjectionViewer; + +import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport +import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport +import dwtx.jface.text.source.projection.AnnotationBag; // packageimport +import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport +import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport +import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport +import dwtx.jface.text.source.projection.IProjectionListener; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport + + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; +import tango.core.Exception; + + + +import dwt.DWTError; +import dwt.custom.ST; +import dwt.custom.StyledText; +import dwt.dnd.Clipboard; +import dwt.dnd.DND; +import dwt.dnd.TextTransfer; +import dwt.dnd.Transfer; +import dwt.events.VerifyEvent; +import dwt.graphics.Point; +import dwt.widgets.Composite; +import dwt.widgets.Display; +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.FindReplaceDocumentAdapter; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentInformationMappingExtension; +import dwtx.jface.text.IDocumentListener; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ISlaveDocumentManager; +import dwtx.jface.text.ITextViewerExtension5; +import dwtx.jface.text.Position; +import dwtx.jface.text.Region; +import dwtx.jface.text.TextUtilities; +import dwtx.jface.text.projection.ProjectionDocument; +import dwtx.jface.text.projection.ProjectionDocumentEvent; +import dwtx.jface.text.projection.ProjectionDocumentManager; +import dwtx.jface.text.source.Annotation; +import dwtx.jface.text.source.AnnotationModelEvent; +import dwtx.jface.text.source.CompositeRuler; +import dwtx.jface.text.source.IAnnotationModel; +import dwtx.jface.text.source.IAnnotationModelExtension; +import dwtx.jface.text.source.IAnnotationModelListener; +import dwtx.jface.text.source.IAnnotationModelListenerExtension; +import dwtx.jface.text.source.IOverviewRuler; +import dwtx.jface.text.source.IVerticalRuler; +import dwtx.jface.text.source.IVerticalRulerColumn; +import dwtx.jface.text.source.SourceViewer; + + +/** + * A projection source viewer is a source viewer which supports multiple visible + * regions which can dynamically be changed. + *

                        + * A projection source viewer uses a ProjectionDocumentManager + * for the management of the visible document.

                        + *

                        + * NOTE: The ProjectionViewer only supports projections that cover full lines. + *

                        + *

                        + * This class should not be subclassed.

                        + * + * @since 3.0 + * @noextend This class is not intended to be subclassed by clients. + */ +public class ProjectionViewer : SourceViewer , ITextViewerExtension5 { + + public override IRegion getModelCoverage() { + return super.getModelCoverage(); + } + public override int modelLine2WidgetLine(int modelLine) { + return super.modelLine2WidgetLine(modelLine); + } + public override int modelOffset2WidgetOffset(int modelOffset) { + return super.modelOffset2WidgetOffset(modelOffset); + } + public override IRegion modelRange2WidgetRange(IRegion modelRange) { + return super.modelRange2WidgetRange(modelRange); + } + protected override IRegion modelRange2WidgetRange(Position modelPosition) { + return super.modelRange2WidgetRange(modelPosition); + } + public override int widgetOffset2ModelOffset(int widgetOffset) { + return super.widgetOffset2ModelOffset(widgetOffset); + } + public override IRegion widgetRange2ModelRange(IRegion widgetRange) { + return super.widgetRange2ModelRange(widgetRange); + } + public int widgetLine2ModelLine(int widgetLine) { + return super.widgetLine2ModelLine(widgetLine); + } + public int widgetLineOfWidgetOffset(int widgetOffset) { + return super.widgetLineOfWidgetOffset(widgetOffset); + } + + private static const int BASE= INFORMATION; // see ISourceViewer.INFORMATION + + /** Operation constant for the expand operation. */ + public static const int EXPAND= BASE + 1; + /** Operation constant for the collapse operation. */ + public static const int COLLAPSE= BASE + 2; + /** Operation constant for the toggle projection operation. */ + public static const int TOGGLE= BASE + 3; + /** Operation constant for the expand all operation. */ + public static const int EXPAND_ALL= BASE + 4; + /** + * Operation constant for the collapse all operation. + * + * @since 3.2 + */ + public static const int COLLAPSE_ALL= BASE + 5; + + /** + * Internal listener to changes of the annotation model. + */ + private class AnnotationModelListener : IAnnotationModelListener, IAnnotationModelListenerExtension { + + /* + * @see dwtx.jface.text.source.IAnnotationModelListener#modelChanged(dwtx.jface.text.source.IAnnotationModel) + */ + public void modelChanged(IAnnotationModel model) { + processModelChanged(model, null); + } + + /* + * @see dwtx.jface.text.source.IAnnotationModelListenerExtension#modelChanged(dwtx.jface.text.source.AnnotationModelEvent) + */ + public void modelChanged(AnnotationModelEvent event) { + processModelChanged(event.getAnnotationModel(), event); + } + + private void processModelChanged(IAnnotationModel model, AnnotationModelEvent event) { + if (model is fProjectionAnnotationModel) { + + if (fProjectionSummary !is null) + fProjectionSummary.updateSummaries(); + processCatchupRequest(event); + + } else if (model is getAnnotationModel() && fProjectionSummary !is null) + fProjectionSummary.updateSummaries(); + } + } + + /** + * Executes the 'replaceVisibleDocument' operation when called the first time. Self-destructs afterwards. + */ + private class ReplaceVisibleDocumentExecutor : IDocumentListener { + + private IDocument fSlaveDocument; + private IDocument fExecutionTrigger; + + /** + * Creates a new executor in order to free the given slave document. + * + * @param slaveDocument the slave document to free + */ + public this(IDocument slaveDocument) { + fSlaveDocument= slaveDocument; + } + + /** + * Installs this executor on the given trigger document. + * + * @param executionTrigger the trigger document + */ + public void install(IDocument executionTrigger) { + if (executionTrigger !is null && fSlaveDocument !is null) { + fExecutionTrigger= executionTrigger; + fExecutionTrigger.addDocumentListener(this); + } + } + + /* + * @see dwtx.jface.text.IDocumentListener#documentAboutToBeChanged(dwtx.jface.text.DocumentEvent) + */ + public void documentAboutToBeChanged(DocumentEvent event) { + } + + /* + * @see dwtx.jface.text.IDocumentListener#documentChanged(dwtx.jface.text.DocumentEvent) + */ + public void documentChanged(DocumentEvent event) { + fExecutionTrigger.removeDocumentListener(this); + executeReplaceVisibleDocument(fSlaveDocument); + } + } + + /** + * A command representing a change of the projection document. This can be either + * adding a master document range, removing a master document change, or invalidating + * the viewer text presentation. + */ + private static class ProjectionCommand { + + const static int ADD= 0; + const static int REMOVE= 1; + const static int INVALIDATE_PRESENTATION= 2; + + ProjectionDocument fProjection; + int fType; + int fOffset; + int fLength; + + this(ProjectionDocument projection, int type, int offset, int length) { + fProjection= projection; + fType= type; + fOffset= offset; + fLength= length; + } + + this(int offset, int length) { + fType= INVALIDATE_PRESENTATION; + fOffset= offset; + fLength= length; + } + + int computeExpectedCosts() { + + switch(fType) { + case ADD: { + try { + IRegion[] gaps= fProjection.computeUnprojectedMasterRegions(fOffset, fLength); + return gaps is null ? 0 : gaps.length; + } catch (BadLocationException x) { + } + break; + } + case REMOVE: { + try { + IRegion[] fragments= fProjection.computeProjectedMasterRegions(fOffset, fLength); + return fragments is null ? 0 : fragments.length; + } catch (BadLocationException x) { + } + break; + } + } + return 0; + } + } + + /** + * The queue of projection command objects. + */ + private static class ProjectionCommandQueue { + + final static int REDRAW_COSTS= 15; + final static int INVALIDATION_COSTS= 10; + + List fList; + int fExpectedExecutionCosts= -1; + + this(){ + fList= new ArrayList(15); + } + + void add(ProjectionCommand command) { + fList.add(command); + } + + Iterator iterator() { + return fList.iterator(); + } + + void clear() { + fList.clear(); + fExpectedExecutionCosts= -1; + } + + bool passedRedrawCostsThreshold() { + if (fExpectedExecutionCosts is -1) + computeExpectedExecutionCosts(); + return fExpectedExecutionCosts > REDRAW_COSTS; + } + + bool passedInvalidationCostsThreshold() { + if (fExpectedExecutionCosts is -1) + computeExpectedExecutionCosts(); + return fExpectedExecutionCosts > INVALIDATION_COSTS; + } + + private void computeExpectedExecutionCosts() { + int max_costs= Math.max(REDRAW_COSTS, INVALIDATION_COSTS); + fExpectedExecutionCosts= fList.size(); + if (fExpectedExecutionCosts <= max_costs) { + ProjectionCommand command; + Iterator e= fList.iterator(); + while (e.hasNext()) { + command= cast(ProjectionCommand) e.next(); + fExpectedExecutionCosts += command.computeExpectedCosts(); + if (fExpectedExecutionCosts > max_costs) + break; + } + } + } + } + + /** The projection annotation model used by this viewer. */ + private ProjectionAnnotationModel fProjectionAnnotationModel; + /** The annotation model listener */ + private IAnnotationModelListener fAnnotationModelListener; + /** The projection summary. */ + private ProjectionSummary fProjectionSummary; + /** Indication that an annotation world change has not yet been processed. */ + private bool fPendingAnnotationWorldChange= false; + /** Indication whether projection changes in the visible document should be considered. */ + private bool fHandleProjectionChanges= true; + /** The list of projection listeners. */ + private List fProjectionListeners; + /** Internal lock for protecting the list of pending requests */ + private Object fLock; + /** The list of pending requests */ + private List fPendingRequests; + /** The replace-visible-document execution trigger */ + private IDocument fReplaceVisibleDocumentExecutionTrigger; + /** true if projection was on the last time we switched to segmented mode. */ + private bool fWasProjectionEnabled; + /** The queue of projection commands used to assess the costs of projection changes. */ + private ProjectionCommandQueue fCommandQueue; + /** + * The amount of lines deleted by the last document event issued by the + * visible document event. + * @since 3.1 + */ + private int fDeletedLines; + + + /** + * Creates a new projection source viewer. + * + * @param parent the DWT parent control + * @param ruler the vertical ruler + * @param overviewRuler the overview ruler + * @param showsAnnotationOverview true if the overview ruler should be shown + * @param styles the DWT style bits + */ + public this(Composite parent, IVerticalRuler ruler, IOverviewRuler overviewRuler, bool showsAnnotationOverview, int styles) { + + fAnnotationModelListener= new AnnotationModelListener(); + fLock= new Object(); + fPendingRequests= new ArrayList(); + + super(parent, ruler, overviewRuler, showsAnnotationOverview, styles); + } + + /** + * Sets the projection summary for this viewer. + * + * @param projectionSummary the projection summary. + */ + public void setProjectionSummary(ProjectionSummary projectionSummary) { + fProjectionSummary= projectionSummary; + } + + /** + * Adds the projection annotation model to the given annotation model. + * + * @param model the model to which the projection annotation model is added + */ + private void addProjectionAnnotationModel(IAnnotationModel model) { + if ( cast(IAnnotationModelExtension)model ) { + IAnnotationModelExtension extension= cast(IAnnotationModelExtension) model; + extension.addAnnotationModel(ProjectionSupport.PROJECTION, fProjectionAnnotationModel); + model.addAnnotationModelListener(fAnnotationModelListener); + } + } + + /** + * Removes the projection annotation model from the given annotation model. + * + * @param model the mode from which the projection annotation model is removed + * @return the removed projection annotation model or null if there was none + */ + private IAnnotationModel removeProjectionAnnotationModel(IAnnotationModel model) { + if ( cast(IAnnotationModelExtension)model ) { + model.removeAnnotationModelListener(fAnnotationModelListener); + IAnnotationModelExtension extension= cast(IAnnotationModelExtension) model; + return extension.removeAnnotationModel(ProjectionSupport.PROJECTION); + } + return null; + } + + /* + * @see dwtx.jface.text.source.SourceViewer#setDocument(dwtx.jface.text.IDocument, dwtx.jface.text.source.IAnnotationModel, int, int) + */ + public void setDocument(IDocument document, IAnnotationModel annotationModel, int modelRangeOffset, int modelRangeLength) { + bool wasProjectionEnabled= false; + + synchronized (fLock) { + fPendingRequests.clear(); + } + + if (fProjectionAnnotationModel !is null) { + wasProjectionEnabled= removeProjectionAnnotationModel(getVisualAnnotationModel()) !is null; + fProjectionAnnotationModel= null; + } + + super.setDocument(document, annotationModel, modelRangeOffset, modelRangeLength); + + if (wasProjectionEnabled && document !is null) + enableProjection(); + } + + /* + * @see dwtx.jface.text.source.SourceViewer#createVisualAnnotationModel(dwtx.jface.text.source.IAnnotationModel) + */ + protected IAnnotationModel createVisualAnnotationModel(IAnnotationModel annotationModel) { + IAnnotationModel model= super.createVisualAnnotationModel(annotationModel); + fProjectionAnnotationModel= new ProjectionAnnotationModel(); + return model; + } + + /** + * Returns the projection annotation model. + * + * @return the projection annotation model + */ + public ProjectionAnnotationModel getProjectionAnnotationModel() { + IAnnotationModel model= getVisualAnnotationModel(); + if ( cast(IAnnotationModelExtension)model ) { + IAnnotationModelExtension extension= cast(IAnnotationModelExtension) model; + return cast(ProjectionAnnotationModel) extension.getAnnotationModel(ProjectionSupport.PROJECTION); + } + return null; + } + + /* + * @see dwtx.jface.text.TextViewer#createSlaveDocumentManager() + */ + protected ISlaveDocumentManager createSlaveDocumentManager() { + return new ProjectionDocumentManager(); + } + + /* + * @see dwtx.jface.text.TextViewer#updateSlaveDocument(dwtx.jface.text.IDocument, int, int) + */ + protected bool updateSlaveDocument(IDocument slaveDocument, int modelRangeOffset, int modelRangeLength) { + if ( cast(ProjectionDocument)slaveDocument ) { + ProjectionDocument projection= cast(ProjectionDocument) slaveDocument; + + int offset= modelRangeOffset; + int length= modelRangeLength; + + if (!isProjectionMode()) { + // mimic original TextViewer behavior + IDocument master= projection.getMasterDocument(); + int line= master.getLineOfOffset(modelRangeOffset); + offset= master.getLineOffset(line); + length= (modelRangeOffset - offset) + modelRangeLength; + + } + + try { + fHandleProjectionChanges= false; + projection.replaceMasterDocumentRanges(offset, length); + } finally { + fHandleProjectionChanges= true; + } + return true; + } + return false; + } + + /** + * Adds a projection annotation listener to this viewer. The listener may + * not be null. If the listener is already registered, this method + * does not have any effect. + * + * @param listener the listener to add + */ + public void addProjectionListener(IProjectionListener listener) { + + Assert.isNotNull(cast(Object)listener); + + if (fProjectionListeners is null) + fProjectionListeners= new ArrayList(); + + if (!fProjectionListeners.contains(cast(Object)listener)) + fProjectionListeners.add(cast(Object)listener); + } + + /** + * Removes the given listener from this viewer. The listener may not be + * null. If the listener is not registered with this viewer, + * this method is without effect. + * + * @param listener the listener to remove + */ + public void removeProjectionListener(IProjectionListener listener) { + + Assert.isNotNull(cast(Object)listener); + + if (fProjectionListeners !is null) { + fProjectionListeners.remove(cast(Object)listener); + if (fProjectionListeners.size() is 0) + fProjectionListeners= null; + } + } + + /** + * Notifies all registered projection listeners + * that projection mode has been enabled. + */ + protected void fireProjectionEnabled() { + if (fProjectionListeners !is null) { + Iterator e= (new ArrayList(fProjectionListeners)).iterator(); + while (e.hasNext()) { + IProjectionListener l= cast(IProjectionListener) e.next(); + l.projectionEnabled(); + } + } + } + + /** + * Notifies all registered projection listeners + * that projection mode has been disabled. + */ + protected void fireProjectionDisabled() { + if (fProjectionListeners !is null) { + Iterator e= (new ArrayList(fProjectionListeners)).iterator(); + while (e.hasNext()) { + IProjectionListener l= cast(IProjectionListener) e.next(); + l.projectionDisabled(); + } + } + } + + /** + * Returns whether this viewer is in projection mode. + * + * @return true if this viewer is in projection mode, + * false otherwise + */ + public final bool isProjectionMode() { + return getProjectionAnnotationModel() !is null; + } + + /** + * Disables the projection mode. + */ + public final void disableProjection() { + if (isProjectionMode()) { + removeProjectionAnnotationModel(getVisualAnnotationModel()); + fProjectionAnnotationModel.removeAllAnnotations(); + fFindReplaceDocumentAdapter= null; + fireProjectionDisabled(); + } + } + + /** + * Enables the projection mode. + */ + public final void enableProjection() { + if (!isProjectionMode()) { + addProjectionAnnotationModel(getVisualAnnotationModel()); + fFindReplaceDocumentAdapter= null; + fireProjectionEnabled(); + } + } + + private void expandAll() { + int offset= 0; + IDocument doc= getDocument(); + int length= doc is null ? 0 : doc.getLength(); + if (isProjectionMode()) { + fProjectionAnnotationModel.expandAll(offset, length); + } + } + + private void expand() { + if (isProjectionMode()) { + Position found= null; + Annotation bestMatch= null; + Point selection= getSelectedRange(); + for (Iterator e= fProjectionAnnotationModel.getAnnotationIterator(); e.hasNext();) { + ProjectionAnnotation annotation= cast(ProjectionAnnotation) e.next(); + if (annotation.isCollapsed()) { + Position position= fProjectionAnnotationModel.getPosition(annotation); + // take the first most fine grained match + if (position !is null && touches(selection, position)) + if (found is null || position.includes(found.offset) && position.includes(found.offset + found.length)) { + found= position; + bestMatch= annotation; + } + } + } + + if (bestMatch !is null) { + fProjectionAnnotationModel.expand(bestMatch); + revealRange(selection.x, selection.y); + } + } + } + + private bool touches(Point selection, Position position) { + return position.overlapsWith(selection.x, selection.y) || selection.y is 0 && position.offset + position.length is selection.x + selection.y; + } + + private void collapse() { + if (isProjectionMode()) { + Position found= null; + Annotation bestMatch= null; + Point selection= getSelectedRange(); + for (Iterator e= fProjectionAnnotationModel.getAnnotationIterator(); e.hasNext();) { + ProjectionAnnotation annotation= cast(ProjectionAnnotation) e.next(); + if (!annotation.isCollapsed()) { + Position position= fProjectionAnnotationModel.getPosition(annotation); + // take the first most fine grained match + if (position !is null && touches(selection, position)) + if (found is null || found.includes(position.offset) && found.includes(position.offset + position.length)) { + found= position; + bestMatch= annotation; + } + } + } + + if (bestMatch !is null) { + fProjectionAnnotationModel.collapse(bestMatch); + revealRange(selection.x, selection.y); + } + } + } + + /* + * @since 3.2 + */ + private void collapseAll() { + int offset= 0; + IDocument doc= getDocument(); + int length= doc is null ? 0 : doc.getLength(); + if (isProjectionMode()) { + fProjectionAnnotationModel.collapseAll(offset, length); + } + } + + /** + * Adds the given master range to the given projection document. While the + * modification is processed, the viewer no longer handles projection + * changes, as it is causing them. + * + * @param projection the projection document + * @param offset the offset in the master document + * @param length the length in the master document + * @throws BadLocationException in case the specified range is invalid + * + * @see ProjectionDocument#addMasterDocumentRange(int, int) + */ + private void addMasterDocumentRange(ProjectionDocument projection, int offset, int length) { + + if (fCommandQueue !is null) { + fCommandQueue.add(new ProjectionCommand(projection, ProjectionCommand.ADD, offset, length)); + } else { + try { + fHandleProjectionChanges= false; + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=108258 + // make sure the document range is strictly line based + int end= offset + length; + offset= toLineStart(projection.getMasterDocument(), offset, false); + length= toLineStart(projection.getMasterDocument(), end, true) - offset; + projection.addMasterDocumentRange(offset, length); + } finally { + fHandleProjectionChanges= true; + } + } + } + + /** + * Removes the given master range from the given projection document. While the + * modification is processed, the viewer no longer handles projection + * changes, as it is causing them. + * + * @param projection the projection document + * @param offset the offset in the master document + * @param length the length in the master document + * @throws BadLocationException in case the specified range is invalid + * + * @see ProjectionDocument#removeMasterDocumentRange(int, int) + */ + private void removeMasterDocumentRange(ProjectionDocument projection, int offset, int length) { + if (fCommandQueue !is null) { + fCommandQueue.add(new ProjectionCommand(projection, ProjectionCommand.REMOVE, offset, length)); + } else { + try { + fHandleProjectionChanges= false; + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=108258 + // make sure the document range is strictly line based + int end= offset + length; + offset= toLineStart(projection.getMasterDocument(), offset, false); + length= toLineStart(projection.getMasterDocument(), end, true) - offset; + projection.removeMasterDocumentRange(offset, length); + } finally { + fHandleProjectionChanges= true; + } + } + } + + /** + * Returns the first line offset <= offset. If testLastLine + * is true and the offset is on last line then offset is returned. + * + * @param document the document + * @param offset the master document offset + * @param testLastLine true if the test for the last line should be performed + * @return the closest line offset >= offset + * @throws BadLocationException if the offset is invalid + * @since 3.2 + */ + private int toLineStart(IDocument document, int offset, bool testLastLine) { + if (document is null) + return offset; + + if (testLastLine && offset >= document.getLineInformationOfOffset(document.getLength() - 1).getOffset()) + return offset; + + return document.getLineInformationOfOffset(offset).getOffset(); + } + + /* + * @see dwtx.jface.text.TextViewer#setVisibleRegion(int, int) + */ + public void setVisibleRegion(int start, int length) { + fWasProjectionEnabled= isProjectionMode(); + disableProjection(); + super.setVisibleRegion(start, length); + } + + /* + * @see dwtx.jface.text.TextViewer#setVisibleDocument(dwtx.jface.text.IDocument) + */ + protected void setVisibleDocument(IDocument document) { + if (!isProjectionMode()) { + super.setVisibleDocument(document); + return; + } + + // In projection mode we don't want to throw away the find/replace document adapter + FindReplaceDocumentAdapter adapter= fFindReplaceDocumentAdapter; + super.setVisibleDocument(document); + fFindReplaceDocumentAdapter= adapter; + } + + /* + * @see dwtx.jface.text.TextViewer#resetVisibleRegion() + */ + public void resetVisibleRegion() { + super.resetVisibleRegion(); + if (fWasProjectionEnabled) + enableProjection(); + } + + /* + * @see dwtx.jface.text.ITextViewer#getVisibleRegion() + */ + public IRegion getVisibleRegion() { + disableProjection(); + IRegion visibleRegion= getModelCoverage(); + if (visibleRegion is null) + visibleRegion= new Region(0, 0); + + return visibleRegion; + } + + /* + * @see dwtx.jface.text.ITextViewer#overlapsWithVisibleRegion(int,int) + */ + public bool overlapsWithVisibleRegion(int offset, int length) { + disableProjection(); + IRegion coverage= getModelCoverage(); + if (coverage is null) + return false; + + bool appending= (offset is coverage.getOffset() + coverage.getLength()) && length is 0; + return appending || TextUtilities.overlaps(coverage, new Region(offset, length)); + } + + /** + * Replace the visible document with the given document. Maintains the + * scroll offset and the selection. + * + * @param slave the visible document + */ + private void replaceVisibleDocument(IDocument slave) { + if (fReplaceVisibleDocumentExecutionTrigger !is null) { + ReplaceVisibleDocumentExecutor executor= new ReplaceVisibleDocumentExecutor(slave); + executor.install(fReplaceVisibleDocumentExecutionTrigger); + } else + executeReplaceVisibleDocument(slave); + } + + + private void executeReplaceVisibleDocument(IDocument visibleDocument) { + StyledText textWidget= getTextWidget(); + try { + if (textWidget !is null && !textWidget.isDisposed()) + textWidget.setRedraw(false); + + int topIndex= getTopIndex(); + Point selection= getSelectedRange(); + setVisibleDocument(visibleDocument); + Point currentSelection= getSelectedRange(); + if (currentSelection.x !is selection.x || currentSelection.y !is selection.y) + setSelectedRange(selection.x, selection.y); + setTopIndex(topIndex); + + } finally { + if (textWidget !is null && !textWidget.isDisposed()) + textWidget.setRedraw(true); + } + } + + /** + * Hides the given range by collapsing it. If requested, a redraw request is issued. + * + * @param offset the offset of the range to hide + * @param length the length of the range to hide + * @param fireRedraw true if a redraw request should be issued, false otherwise + * @throws BadLocationException in case the range is invalid + */ + private void collapse(int offset, int length, bool fireRedraw) { + ProjectionDocument projection= null; + + IDocument visibleDocument= getVisibleDocument(); + if ( cast(ProjectionDocument)visibleDocument ) + projection= cast(ProjectionDocument) visibleDocument; + else { + IDocument master= getDocument(); + IDocument slave= createSlaveDocument(getDocument()); + if ( cast(ProjectionDocument)slave ) { + projection= cast(ProjectionDocument) slave; + addMasterDocumentRange(projection, 0, master.getLength()); + replaceVisibleDocument(projection); + } + } + + if (projection !is null) + removeMasterDocumentRange(projection, offset, length); + + if (projection !is null && fireRedraw) { + // repaint line above to get the folding box + IDocument document= getDocument(); + int line= document.getLineOfOffset(offset); + if (line > 0) { + IRegion info= document.getLineInformation(line - 1); + internalInvalidateTextPresentation(info.getOffset(), info.getLength()); + } + } + } + + /** + * Makes the given range visible again while not changing the folding state of any contained + * ranges. If requested, a redraw request is issued. + * + * @param offset the offset of the range to be expanded + * @param length the length of the range to be expanded + * @param fireRedraw true if a redraw request should be issued, + * false otherwise + * @throws BadLocationException in case the range is invalid + */ + private void expand(int offset, int length, bool fireRedraw) { + IDocument slave= getVisibleDocument(); + if ( cast(ProjectionDocument)slave ) { + ProjectionDocument projection= cast(ProjectionDocument) slave; + + // expand + addMasterDocumentRange(projection, offset, length); + + // collapse contained regions + ProjectionAnnotation[] collapsed= computeCollapsedNestedAnnotations(offset, length); + if (collapsed !is null) { + for (int i= 0; i < collapsed.length; i++) { + IRegion[] regions= computeCollapsedRegions(fProjectionAnnotationModel.getPosition(collapsed[i])); + if (regions !is null) + for (int j= 0; j < regions.length; j++) + removeMasterDocumentRange(projection, regions[j].getOffset(), regions[j].getLength()); + } + } + + // redraw if requested + if (fireRedraw) + internalInvalidateTextPresentation(offset, length); + } + } + + /** + * Processes the request for catch up with the annotation model in the UI thread. If the current + * thread is not the UI thread or there are pending catch up requests, a new request is posted. + * + * @param event the annotation model event + */ + protected final void processCatchupRequest(AnnotationModelEvent event) { + if (Display.getCurrent() !is null) { + bool run= false; + synchronized (fLock) { + run= fPendingRequests.isEmpty(); + } + if (run) { + + try { + catchupWithProjectionAnnotationModel(event); + } catch (BadLocationException x) { + throw new IllegalArgumentException(null); + } + + } else + postCatchupRequest(event); + } else { + postCatchupRequest(event); + } + } + + /** + * Posts the request for catch up with the annotation model into the UI thread. + * + * @param event the annotation model event + */ + protected final void postCatchupRequest(AnnotationModelEvent event) { + synchronized (fLock) { + fPendingRequests.add(event); + if (fPendingRequests.size() is 1) { + StyledText widget= getTextWidget(); + if (widget !is null) { + Display display= widget.getDisplay(); + if (display !is null) { + display.asyncExec(new class() Runnable { + public void run() { + try { + while (true) { + AnnotationModelEvent ame= null; + synchronized (fLock) { + if (fPendingRequests.size() is 0) + return; + ame= cast(AnnotationModelEvent) fPendingRequests.remove(0); + } + catchupWithProjectionAnnotationModel(ame); + } + } catch (BadLocationException x) { + try { + catchupWithProjectionAnnotationModel(null); + } catch (BadLocationException x1) { + throw new IllegalArgumentException(null); + } finally { + synchronized (fLock) { + fPendingRequests.clear(); + } + } + } + } + }); + } + } + } + } + } + + /** + * Tests whether the visible document's master document + * is identical to this viewer's document. + * + * @return true if the visible document's master is + * identical to this viewer's document + * @since 3.1 + */ + private bool isVisibleMasterDocumentSameAsDocument() { + IDocument visibleDocument= getVisibleDocument(); + return ( cast(ProjectionDocument)visibleDocument ) && (cast(ProjectionDocument)visibleDocument).getMasterDocument() is getDocument(); + } + + /** + * Adapts the slave visual document of this viewer to the changes described + * in the annotation model event. When the event is null, + * this is identical to a world change event. + * + * @param event the annotation model event or null + * @exception BadLocationException in case the annotation model event is no longer in synchronization with the document + */ + private void catchupWithProjectionAnnotationModel(AnnotationModelEvent event) { + + if (event is null || !isVisibleMasterDocumentSameAsDocument()) { + + fPendingAnnotationWorldChange= false; + reinitializeProjection(); + + } else if (event.isWorldChange()) { + + if (event.isValid()) { + fPendingAnnotationWorldChange= false; + reinitializeProjection(); + } else + fPendingAnnotationWorldChange= true; + + } else if (fPendingAnnotationWorldChange) { + if (event.isValid()) { + fPendingAnnotationWorldChange= false; + reinitializeProjection(); + } + } else { + + Annotation[] addedAnnotations= event.getAddedAnnotations(); + Annotation[] changedAnnotation= event.getChangedAnnotations(); + Annotation[] removedAnnotations= event.getRemovedAnnotations(); + + fCommandQueue= new ProjectionCommandQueue(); + + bool isRedrawing= redraws(); + int topIndex= isRedrawing ? getTopIndex() : -1; + + processDeletions(event, removedAnnotations, true); + List coverage= new ArrayList(); + processChanges(addedAnnotations, true, coverage); + processChanges(changedAnnotation, true, coverage); + + ProjectionCommandQueue commandQueue= fCommandQueue; + fCommandQueue= null; + + if (commandQueue.passedRedrawCostsThreshold()) { + setRedraw(false); + try { + executeProjectionCommands(commandQueue, false); + } catch (IllegalArgumentException x) { + reinitializeProjection(); + } finally { + setRedraw(true, topIndex); + } + } else { + try { + bool fireRedraw= !commandQueue.passedInvalidationCostsThreshold(); + executeProjectionCommands(commandQueue, fireRedraw); + if (!fireRedraw) + invalidateTextPresentation(); + } catch (IllegalArgumentException x) { + reinitializeProjection(); + } + } + } + } + + private void executeProjectionCommands(ProjectionCommandQueue commandQueue, bool fireRedraw) { + + ProjectionCommand command; + Iterator e= commandQueue.iterator(); + while (e.hasNext()) { + command= cast(ProjectionCommand) e.next(); + switch (command.fType) { + case ProjectionCommand.ADD: + addMasterDocumentRange(command.fProjection, command.fOffset, command.fLength); + break; + case ProjectionCommand.REMOVE: + removeMasterDocumentRange(command.fProjection, command.fOffset, command.fLength); + break; + case ProjectionCommand.INVALIDATE_PRESENTATION: + if (fireRedraw) + invalidateTextPresentation(command.fOffset, command.fLength); + break; + } + } + + commandQueue.clear(); + } + + private bool covers(int offset, int length, Position position) { + if (!(position.offset is offset && position.length is length) && !position.isDeleted()) + return offset <= position.getOffset() && position.getOffset() + position.getLength() <= offset + length; + return false; + } + + private ProjectionAnnotation[] computeCollapsedNestedAnnotations(int offset, int length) { + List annotations= new ArrayList(5); + Iterator e= fProjectionAnnotationModel.getAnnotationIterator(); + while (e.hasNext()) { + ProjectionAnnotation annotation= cast(ProjectionAnnotation) e.next(); + if (annotation.isCollapsed()) { + Position position= fProjectionAnnotationModel.getPosition(annotation); + if (position is null) { + // annotation might already be deleted, we will be informed later on about this deletion + continue; + } + if (covers(offset, length, position)) + annotations.add(annotation); + } + } + + if (annotations.size() > 0) { + ProjectionAnnotation[] result= new ProjectionAnnotation[annotations.size()]; + annotations.toArray(result); + return result; + } + + return null; + } + + private void internalInvalidateTextPresentation(int offset, int length) { + if (fCommandQueue !is null) { + fCommandQueue.add(new ProjectionCommand(offset, length)); + } else { + invalidateTextPresentation(offset, length); + } + } + + /* + * We pass the removed annotation into this method for performance reasons only. Otherwise, they could be fetch from the event. + */ + private void processDeletions(AnnotationModelEvent event, Annotation[] removedAnnotations, bool fireRedraw) { + for (int i= 0; i < removedAnnotations.length; i++) { + ProjectionAnnotation annotation= cast(ProjectionAnnotation) removedAnnotations[i]; + if (annotation.isCollapsed()) { + Position expanded= event.getPositionOfRemovedAnnotation(annotation); + expand(expanded.getOffset(), expanded.getLength(), fireRedraw); + } + } + } + + /** + * Computes the region that must be collapsed when the given position is the + * position of an expanded projection annotation. + * + * @param position the position + * @return the range that must be collapsed + */ + public IRegion computeCollapsedRegion(Position position) { + try { + IDocument document= getDocument(); + if (document is null) + return null; + + int line= document.getLineOfOffset(position.getOffset()); + int offset= document.getLineOffset(line + 1); + + int length= position.getLength() - (offset - position.getOffset()); + if (length > 0) + return new Region(offset, length); + } catch (BadLocationException x) { + } + + return null; + } + + /** + * Computes the regions that must be collapsed when the given position is + * the position of an expanded projection annotation. + * + * @param position the position + * @return the ranges that must be collapsed, or null if + * there are none + * @since 3.1 + */ + IRegion[] computeCollapsedRegions(Position position) { + try { + IDocument document= getDocument(); + if (document is null) + return null; + + if ( cast(IProjectionPosition)position ) { + IProjectionPosition projPosition= cast(IProjectionPosition) position; + return projPosition.computeProjectionRegions(document); + } + + int line= document.getLineOfOffset(position.getOffset()); + int offset= document.getLineOffset(line + 1); + + int length= position.getLength() - (offset - position.getOffset()); + if (length > 0) + return [new Region(offset, length)]; + + return null; + } catch (BadLocationException x) { + return null; + } + } + + /** + * Computes the collapsed region anchor for the given position. Assuming + * that the position is the position of an expanded projection annotation, + * the anchor is the region that is still visible after the projection + * annotation has been collapsed. + * + * @param position the position + * @return the collapsed region anchor + */ + public Position computeCollapsedRegionAnchor(Position position) { + try { + IDocument document= getDocument(); + if (document is null) + return null; + + int captionOffset= position.getOffset(); + if ( cast(IProjectionPosition)position ) + captionOffset+= (cast(IProjectionPosition) position).computeCaptionOffset(document); + + IRegion lineInfo= document.getLineInformationOfOffset(captionOffset); + return new Position(lineInfo.getOffset() + lineInfo.getLength(), 0); + } catch (BadLocationException x) { + } + return null; + } + + private void processChanges(Annotation[] annotations, bool fireRedraw, List coverage) { + for (int i= 0; i < annotations.length; i++) { + ProjectionAnnotation annotation= cast(ProjectionAnnotation) annotations[i]; + Position position= fProjectionAnnotationModel.getPosition(annotation); + + if (position is null) + continue; + + if (!covers(coverage, position)) { + if (annotation.isCollapsed()) { + coverage.add(position); + IRegion[] regions= computeCollapsedRegions(position); + if (regions !is null) + for (int j= 0; j < regions.length; j++) + collapse(regions[j].getOffset(), regions[j].getLength(), fireRedraw); + } else { + expand(position.getOffset(), position.getLength(), fireRedraw); + } + } + } + } + + private bool covers(List coverage, Position position) { + Iterator e= coverage.iterator(); + while (e.hasNext()) { + Position p= cast(Position) e.next(); + if (p.getOffset() <= position.getOffset() && position.getOffset() + position.getLength() <= p.getOffset() + p.getLength()) + return true; + } + return false; + } + + /** + * Forces this viewer to throw away any old state and to initialize its content + * from its projection annotation model. + * + * @throws BadLocationException in case something goes wrong during initialization + */ + public final void reinitializeProjection() { + + ProjectionDocument projection= null; + + ISlaveDocumentManager manager= getSlaveDocumentManager(); + if (manager !is null) { + IDocument master= getDocument(); + if (master !is null) { + IDocument slave= manager.createSlaveDocument(master); + if ( cast(ProjectionDocument)slave ) { + projection= cast(ProjectionDocument) slave; + addMasterDocumentRange(projection, 0, master.getLength()); + } + } + } + + if (projection !is null) { + Iterator e= fProjectionAnnotationModel.getAnnotationIterator(); + while (e.hasNext()) { + ProjectionAnnotation annotation= cast(ProjectionAnnotation) e.next(); + if (annotation.isCollapsed()) { + Position position= fProjectionAnnotationModel.getPosition(annotation); + if (position !is null) { + IRegion[] regions= computeCollapsedRegions(position); + if (regions !is null) + for (int i= 0; i < regions.length; i++) + removeMasterDocumentRange(projection, regions[i].getOffset(), regions[i].getLength()); + } + } + } + + } + + replaceVisibleDocument(projection); + } + + /* + * @see dwtx.jface.text.TextViewer#handleVerifyEvent(dwt.events.VerifyEvent) + */ + protected void handleVerifyEvent(VerifyEvent e) { + IRegion modelRange= event2ModelRange(e); + if (exposeModelRange(modelRange)) + e.doit= false; + else + super.handleVerifyEvent(e); + } + + /** + * Adds the give column as last column to this viewer's vertical ruler. + * + * @param column the column to be added + */ + public void addVerticalRulerColumn(IVerticalRulerColumn column) { + IVerticalRuler ruler= getVerticalRuler(); + if ( cast(CompositeRuler)ruler ) { + CompositeRuler compositeRuler= cast(CompositeRuler) ruler; + compositeRuler.addDecorator(99, column); + } + } + + /** + * Removes the give column from this viewer's vertical ruler. + * + * @param column the column to be removed + */ + public void removeVerticalRulerColumn(IVerticalRulerColumn column) { + IVerticalRuler ruler= getVerticalRuler(); + if ( cast(CompositeRuler)ruler ) { + CompositeRuler compositeRuler= cast(CompositeRuler) ruler; + compositeRuler.removeDecorator(column); + } + } + + /* + * @see dwtx.jface.text.ITextViewerExtension5#exposeModelRange(dwtx.jface.text.IRegion) + */ + public bool exposeModelRange(IRegion modelRange) { + if (isProjectionMode()) + return fProjectionAnnotationModel.expandAll(modelRange.getOffset(), modelRange.getLength()); + + if (!overlapsWithVisibleRegion(modelRange.getOffset(), modelRange.getLength())) { + resetVisibleRegion(); + return true; + } + + return false; + } + + /* + * @see dwtx.jface.text.source.SourceViewer#setRangeIndication(int, int, bool) + */ + public void setRangeIndication(int offset, int length, bool moveCursor) { + IRegion rangeIndication= getRangeIndication(); + if (moveCursor && fProjectionAnnotationModel !is null && (rangeIndication is null || offset !is rangeIndication.getOffset() || length !is rangeIndication.getLength())) { + List expand= new ArrayList(2); + // expand the immediate effected collapsed regions + Iterator iterator= fProjectionAnnotationModel.getAnnotationIterator(); + while (iterator.hasNext()) { + ProjectionAnnotation annotation= cast(ProjectionAnnotation)iterator.next(); + if (annotation.isCollapsed() && willAutoExpand(fProjectionAnnotationModel.getPosition(annotation), offset, length)) + expand.add(annotation); + } + + if (!expand.isEmpty()) { + Iterator e= expand.iterator(); + while (e.hasNext()) + fProjectionAnnotationModel.expand(cast(Annotation)e.next()); + } + } + super.setRangeIndication(offset, length, moveCursor); + } + + private bool willAutoExpand(Position position, int offset, int length) { + if (position is null || position.isDeleted()) + return false; + // right or left boundary + if (position.getOffset() is offset || position.getOffset() + position.getLength() is offset + length) + return true; + // completely embedded in given position + if (position.getOffset() < offset && offset + length < position.getOffset() + position.getLength()) + return true; + return false; + } + + /* + * @see dwtx.jface.text.source.SourceViewer#handleDispose() + * @since 3.0 + */ + protected void handleDispose() { + fWasProjectionEnabled= false; + super.handleDispose(); + } + + /* + * @see dwtx.jface.text.TextViewer#handleVisibleDocumentAboutToBeChanged(dwtx.jface.text.DocumentEvent) + */ + protected void handleVisibleDocumentChanged(DocumentEvent event) { + if (fHandleProjectionChanges && cast(ProjectionDocumentEvent)event && isProjectionMode()) { + ProjectionDocumentEvent e= cast(ProjectionDocumentEvent) event; + + DocumentEvent master= e.getMasterEvent(); + if (master !is null) + fReplaceVisibleDocumentExecutionTrigger= master.getDocument(); + + try { + + int replaceLength= e.getText() is null ? 0 : e.getText().length(); + if (ProjectionDocumentEvent.PROJECTION_CHANGE is e.getChangeType()) { + if (e.getLength() is 0 && replaceLength !is 0) + fProjectionAnnotationModel.expandAll(e.getMasterOffset(), e.getMasterLength()); + } else if (master !is null && (replaceLength > 0 || fDeletedLines > 1)) { + try { + int numberOfLines= e.getDocument().getNumberOfLines(e.getOffset(), replaceLength); + if (numberOfLines > 1 || fDeletedLines > 1) + fProjectionAnnotationModel.expandAll(master.getOffset(), master.getLength()); + } catch (BadLocationException x) { + } + } + + } finally { + fReplaceVisibleDocumentExecutionTrigger= null; + } + + } + } + + /* + * @see dwtx.jface.text.TextViewer#handleVisibleDocumentAboutToBeChanged(dwtx.jface.text.DocumentEvent) + * @since 3.1 + */ + protected void handleVisibleDocumentAboutToBeChanged(DocumentEvent event) { + if (fHandleProjectionChanges && cast(ProjectionDocumentEvent)event && isProjectionMode()) { + int deletedLines; + try { + deletedLines= event.getDocument().getNumberOfLines(event.getOffset(), event.getLength()); + } catch (BadLocationException e1) { + deletedLines= 0; + } + fDeletedLines= deletedLines; + } + } + + /* + * @see dwtx.jface.text.ITextViewerExtension5#getCoveredModelRanges(dwtx.jface.text.IRegion) + */ + public IRegion[] getCoveredModelRanges(IRegion modelRange) { + if (fInformationMapping is null) + return [ new Region(modelRange.getOffset(), modelRange.getLength()) ]; + + if ( cast(IDocumentInformationMappingExtension)fInformationMapping ) { + IDocumentInformationMappingExtension extension= cast(IDocumentInformationMappingExtension) fInformationMapping; + try { + return extension.getExactCoverage(modelRange); + } catch (BadLocationException x) { + } + } + + return null; + } + + /* + * @see dwtx.jface.text.ITextOperationTarget#doOperation(int) + */ + public void doOperation(int operation) { + switch (operation) { + case TOGGLE: + if (canDoOperation(TOGGLE)) { + if (!isProjectionMode()) { + enableProjection(); + } else { + expandAll(); + disableProjection(); + } + return; + } + } + + if (!isProjectionMode()) { + super.doOperation(operation); + return; + } + + StyledText textWidget= getTextWidget(); + if (textWidget is null) + return; + + Point selection= null; + switch (operation) { + + case CUT: + + if (redraws()) { + selection= getSelectedRange(); + if (exposeModelRange(new Region(selection.x, selection.y))) + return; + + if (selection.y is 0) + copyMarkedRegion(true); + else + copyToClipboard(selection.x, selection.y, true, textWidget); + + selection= textWidget.getSelectionRange(); + fireSelectionChanged(selection.x, selection.y); + } + break; + + case COPY: + + if (redraws()) { + selection= getSelectedRange(); + if (selection.y is 0) + copyMarkedRegion(false); + else + copyToClipboard(selection.x, selection.y, false, textWidget); + } + break; + + case DELETE: + + if (redraws()) { + try { + selection= getSelectedRange(); + Point widgetSelection= textWidget.getSelectionRange(); + if (selection.y is 0 || selection.y is widgetSelection.y) + getTextWidget().invokeAction(ST.DELETE_NEXT); + else + deleteTextRange(selection.x, selection.y, textWidget); + + selection= textWidget.getSelectionRange(); + fireSelectionChanged(selection.x, selection.y); + + } catch (BadLocationException x) { + // ignore + } + } + break; + + + case EXPAND_ALL: + if (redraws()) + expandAll(); + break; + + case EXPAND: + if (redraws()) { + expand(); + } + break; + + case COLLAPSE_ALL: + if (redraws()) + collapseAll(); + break; + + case COLLAPSE: + if (redraws()) { + collapse(); + } + break; + + default: + super.doOperation(operation); + } + } + + /* + * @see dwtx.jface.text.source.SourceViewer#canDoOperation(int) + */ + public bool canDoOperation(int operation) { + + switch (operation) { + case COLLAPSE: + case COLLAPSE_ALL: + case EXPAND: + case EXPAND_ALL: + return isProjectionMode(); + case TOGGLE: + return isProjectionMode() || !isSegmented(); + } + + return super.canDoOperation(operation); + } + + private bool isSegmented() { + IDocument document= getDocument(); + int length= document is null ? 0 : document.getLength(); + IRegion visible= getModelCoverage(); + bool isSegmented= visible !is null && !(cast(Object)visible).opEquals(new Region(0, length)); + return isSegmented; + } + + private IRegion getMarkedRegion() { + if (getTextWidget() is null) + return null; + + if (fMarkPosition is null || fMarkPosition.isDeleted()) + return null; + + int start= fMarkPosition.getOffset(); + int end= getSelectedRange().x; + + return start > end ? new Region (end, start - end) : new Region(start, end - start); + } + + /* + * @see dwtx.jface.text.TextViewer#copyMarkedRegion(bool) + */ + protected void copyMarkedRegion(bool delete_) { + IRegion markedRegion= getMarkedRegion(); + if (markedRegion !is null) + copyToClipboard(markedRegion.getOffset(), markedRegion.getLength(), delete_, getTextWidget()); + } + + private void copyToClipboard(int offset, int length, bool delete_, StyledText textWidget) { + + String copyText= null; + + try { + IDocument document= getDocument(); + copyText= document.get(offset, length); + } catch (BadLocationException ex) { + // XXX: should log here, but JFace Text has no Log + // As a fallback solution let the widget handle this + textWidget.copy(); + } + + if (copyText !is null && copyText.equals(textWidget.getSelectionText())) { + /* + * XXX: Reduce pain of https://bugs.eclipse.org/bugs/show_bug.cgi?id=64498 + * by letting the widget handle the copy operation in this special case. + */ + textWidget.copy(); + } else if (copyText !is null) { + + Clipboard clipboard= new Clipboard(textWidget.getDisplay()); + + try { + Transfer[] dataTypes= [ TextTransfer.getInstance() ]; + Object[] data= [ stringcast(copyText) ]; + try { + clipboard.setContents(data, dataTypes); + } catch (DWTError e) { + if (e.code !is DND.ERROR_CANNOT_SET_CLIPBOARD) + throw e; + /* + * TODO see https://bugs.eclipse.org/bugs/show_bug.cgi?id=59459 + * we should either log and/or inform the user + * silently fail for now. + */ + return; + } + + } finally { + clipboard.dispose(); + } + } + + if (delete_) { + try { + deleteTextRange(offset, length, textWidget); + } catch (BadLocationException x) { + // XXX: should log here, but JFace Text has no Log + } + } + } + + private void deleteTextRange(int offset, int length, StyledText textWidget) { + getDocument().replace(offset, length, ""); //$NON-NLS-1$ + int widgetCaret= modelOffset2WidgetOffset(offset); + if (widgetCaret > -1) + textWidget.setSelection(widgetCaret); + } + + /** + * Adapts the behavior of the super class to respect line based folding. + * + * @param widgetSelection the widget selection + * @return the model selection while respecting line based folding + */ + protected Point widgetSelection2ModelSelection(Point widgetSelection) { + + if (!isProjectionMode()) + return super.widgetSelection2ModelSelection(widgetSelection); + + /* + * There is one requirement that governs preservation of logical + * positions: + * + * 1) a selection with widget_length is 0 should never expand to have + * model_length > 0. + * + * There are a number of ambiguities to resolve with projection regions. + * A projected region P has a widget-length of zero. Its widget offset + * may interact with the selection S in various ways: + * + * A) P.widget_offset lies at the caret, S.widget_length is zero. + * Requirement 1 applies. S is *behind* P (done so by widgetRange2ModelRange). + * + * B) P.widget_offset lies inside the widget selection. This case is + * easy: P is included in S, which is automatically done so by + * widgetRange2ModelRange. + * + * C) P.widget_offset lies at S.widget_end: This is + * arguable - our policy is to include P if it belongs to a projection + * annotation that overlaps with the widget selection. + * + * D) P.widget_offset lies at S.widget_offset: Arguable - our policy + * is to include P if it belongs to a projection annotation that + * overlaps with the widget selection + */ + IRegion modelSelection= widgetRange2ModelRange(new Region(widgetSelection.x, widgetSelection.y)); + if (modelSelection is null) + return null; + + int modelOffset= modelSelection.getOffset(); + int modelEndOffset= modelOffset + modelSelection.getLength(); + + /* Case A: never expand a zero-length selection. S is *behind* P. */ + if (widgetSelection.y is 0) + return new Point(modelEndOffset, 0); + + int widgetSelectionExclusiveEnd= widgetSelection.x + widgetSelection.y; + Position[] annotationPositions= computeOverlappingAnnotationPositions(modelSelection); + for (int i= 0; i < annotationPositions.length; i++) { + IRegion[] regions= computeCollapsedRegions(annotationPositions[i]); + if (regions is null) + continue; + for (int j= 0; j < regions.length; j++) { + IRegion modelRange= regions[j]; + IRegion widgetRange= modelRange2ClosestWidgetRange(modelRange); + // only take collapsed ranges, i.e. widget length is 0 + if (widgetRange !is null && widgetRange.getLength() is 0) { + int widgetOffset= widgetRange.getOffset(); + // D) region is collapsed at S.widget_offset + if (widgetOffset is widgetSelection.x) + modelOffset= Math.min(modelOffset, modelRange.getOffset()); + // C) region is collapsed at S.widget_end + else if (widgetOffset is widgetSelectionExclusiveEnd) + modelEndOffset= Math.max(modelEndOffset, modelRange.getOffset() + modelRange.getLength()); + } + } + } + return new Point(modelOffset, modelEndOffset - modelOffset); + } + + /** + * Returns the positions of all annotations that intersect with + * modelSelection and that are at least partly visible. + * @param modelSelection a model range + * @return the positions of all annotations that intersect with + * modelSelection + * @since 3.1 + */ + private Position[] computeOverlappingAnnotationPositions(IRegion modelSelection) { + List positions= new ArrayList(); + for (Iterator e= fProjectionAnnotationModel.getAnnotationIterator(); e.hasNext();) { + ProjectionAnnotation annotation= cast(ProjectionAnnotation) e.next(); + Position position= fProjectionAnnotationModel.getPosition(annotation); + if (position !is null && position.overlapsWith(modelSelection.getOffset(), modelSelection.getLength()) && modelRange2WidgetRange(position) !is null) + positions.add(position); + } + return arraycast!(Position)( positions.toArray()); + } + + /* + * @see dwtx.jface.text.TextViewer#getFindReplaceDocumentAdapter() + */ + protected FindReplaceDocumentAdapter getFindReplaceDocumentAdapter() { + if (fFindReplaceDocumentAdapter is null) { + IDocument document= isProjectionMode() ? getDocument() : getVisibleDocument(); + fFindReplaceDocumentAdapter= new FindReplaceDocumentAdapter(document); + } + return fFindReplaceDocumentAdapter; + } + + /* + * @see dwtx.jface.text.TextViewer#findAndSelect(int, java.lang.String, bool, bool, bool, bool) + */ + protected int findAndSelect(int startPosition, String findString, bool forwardSearch, bool caseSensitive, bool wholeWord, bool regExSearch) { + + if (!isProjectionMode()) + return super.findAndSelect(startPosition, findString, forwardSearch, caseSensitive, wholeWord, regExSearch); + + StyledText textWidget= getTextWidget(); + if (textWidget is null) + return -1; + + try { + + IRegion matchRegion= getFindReplaceDocumentAdapter().find(startPosition, findString, forwardSearch, caseSensitive, wholeWord, regExSearch); + if (matchRegion !is null) { + exposeModelRange(matchRegion); + revealRange(matchRegion.getOffset(), matchRegion.getLength()); + setSelectedRange(matchRegion.getOffset(), matchRegion.getLength()); + return matchRegion.getOffset(); + } + + } catch (BadLocationException x) { + } + + return -1; + } + + /* + * @see dwtx.jface.text.TextViewer#findAndSelectInRange(int, java.lang.String, bool, bool, bool, int, int, bool) + */ + protected int findAndSelectInRange(int startPosition, String findString, bool forwardSearch, bool caseSensitive, bool wholeWord, int rangeOffset, int rangeLength, bool regExSearch) { + + if (!isProjectionMode()) + return super.findAndSelectInRange(startPosition, findString, forwardSearch, caseSensitive, wholeWord, rangeOffset, rangeLength, regExSearch); + + StyledText textWidget= getTextWidget(); + if (textWidget is null) + return -1; + + try { + + int modelOffset= startPosition; + if (forwardSearch && (startPosition is -1 || startPosition < rangeOffset)) { + modelOffset= rangeOffset; + } else if (!forwardSearch && (startPosition is -1 || startPosition > rangeOffset + rangeLength)) { + modelOffset= rangeOffset + rangeLength; + } + + IRegion matchRegion= getFindReplaceDocumentAdapter().find(modelOffset, findString, forwardSearch, caseSensitive, wholeWord, regExSearch); + if (matchRegion !is null) { + int offset= matchRegion.getOffset(); + int length= matchRegion.getLength(); + if (rangeOffset <= offset && offset + length <= rangeOffset + rangeLength) { + exposeModelRange(matchRegion); + revealRange(offset, length); + setSelectedRange(offset, length); + return offset; + } + } + + } catch (BadLocationException x) { + } + + return -1; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/projection/SourceViewerInformationControl.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/projection/SourceViewerInformationControl.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,451 @@ +/******************************************************************************* + * 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 + * 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.text.source.projection.SourceViewerInformationControl; + +import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport +import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport +import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport +import dwtx.jface.text.source.projection.AnnotationBag; // packageimport +import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport +import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport +import dwtx.jface.text.source.projection.IProjectionListener; // packageimport +import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport + + +import dwt.dwthelper.utils; + + + + +import dwt.DWT; +import dwt.custom.StyledText; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.events.FocusListener; +import dwt.events.KeyEvent; +import dwt.events.KeyListener; +import dwt.graphics.Color; +import dwt.graphics.Font; +import dwt.graphics.FontData; +import dwt.graphics.GC; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.layout.GridData; +import dwt.layout.GridLayout; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Label; +import dwt.widgets.Shell; +import dwtx.jface.resource.JFaceResources; +import dwtx.jface.text.Document; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IInformationControl; +import dwtx.jface.text.IInformationControlCreator; +import dwtx.jface.text.IInformationControlExtension; +import dwtx.jface.text.IInformationControlExtension3; +import dwtx.jface.text.IInformationControlExtension5; +import dwtx.jface.text.source.SourceViewer; +import dwtx.jface.text.source.SourceViewerConfiguration; + +/** + * Source viewer based implementation of {@link dwtx.jface.text.IInformationControl}. + * Displays information in a source viewer. + * + * @since 3.0 + */ +class SourceViewerInformationControl : IInformationControl, IInformationControlExtension, IInformationControlExtension3, IInformationControlExtension5, DisposeListener { + + /** The control's shell */ + private Shell fShell; + /** The control's text widget */ + private StyledText fText; + /** The symbolic font name of the text font */ + private const String fSymbolicFontName; + /** The text font (do not dispose!) */ + private Font fTextFont; + /** The control's source viewer */ + private SourceViewer fViewer; + /** The optional status field. */ + private Label fStatusField; + /** The separator for the optional status field. */ + private Label fSeparator; + /** The font of the optional status text label.*/ + private Font fStatusTextFont; + /** The maximal widget width. */ + private int fMaxWidth; + /** The maximal widget height. */ + private int fMaxHeight; + + + /** + * Creates a source viewer information control with the given shell as parent. The given shell + * styles are applied to the created shell. The given styles are applied to the created styled + * text widget. The text widget will be initialized with the given font. The status field will + * contain the given text or be hidden. + * + * @param parent the parent shell + * @param isResizable true if resizable + * @param symbolicFontName the symbolic font name + * @param statusFieldText the text to be used in the optional status field or null + * if the status field should be hidden + */ + public this(Shell parent, bool isResizable, String symbolicFontName, String statusFieldText) { + GridLayout layout; + GridData gd; + + int shellStyle= DWT.TOOL | DWT.ON_TOP | (isResizable ? DWT.RESIZE : 0); + int textStyle= isResizable ? DWT.V_SCROLL | DWT.H_SCROLL : DWT.NONE; + + fShell= new Shell(parent, DWT.NO_FOCUS | DWT.ON_TOP | shellStyle); + Display display= fShell.getDisplay(); + + Composite composite= fShell; + layout= new GridLayout(1, false); + layout.marginHeight= 0; + layout.marginWidth= 0; + composite.setLayout(layout); + gd= new GridData(GridData.FILL_HORIZONTAL); + composite.setLayoutData(gd); + + if (statusFieldText !is null) { + composite= new Composite(composite, DWT.NONE); + layout= new GridLayout(1, false); + layout.marginHeight= 0; + layout.marginWidth= 0; + composite.setLayout(layout); + gd= new GridData(GridData.FILL_BOTH); + composite.setLayoutData(gd); + composite.setForeground(display.getSystemColor(DWT.COLOR_INFO_FOREGROUND)); + composite.setBackground(display.getSystemColor(DWT.COLOR_INFO_BACKGROUND)); + } + + // Source viewer + fViewer= new SourceViewer(composite, null, textStyle); + fViewer.configure(new SourceViewerConfiguration()); + fViewer.setEditable(false); + + fText= fViewer.getTextWidget(); + gd= new GridData(GridData.BEGINNING | GridData.FILL_BOTH); + fText.setLayoutData(gd); + fText.setForeground(parent.getDisplay().getSystemColor(DWT.COLOR_INFO_FOREGROUND)); + fText.setBackground(parent.getDisplay().getSystemColor(DWT.COLOR_INFO_BACKGROUND)); + fSymbolicFontName= symbolicFontName; + fTextFont= JFaceResources.getFont(symbolicFontName); + fText.setFont(fTextFont); + + fText.addKeyListener(new class() KeyListener { + + public void keyPressed(KeyEvent e) { + if (e.character is 0x1B) // ESC + fShell.dispose(); + } + + public void keyReleased(KeyEvent e) {} + }); + + // Status field + if (statusFieldText !is null) { + + // Horizontal separator line + fSeparator= new Label(composite, DWT.SEPARATOR | DWT.HORIZONTAL | DWT.LINE_DOT); + fSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // Status field label + fStatusField= new Label(composite, DWT.RIGHT); + fStatusField.setText(statusFieldText); + Font font= fStatusField.getFont(); + FontData[] fontDatas= font.getFontData(); + for (int i= 0; i < fontDatas.length; i++) + fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10); + fStatusTextFont= new Font(fStatusField.getDisplay(), fontDatas); + fStatusField.setFont(fStatusTextFont); + GridData gd2= new GridData(GridData.FILL_VERTICAL | GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING); + fStatusField.setLayoutData(gd2); + + // Regarding the color see bug 41128 + fStatusField.setForeground(display.getSystemColor(DWT.COLOR_WIDGET_DARK_SHADOW)); + + fStatusField.setBackground(display.getSystemColor(DWT.COLOR_INFO_BACKGROUND)); + } + + addDisposeListener(this); + } + + /** + * @see dwtx.jface.text.IInformationControlExtension2#setInput(java.lang.Object) + * @param input the input object + */ + public void setInput(Object input) { + if ( cast(ArrayWrapperString)input ) + setInformation(stringcast(input)); + else + setInformation(null); + } + + /* + * @see IInformationControl#setInformation(String) + */ + public void setInformation(String content) { + if (content is null) { + fViewer.setInput(null); + return; + } + + IDocument doc= new Document(content); + fViewer.setInput(cast(Object)doc); + } + + /* + * @see IInformationControl#setVisible(bool) + */ + public void setVisible(bool visible) { + fShell.setVisible(visible); + } + + /* + * @see dwt.events.DisposeListener#widgetDisposed(dwt.events.DisposeEvent) + */ + public void widgetDisposed(DisposeEvent event) { + if (fStatusTextFont !is null && !fStatusTextFont.isDisposed()) + fStatusTextFont.dispose(); + + fStatusTextFont= null; + fTextFont= null; + fShell= null; + fText= null; + } + + /* + * @see dwtx.jface.text.IInformationControl#dispose() + */ + public final void dispose() { + if (fShell !is null && !fShell.isDisposed()) + fShell.dispose(); + else + widgetDisposed(null); + } + + /* + * @see IInformationControl#setSize(int, int) + */ + public void setSize(int width, int height) { + + if (fStatusField !is null) { + GridData gd= cast(GridData)fViewer.getTextWidget().getLayoutData(); + Point statusSize= fStatusField.computeSize(DWT.DEFAULT, DWT.DEFAULT, true); + Point separatorSize= fSeparator.computeSize(DWT.DEFAULT, DWT.DEFAULT, true); + gd.heightHint= height - statusSize.y - separatorSize.y; + } + fShell.setSize(width, height); + + if (fStatusField !is null) + fShell.pack(true); + } + + /* + * @see IInformationControl#setLocation(Point) + */ + public void setLocation(Point location) { + fShell.setLocation(location); + } + + /* + * @see IInformationControl#setSizeConstraints(int, int) + */ + public void setSizeConstraints(int maxWidth, int maxHeight) { + fMaxWidth= maxWidth; + fMaxHeight= maxHeight; + } + + /* + * @see IInformationControl#computeSizeHint() + */ + public Point computeSizeHint() { + // compute the preferred size + int x= DWT.DEFAULT; + int y= DWT.DEFAULT; + Point size= fShell.computeSize(x, y); + if (size.x > fMaxWidth) + x= fMaxWidth; + if (size.y > fMaxHeight) + y= fMaxHeight; + + // recompute using the constraints if the preferred size is larger than the constraints + if (x !is DWT.DEFAULT || y !is DWT.DEFAULT) + size= fShell.computeSize(x, y, false); + + return size; + } + + /* + * @see IInformationControl#addDisposeListener(DisposeListener) + */ + public void addDisposeListener(DisposeListener listener) { + fShell.addDisposeListener(listener); + } + + /* + * @see IInformationControl#removeDisposeListener(DisposeListener) + */ + public void removeDisposeListener(DisposeListener listener) { + fShell.removeDisposeListener(listener); + } + + /* + * @see IInformationControl#setForegroundColor(Color) + */ + public void setForegroundColor(Color foreground) { + fText.setForeground(foreground); + } + + /* + * @see IInformationControl#setBackgroundColor(Color) + */ + public void setBackgroundColor(Color background) { + fText.setBackground(background); + } + + /* + * @see IInformationControl#isFocusControl() + */ + public bool isFocusControl() { + return fShell.getDisplay().getActiveShell() is fShell; + } + + /* + * @see IInformationControl#setFocus() + */ + public void setFocus() { + fShell.forceFocus(); + fText.setFocus(); + } + + /* + * @see IInformationControl#addFocusListener(FocusListener) + */ + public void addFocusListener(FocusListener listener) { + fText.addFocusListener(listener); + } + + /* + * @see IInformationControl#removeFocusListener(FocusListener) + */ + public void removeFocusListener(FocusListener listener) { + fText.removeFocusListener(listener); + } + + /* + * @see IInformationControlExtension#hasContents() + */ + public bool hasContents() { + return fText.getCharCount() > 0; + } + + /* + * @see dwtx.jface.text.IInformationControlExtension3#computeTrim() + * @since 3.4 + */ + public Rectangle computeTrim() { + Rectangle trim= fShell.computeTrim(0, 0, 0, 0); + addInternalTrim(trim); + return trim; + } + + /** + * Adds the internal trimmings to the given trim of the shell. + * + * @param trim the shell's trim, will be updated + * @since 3.4 + */ + private void addInternalTrim(Rectangle trim) { + if (fStatusField !is null) { + trim.height+= fSeparator.computeSize(DWT.DEFAULT, DWT.DEFAULT).y; + trim.height+= fStatusField.computeSize(DWT.DEFAULT, DWT.DEFAULT).y; + } + } + + /* + * @see dwtx.jface.text.IInformationControlExtension3#getBounds() + * @since 3.4 + */ + public Rectangle getBounds() { + return fShell.getBounds(); + } + + /* + * @see dwtx.jface.text.IInformationControlExtension3#restoresLocation() + * @since 3.4 + */ + public bool restoresLocation() { + return false; + } + + /* + * @see dwtx.jface.text.IInformationControlExtension3#restoresSize() + * @since 3.4 + */ + public bool restoresSize() { + return false; + } + + /* + * @see dwtx.jface.text.IInformationControlExtension5#getInformationPresenterControlCreator() + * @since 3.4 + */ + public IInformationControlCreator getInformationPresenterControlCreator() { + return new class() IInformationControlCreator { + public IInformationControl createInformationControl(Shell parent) { + return new SourceViewerInformationControl(parent, true, fSymbolicFontName, null); + } + }; + } + + /* + * @see dwtx.jface.text.IInformationControlExtension5#containsControl(dwt.widgets.Control) + * @since 3.4 + */ + public bool containsControl(Control control) { + do { + if (control is fShell) + return true; + if ( cast(Shell)control ) + return false; + control= control.getParent(); + } while (control !is null); + return false; + } + + /* + * @see dwtx.jface.text.IInformationControlExtension5#isVisible() + * @since 3.4 + */ + public bool isVisible() { + return fShell !is null && !fShell.isDisposed() && fShell.isVisible(); + } + + /* + * @see dwtx.jface.text.IInformationControlExtension5#computeSizeConstraints(int, int) + */ + public Point computeSizeConstraints(int widthInChars, int heightInChars) { + GC gc= new GC(fText); + gc.setFont(fTextFont); + int width= gc.getFontMetrics().getAverageCharWidth(); + int height = gc.getFontMetrics().getHeight(); + gc.dispose(); + + return new Point (widthInChars * width, heightInChars * height); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/projection/images/collapsed.gif Binary file dwtx/jface/text/source/projection/images/collapsed.gif has changed diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/source/projection/images/expanded.gif Binary file dwtx/jface/text/source/projection/images/expanded.gif has changed diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/ContextTypeRegistry.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/ContextTypeRegistry.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.templates.ContextTypeRegistry; + +import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport +import dwtx.jface.text.templates.TemplateBuffer; // packageimport +import dwtx.jface.text.templates.TemplateContext; // packageimport +import dwtx.jface.text.templates.TemplateContextType; // packageimport +import dwtx.jface.text.templates.Template; // packageimport +import dwtx.jface.text.templates.TemplateVariable; // packageimport +import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport +import dwtx.jface.text.templates.TemplateException; // packageimport +import dwtx.jface.text.templates.TemplateTranslator; // packageimport +import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport +import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport +import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.templates.TemplateProposal; // packageimport +import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport +import dwtx.jface.text.templates.TextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateVariableType; // packageimport +import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + +/** + * A registry for context types. Editor implementors will usually instantiate a + * registry and configure the context types available in their editor. + *

                        + * In order to pick up templates contributed using the dwtx.ui.editors.templates + * extension point, use a ContributionContextTypeRegistry. + *

                        + * + * @since 3.0 + */ +public class ContextTypeRegistry { + + /** all known context types */ + private const Map fContextTypes; + + this(){ + fContextTypes= new LinkedHashMap(); + } + /** + * Adds a context type to the registry. If there already is a context type + * with the same ID registered, it is replaced. + * + * @param contextType the context type to add + */ + public void addContextType(TemplateContextType contextType) { + fContextTypes.put(contextType.getId(), contextType); + } + + /** + * Returns the context type if the id is valid, null otherwise. + * + * @param id the id of the context type to retrieve + * @return the context type if name is valid, null otherwise + */ + public TemplateContextType getContextType(String id) { + return cast(TemplateContextType) fContextTypes.get(id); + } + + /** + * Returns an iterator over all registered context types. + * + * @return an iterator over all registered context types + */ + public Iterator contextTypes() { + return fContextTypes.values().iterator(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/DocumentTemplateContext.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/DocumentTemplateContext.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,213 @@ +/******************************************************************************* + * 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 + * 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.text.templates.DocumentTemplateContext; + +import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport +import dwtx.jface.text.templates.TemplateBuffer; // packageimport +import dwtx.jface.text.templates.TemplateContext; // packageimport +import dwtx.jface.text.templates.TemplateContextType; // packageimport +import dwtx.jface.text.templates.Template; // packageimport +import dwtx.jface.text.templates.TemplateVariable; // packageimport +import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport +import dwtx.jface.text.templates.TemplateException; // packageimport +import dwtx.jface.text.templates.TemplateTranslator; // packageimport +import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport +import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.templates.TemplateProposal; // packageimport +import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport +import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport +import dwtx.jface.text.templates.TextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateVariableType; // packageimport +import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.Position; + +/** + * Instances of this class describe the context of a template as a region of + * a document. That region may be either specified by its offset and length, or + * by a Position which may or may not be registered with the + * document. + *

                        + * Clients may instantiate and extend this class. + *

                        + * + * @since 3.0 + */ +public class DocumentTemplateContext : TemplateContext { + + /** The text of the document. */ + private const IDocument fDocument; + /** + * The region of the document described by this context. We store a + * position since clients may specify the document region as (updateable) + * Positions. + */ + private const Position fPosition; + /** + * The original offset of this context. Will only be updated by the setter + * method. + */ + private int fOriginalOffset; + /** + * The original length of this context. Will only be updated by the setter + * method. + */ + private int fOriginalLength; + + /** + * Creates a document template context. + * + * @param type the context type + * @param document the document this context applies to + * @param offset the offset of the document region + * @param length the length of the document region + */ + public this(TemplateContextType type, IDocument document, int offset, int length) { + this(type, document, new Position(offset, length)); + } + + /** + * Creates a document template context. The supplied Position + * will be queried to compute the getStart and + * getEnd methods, which will therefore answer updated + * position data if it is registered with the document. + * + * @param type the context type + * @param document the document this context applies to + * @param position the position describing the area of the document which + * forms the template context + * @since 3.1 + */ + public this(TemplateContextType type, IDocument document, Position position) { + super(type); + + Assert.isNotNull(cast(Object)document); + Assert.isNotNull(position); + Assert.isTrue(position.getOffset() <= document.getLength()); + + fDocument= document; + fPosition= position; + fOriginalOffset= fPosition.getOffset(); + fOriginalLength= fPosition.getLength(); + } + + /** + * Returns the document. + * + * @return the document + */ + public IDocument getDocument() { + return fDocument; + } + + /** + * Returns the completion offset within the string of the context. + * + * @return the completion offset within the string of the context + */ + public int getCompletionOffset() { + return fOriginalOffset; + } + + /** + * Sets the completion offset. + * + * @param newOffset the new completion offset + */ + protected void setCompletionOffset(int newOffset) { + fOriginalOffset= newOffset; + fPosition.setOffset(newOffset); + } + + /** + * Returns the completion length within the string of the context. + * + * @return the completion length within the string of the context + */ + public int getCompletionLength() { + return fOriginalLength; + } + + /** + * Sets the completion length. + * + * @param newLength the new completion length + */ + protected void setCompletionLength(int newLength) { + fOriginalLength= newLength; + fPosition.setLength(newLength); + } + + /** + * Returns the keyword which triggered template insertion. + * + * @return the keyword which triggered template insertion + */ + public String getKey() { + int offset= getStart(); + int length= getEnd() - offset; + try { + return fDocument.get(offset, length); + } catch (BadLocationException e) { + return ""; //$NON-NLS-1$ + } + } + + /** + * Returns the beginning offset of the keyword. + * + * @return the beginning offset of the keyword + */ + public int getStart() { + return fPosition.getOffset(); + } + + /** + * Returns the end offset of the keyword. + * + * @return the end offset of the keyword + */ + public int getEnd() { + return fPosition.getOffset() + fPosition.getLength(); + } + + /* + * @see dwtx.jface.text.templates.TemplateContext#canEvaluate(dwtx.jface.text.templates.Template) + */ + public bool canEvaluate(Template template_) { + return true; + } + + /* + * @see dwtx.jface.text.templates.TemplateContext#evaluate(dwtx.jface.text.templates.Template) + */ + public TemplateBuffer evaluate(Template template_) { + if (!canEvaluate(template_)) + return null; + + TemplateTranslator translator= new TemplateTranslator(); + TemplateBuffer buffer= translator.translate(template_); + + getContextType().resolve(buffer, this); + + return buffer; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/GlobalTemplateVariables.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/GlobalTemplateVariables.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,203 @@ +/******************************************************************************* + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Sebastian Davids: sdavids@gmx.de - see bug 25376 + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.text.templates.GlobalTemplateVariables; + +import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport +import dwtx.jface.text.templates.TemplateBuffer; // packageimport +import dwtx.jface.text.templates.TemplateContext; // packageimport +import dwtx.jface.text.templates.TemplateContextType; // packageimport +import dwtx.jface.text.templates.Template; // packageimport +import dwtx.jface.text.templates.TemplateVariable; // packageimport +import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport +import dwtx.jface.text.templates.TemplateException; // packageimport +import dwtx.jface.text.templates.TemplateTranslator; // packageimport +import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport +import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.templates.TemplateProposal; // packageimport +import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport +import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport +import dwtx.jface.text.templates.TextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateVariableType; // packageimport +import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport + + +import dwt.dwthelper.utils; + +// import com.ibm.icu.text.DateFormat; +// import com.ibm.icu.util.Calendar; + +/** + * Global variables which are available in any context. + *

                        + * Clients may instantiate the classes contained within this class. + *

                        + * + * @since 3.0 + */ +public class GlobalTemplateVariables { + + /** The type of the selection variables. */ + public static const String SELECTION= "selection"; //$NON-NLS-1$ + + /** + * The cursor variable determines the cursor placement after template edition. + */ + public static class Cursor : SimpleTemplateVariableResolver { + + /** Name of the cursor variable, value= {@value} */ + public static const String NAME= "cursor"; //$NON-NLS-1$ + + /** + * Creates a new cursor variable + */ + public this() { + super(NAME, TextTemplateMessages.getString("GlobalVariables.variable.description.cursor")); //$NON-NLS-1$ + setEvaluationString(""); //$NON-NLS-1$ + } + } + + /** + * The word selection variable determines templates that work on a full + * lines selection. + */ + public static class WordSelection : SimpleTemplateVariableResolver { + + /** Name of the word selection variable, value= {@value} */ + public static const String NAME= "word_selection"; //$NON-NLS-1$ + + /** + * Creates a new word selection variable + */ + public this() { + super(NAME, TextTemplateMessages.getString("GlobalVariables.variable.description.selectedWord")); //$NON-NLS-1$ + } + protected String resolve(TemplateContext context) { + String selection= context.getVariable(SELECTION); + if (selection is null) + return ""; //$NON-NLS-1$ + return selection; + } + } + + /** + * The line selection variable determines templates that work on selected + * lines. + */ + public static class LineSelection : SimpleTemplateVariableResolver { + + /** Name of the line selection variable, value= {@value} */ + public static const String NAME= "line_selection"; //$NON-NLS-1$ + + /** + * Creates a new line selection variable + */ + public this() { + super(NAME, TextTemplateMessages.getString("GlobalVariables.variable.description.selectedLines")); //$NON-NLS-1$ + } + protected String resolve(TemplateContext context) { + String selection= context.getVariable(SELECTION); + if (selection is null) + return ""; //$NON-NLS-1$ + return selection; + } + } + + /** + * The dollar variable inserts an escaped dollar symbol. + */ + public static class Dollar : SimpleTemplateVariableResolver { + /** + * Creates a new dollar variable + */ + public this() { + super("dollar", TextTemplateMessages.getString("GlobalVariables.variable.description.dollar")); //$NON-NLS-1$ //$NON-NLS-2$ + setEvaluationString("$"); //$NON-NLS-1$ + } + } + + /** + * The date variable evaluates to the current date. + */ + public static class Date : SimpleTemplateVariableResolver { + /** + * Creates a new date variable + */ + public this() { + super("date", TextTemplateMessages.getString("GlobalVariables.variable.description.date")); //$NON-NLS-1$ //$NON-NLS-2$ + } + protected String resolve(TemplateContext context) { + implMissing(__FILE__,__LINE__); + return null; + //return DateFormat.getDateInstance().format(new java.util.Date()); + } + } + + /** + * The year variable evaluates to the current year. + */ + public static class Year : SimpleTemplateVariableResolver { + /** + * Creates a new year variable + */ + public this() { + super("year", TextTemplateMessages.getString("GlobalVariables.variable.description.year")); //$NON-NLS-1$ //$NON-NLS-2$ + } + protected String resolve(TemplateContext context) { + implMissing(__FILE__,__LINE__); + return null; + //return Integer.toString(Calendar.getInstance().get(Calendar.YEAR)); + } + } + + /** + * The time variable evaluates to the current time. + */ + public static class Time : SimpleTemplateVariableResolver { + /** + * Creates a new time variable + */ + public this() { + super("time", TextTemplateMessages.getString("GlobalVariables.variable.description.time")); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * {@inheritDoc} + */ + protected String resolve(TemplateContext context) { + implMissing(__FILE__,__LINE__); + return null; + //return DateFormat.getTimeInstance().format(new java.util.Date()); + } + } + + /** + * The user variable evaluates to the current user. + */ + public static class User : SimpleTemplateVariableResolver { + /** + * Creates a new user name variable + */ + public this() { + super("user", TextTemplateMessages.getString("GlobalVariables.variable.description.user")); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * {@inheritDoc} + */ + protected String resolve(TemplateContext context) { + return System.getProperty("user.name"); //$NON-NLS-1$ + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/InclusivePositionUpdater.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/InclusivePositionUpdater.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.templates.InclusivePositionUpdater; + +import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport +import dwtx.jface.text.templates.TemplateBuffer; // packageimport +import dwtx.jface.text.templates.TemplateContext; // packageimport +import dwtx.jface.text.templates.TemplateContextType; // packageimport +import dwtx.jface.text.templates.Template; // packageimport +import dwtx.jface.text.templates.TemplateVariable; // packageimport +import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport +import dwtx.jface.text.templates.TemplateException; // packageimport +import dwtx.jface.text.templates.TemplateTranslator; // packageimport +import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport +import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport +import dwtx.jface.text.templates.TemplateProposal; // packageimport +import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport +import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport +import dwtx.jface.text.templates.TextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateVariableType; // packageimport +import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.BadPositionCategoryException; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IPositionUpdater; +import dwtx.jface.text.Position; + +/** + * Position updater that takes any change in [position.offset, position.offset + position.length] as + * belonging to the position. + * + * @since 3.0 + */ +class InclusivePositionUpdater : IPositionUpdater { + + /** The position category. */ + private const String fCategory; + + /** + * Creates a new updater for the given category. + * + * @param category the new category. + */ + public this(String category) { + fCategory= category; + } + + /* + * @see dwtx.jface.text.IPositionUpdater#update(dwtx.jface.text.DocumentEvent) + */ + public void update(DocumentEvent event) { + + int eventOffset= event.getOffset(); + int eventOldLength= event.getLength(); + int eventNewLength= event.getText() is null ? 0 : event.getText().length(); + int deltaLength= eventNewLength - eventOldLength; + + try { + Position[] positions= event.getDocument().getPositions(fCategory); + + for (int i= 0; i !is positions.length; i++) { + + Position position= positions[i]; + + if (position.isDeleted()) + continue; + + int offset= position.getOffset(); + int length= position.getLength(); + int end= offset + length; + + if (offset > eventOffset + eventOldLength) + // position comes way + // after change - shift + position.setOffset(offset + deltaLength); + else if (end < eventOffset) { + // position comes way before change - + // leave alone + } else if (offset <= eventOffset && end >= eventOffset + eventOldLength) { + // event completely internal to the position - adjust length + position.setLength(length + deltaLength); + } else if (offset < eventOffset) { + // event extends over end of position - adjust length + int newEnd= eventOffset + eventNewLength; + position.setLength(newEnd - offset); + } else if (end > eventOffset + eventOldLength) { + // event extends from before position into it - adjust offset + // and length + // offset becomes end of event, length adjusted accordingly + // we want to recycle the overlapping part + position.setOffset(eventOffset); + int deleted= eventOffset + eventOldLength - offset; + position.setLength(length - deleted + eventNewLength); + } else { + // event consumes the position - delete it + position.delete_(); + } + } + } catch (BadPositionCategoryException e) { + // ignore and return + } + } + + /** + * Returns the position category. + * + * @return the position category + */ + public String getCategory() { + return fCategory; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/JFaceTextTemplateMessages.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/JFaceTextTemplateMessages.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,67 @@ +/******************************************************************************* + * 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 + * 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.text.templates.JFaceTextTemplateMessages; + +import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport +import dwtx.jface.text.templates.TemplateBuffer; // packageimport +import dwtx.jface.text.templates.TemplateContext; // packageimport +import dwtx.jface.text.templates.TemplateContextType; // packageimport +import dwtx.jface.text.templates.Template; // packageimport +import dwtx.jface.text.templates.TemplateVariable; // packageimport +import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport +import dwtx.jface.text.templates.TemplateException; // packageimport +import dwtx.jface.text.templates.TemplateTranslator; // packageimport +import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport +import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport +import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.templates.TemplateProposal; // packageimport +import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport +import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport +import dwtx.jface.text.templates.TextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateVariableType; // packageimport +import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.dwthelper.ResourceBundle; +import dwtx.dwtxhelper.MessageFormat; + +/** + * @since 3.0 + */ +class JFaceTextTemplateMessages { + +// private static const String RESOURCE_BUNDLE= JFaceTextTemplateMessages.classinfo.getName(); + private static ResourceBundle fgResourceBundle;//= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + static this() { + fgResourceBundle = ResourceBundle.getBundle( + getImportData!("dwtx.jface.text.templates.JFaceTextTemplateMessages.properties")); + } + + private this() { + } + + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return '!' ~ key ~ '!'; + } + } + + public static String getFormattedString(String key, Object[] args... ) { + return MessageFormat.format(getString(key), args); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/PositionBasedCompletionProposal.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/PositionBasedCompletionProposal.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,194 @@ +/******************************************************************************* + * 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 + * 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.text.templates.PositionBasedCompletionProposal; + +import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport +import dwtx.jface.text.templates.TemplateBuffer; // packageimport +import dwtx.jface.text.templates.TemplateContext; // packageimport +import dwtx.jface.text.templates.TemplateContextType; // packageimport +import dwtx.jface.text.templates.Template; // packageimport +import dwtx.jface.text.templates.TemplateVariable; // packageimport +import dwtx.jface.text.templates.TemplateException; // packageimport +import dwtx.jface.text.templates.TemplateTranslator; // packageimport +import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport +import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport +import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.templates.TemplateProposal; // packageimport +import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport +import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport +import dwtx.jface.text.templates.TextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateVariableType; // packageimport +import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport + +import dwt.dwthelper.utils; + + + + + +import dwt.graphics.Image; +import dwt.graphics.Point; +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.Position; +import dwtx.jface.text.contentassist.ICompletionProposal; +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; +import dwtx.jface.text.contentassist.IContextInformation; + + +/** + * A position based completion proposal. + * + * @since 3.0 + */ +final class PositionBasedCompletionProposal : ICompletionProposal, ICompletionProposalExtension2 { + + /** The string to be displayed in the completion proposal popup */ + private String fDisplayString; + /** The replacement string */ + private String fReplacementString; + /** The replacement position. */ + private Position fReplacementPosition; + /** The cursor position after this proposal has been applied */ + private int fCursorPosition; + /** The image to be displayed in the completion proposal popup */ + private Image fImage; + /** The context information of this proposal */ + private IContextInformation fContextInformation; + /** The additional info of this proposal */ + private String fAdditionalProposalInfo; + + /** + * Creates a new completion proposal based on the provided information. The replacement string is + * considered being the display string too. All remaining fields are set to null. + * + * @param replacementString the actual string to be inserted into the document + * @param replacementPosition the position of the text to be replaced + * @param cursorPosition the position of the cursor following the insert relative to replacementOffset + */ + public this(String replacementString, Position replacementPosition, int cursorPosition) { + this(replacementString, replacementPosition, cursorPosition, null, null, null, null); + } + + /** + * Creates a new completion proposal. All fields are initialized based on the provided information. + * + * @param replacementString the actual string to be inserted into the document + * @param replacementPosition the position of the text to be replaced + * @param cursorPosition the position of the cursor following the insert relative to replacementOffset + * @param image the image to display for this proposal + * @param displayString the string to be displayed for the proposal + * @param contextInformation the context information associated with this proposal + * @param additionalProposalInfo the additional information associated with this proposal + */ + public this(String replacementString, Position replacementPosition, int cursorPosition, Image image, String displayString, IContextInformation contextInformation, String additionalProposalInfo) { + Assert.isNotNull(replacementString); + Assert.isTrue(replacementPosition !is null); + + fReplacementString= replacementString; + fReplacementPosition= replacementPosition; + fCursorPosition= cursorPosition; + fImage= image; + fDisplayString= displayString; + fContextInformation= contextInformation; + fAdditionalProposalInfo= additionalProposalInfo; + } + + /* + * @see ICompletionProposal#apply(IDocument) + */ + public void apply(IDocument document) { + try { + document.replace(fReplacementPosition.getOffset(), fReplacementPosition.getLength(), fReplacementString); + } catch (BadLocationException x) { + // ignore + } + } + + /* + * @see ICompletionProposal#getSelection(IDocument) + */ + public Point getSelection(IDocument document) { + return new Point(fReplacementPosition.getOffset() + fCursorPosition, 0); + } + + /* + * @see ICompletionProposal#getContextInformation() + */ + public IContextInformation getContextInformation() { + return fContextInformation; + } + + /* + * @see ICompletionProposal#getImage() + */ + public Image getImage() { + return fImage; + } + + /* + * @see dwtx.jface.text.contentassist.ICompletionProposal#getDisplayString() + */ + public String getDisplayString() { + if (fDisplayString !is null) + return fDisplayString; + return fReplacementString; + } + + /* + * @see ICompletionProposal#getAdditionalProposalInfo() + */ + public String getAdditionalProposalInfo() { + return fAdditionalProposalInfo; + } + + /* + * @see dwtx.jface.text.contentassist.ICompletionProposalExtension2#apply(dwtx.jface.text.ITextViewer, char, int, int) + */ + public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) { + apply(viewer.getDocument()); + } + + /* + * @see dwtx.jface.text.contentassist.ICompletionProposalExtension2#selected(dwtx.jface.text.ITextViewer, bool) + */ + public void selected(ITextViewer viewer, bool smartToggle) { + } + + /* + * @see dwtx.jface.text.contentassist.ICompletionProposalExtension2#unselected(dwtx.jface.text.ITextViewer) + */ + public void unselected(ITextViewer viewer) { + } + + /* + * @see dwtx.jface.text.contentassist.ICompletionProposalExtension2#validate(dwtx.jface.text.IDocument, int, dwtx.jface.text.DocumentEvent) + */ + public bool validate(IDocument document, int offset, DocumentEvent event) { + try { + String content= document.get(fReplacementPosition.getOffset(), offset - fReplacementPosition.getOffset()); + if (fReplacementString.startsWith(content)) + return true; + } catch (BadLocationException e) { + // ignore concurrently modified document + } + return false; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/SimpleTemplateVariableResolver.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/SimpleTemplateVariableResolver.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.templates.SimpleTemplateVariableResolver; + +import dwtx.jface.text.templates.TemplateBuffer; // packageimport +import dwtx.jface.text.templates.TemplateContext; // packageimport +import dwtx.jface.text.templates.TemplateContextType; // packageimport +import dwtx.jface.text.templates.Template; // packageimport +import dwtx.jface.text.templates.TemplateVariable; // packageimport +import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport +import dwtx.jface.text.templates.TemplateException; // packageimport +import dwtx.jface.text.templates.TemplateTranslator; // packageimport +import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport +import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport +import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.templates.TemplateProposal; // packageimport +import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport +import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport +import dwtx.jface.text.templates.TextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateVariableType; // packageimport +import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * A simple template variable resolver, which always evaluates to a defined string. + *

                        + * Clients may instantiate and extend this class. + *

                        + * + * @since 3.0 + */ +public class SimpleTemplateVariableResolver : TemplateVariableResolver { + + /** The string to which this variable evaluates. */ + private String fEvaluationString; + + /* + * @see TemplateVariableResolver#TemplateVariableResolver(String, String) + */ + protected this(String type, String description) { + super(type, description); + } + + /** + * Sets the string to which this variable evaluates. + * + * @param evaluationString the evaluation string, may be null. + */ + public final void setEvaluationString(String evaluationString) { + fEvaluationString= evaluationString; + } + + /* + * @see TemplateVariableResolver#evaluate(TemplateContext) + */ + protected String resolve(TemplateContext context) { + return fEvaluationString; + } + + /** + * Returns always true, since simple variables are normally + * unambiguous. + * + * @param context {@inheritDoc} + * @return true + */ + protected bool isUnambiguous(TemplateContext context) { + return true; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/Template.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/Template.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,241 @@ +/******************************************************************************* + * 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 + * 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.text.templates.Template; + +import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport +import dwtx.jface.text.templates.TemplateBuffer; // packageimport +import dwtx.jface.text.templates.TemplateContext; // packageimport +import dwtx.jface.text.templates.TemplateContextType; // packageimport +import dwtx.jface.text.templates.TemplateVariable; // packageimport +import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport +import dwtx.jface.text.templates.TemplateException; // packageimport +import dwtx.jface.text.templates.TemplateTranslator; // packageimport +import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport +import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport +import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.templates.TemplateProposal; // packageimport +import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport +import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport +import dwtx.jface.text.templates.TextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateVariableType; // packageimport +import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.core.runtime.Assert; + + +/** + * A template consisting of a name and a pattern. + *

                        + * Clients may instantiate this class. May become final in the future. + *

                        + * @since 3.0 + * @noextend This class is not intended to be subclassed by clients. + */ +public class Template { + + private alias .toHash toHash; + private alias .equals equals; + + /** The name of this template */ + private /*final*/ String fName; + /** A description of this template */ + private /*final*/ String fDescription; + /** The name of the context type of this template */ + private /*final*/ String fContextTypeId; + /** The template pattern. */ + private /*final*/ String fPattern; + /** + * The auto insertable property. + * @since 3.1 + */ + private const bool fIsAutoInsertable; + + /** + * Creates an empty template. + */ + public this() { + this("", "", "", "", true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + + /** + * Creates a copy of a template. + * + * @param template the template to copy + */ + public this(Template template_) { + this(template_.getName(), template_.getDescription(), template_.getContextTypeId(), template_.getPattern(), template_.isAutoInsertable()); + } + + /** + * Creates a template. + * + * @param name the name of the template + * @param description the description of the template + * @param contextTypeId the id of the context type in which the template can be applied + * @param pattern the template pattern + * @deprecated as of 3.1 replaced by {@link #Template(String, String, String, String, bool)} + */ + public this(String name, String description, String contextTypeId, String pattern) { + this(name, description, contextTypeId, pattern, true); // templates are auto insertable per default + } + + /** + * Creates a template. + * + * @param name the name of the template + * @param description the description of the template + * @param contextTypeId the id of the context type in which the template can be applied + * @param pattern the template pattern + * @param isAutoInsertable the auto insertable property of the template + * @since 3.1 + */ + public this(String name, String description, String contextTypeId, String pattern, bool isAutoInsertable) { + Assert.isNotNull(description); + fDescription= description; + fName= name; + Assert.isNotNull(contextTypeId); + fContextTypeId= contextTypeId; + fPattern= pattern; + fIsAutoInsertable= isAutoInsertable; + } + + /* + * @see Object#hashCode() + */ + public override hash_t toHash() { + return fName.toHash() ^ fPattern.toHash() ^ fContextTypeId.toHash(); + } + + /** + * Sets the description of the template. + * + * @param description the new description + * @deprecated Templates should never be modified + */ + public void setDescription(String description) { + Assert.isNotNull(description); + fDescription= description; + } + + /** + * Returns the description of the template. + * + * @return the description of the template + */ + public String getDescription() { + return fDescription; + } + + /** + * Sets the name of the context type in which the template can be applied. + * + * @param contextTypeId the new context type name + * @deprecated Templates should never be modified + */ + public void setContextTypeId(String contextTypeId) { + Assert.isNotNull(contextTypeId); + fContextTypeId= contextTypeId; + } + + /** + * Returns the id of the context type in which the template can be applied. + * + * @return the id of the context type in which the template can be applied + */ + public String getContextTypeId() { + return fContextTypeId; + } + + /** + * Sets the name of the template. + * + * @param name the name of the template + * @deprecated Templates should never be modified + */ + public void setName(String name) { + fName= name; + } + + /** + * Returns the name of the template. + * + * @return the name of the template + */ + public String getName() { + return fName; + } + + /** + * Sets the pattern of the template. + * + * @param pattern the new pattern of the template + * @deprecated Templates should never be modified + */ + public void setPattern(String pattern) { + fPattern= pattern; + } + + /** + * Returns the template pattern. + * + * @return the template pattern + */ + public String getPattern() { + return fPattern; + } + + /** + * Returns true if template is enabled and matches the context, + * false otherwise. + * + * @param prefix the prefix (e.g. inside a document) to match + * @param contextTypeId the context type id to match + * @return true if template is enabled and matches the context, + * false otherwise + */ + public bool matches(String prefix, String contextTypeId) { + return fContextTypeId.equals(contextTypeId); + } + + /* + * @see java.lang.Object#equals(java.lang.Object) + */ + public bool equals(Object o) { + if (!( cast(Template)o )) + return false; + + Template t= cast(Template) o; + if (t is this) + return true; + + return t.fName.equals(fName) + && t.fPattern.equals(fPattern) + && t.fContextTypeId.equals(fContextTypeId) + && t.fDescription.equals(fDescription) + && t.fIsAutoInsertable is fIsAutoInsertable; + } + + /** + * Returns the auto insertable property of the template. + * + * @return the auto insertable property of the template + * @since 3.1 + */ + public bool isAutoInsertable() { + return fIsAutoInsertable; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/TemplateBuffer.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/TemplateBuffer.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,115 @@ +/******************************************************************************* + * 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 + * 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.text.templates.TemplateBuffer; + +import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport +import dwtx.jface.text.templates.TemplateContext; // packageimport +import dwtx.jface.text.templates.TemplateContextType; // packageimport +import dwtx.jface.text.templates.Template; // packageimport +import dwtx.jface.text.templates.TemplateVariable; // packageimport +import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport +import dwtx.jface.text.templates.TemplateException; // packageimport +import dwtx.jface.text.templates.TemplateTranslator; // packageimport +import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport +import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport +import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.templates.TemplateProposal; // packageimport +import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport +import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport +import dwtx.jface.text.templates.TextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateVariableType; // packageimport +import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.core.runtime.Assert; + +/** + * A template buffer is a container for a string and variables. + *

                        + * Clients may instantiate this class. + *

                        + * + * @since 3.0 + */ +public final class TemplateBuffer { + + /** The string of the template buffer */ + private String fString; + /** The variable positions of the template buffer */ + private TemplateVariable[] fVariables; + + /** + * Creates a template buffer. + * + * @param string the string + * @param variables the variable positions + */ + public this(String string, TemplateVariable[] variables) { + setContent(string, variables); + } + + /** + * Sets the content of the template buffer. + * + * @param string the string + * @param variables the variable positions + */ + public final void setContent(String string, TemplateVariable[] variables) { + Assert.isNotNull(string); +// Assert.isNotNull(variables); + + // XXX assert non-overlapping variable properties + + fString= string; + fVariables= copy(variables); + } + + /** + * Returns a copy of the given array. + * + * @param array the array to be copied + * @return a copy of the given array or null when array is null + * @since 3.1 + */ + private static TemplateVariable[] copy(TemplateVariable[] array) { + if (array !is null) { + TemplateVariable[] copy= new TemplateVariable[array.length]; + System.arraycopy(array, 0, copy, 0, array.length); + return copy; + } + return null; + } + + /** + * Returns the string of the template buffer. + * + * @return the string representation of the template buffer + */ + public final String getString() { + return fString; + } + + /** + * Returns the variable positions of the template buffer. The returned array is + * owned by this variable and must not be modified. + * + * @return the variable positions of the template buffer + */ + public final TemplateVariable[] getVariables() { + return fVariables; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/TemplateCompletionProcessor.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/TemplateCompletionProcessor.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,284 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.templates.TemplateCompletionProcessor; + +import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport +import dwtx.jface.text.templates.TemplateBuffer; // packageimport +import dwtx.jface.text.templates.TemplateContext; // packageimport +import dwtx.jface.text.templates.TemplateContextType; // packageimport +import dwtx.jface.text.templates.Template; // packageimport +import dwtx.jface.text.templates.TemplateVariable; // packageimport +import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport +import dwtx.jface.text.templates.TemplateException; // packageimport +import dwtx.jface.text.templates.TemplateTranslator; // packageimport +import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport +import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport +import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.templates.TemplateProposal; // packageimport +import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport +import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateVariableType; // packageimport +import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + + +import dwt.graphics.Image; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextSelection; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.Region; +import dwtx.jface.text.contentassist.ICompletionProposal; +import dwtx.jface.text.contentassist.IContentAssistProcessor; +import dwtx.jface.text.contentassist.IContextInformation; +import dwtx.jface.text.contentassist.IContextInformationValidator; + + +/** + * A completion processor that computes template proposals. Subclasses need to + * provide implementations for {@link #getTemplates(String)}, + * {@link #getContextType(ITextViewer, IRegion)} and {@link #getImage(Template)}. + * + * @since 3.0 + */ +public abstract class TemplateCompletionProcessor : IContentAssistProcessor { + + private static final class ProposalComparator : Comparator { + public int compare(Object o1, Object o2) { + return (cast(TemplateProposal) o2).getRelevance() - (cast(TemplateProposal) o1).getRelevance(); + } + } + + private static Comparator fgProposalComparator_; + private static Comparator fgProposalComparator(){ + if(fgProposalComparator_ is null ) { + synchronized( TemplateCompletionProcessor.classinfo ){ + if(fgProposalComparator_ is null ) { + fgProposalComparator_ = new ProposalComparator(); + } + } + } + return fgProposalComparator_; + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(dwtx.jface.text.ITextViewer, + * int) + */ + public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) { + + ITextSelection selection= cast(ITextSelection) viewer.getSelectionProvider().getSelection(); + + // adjust offset to end of normalized selection + if (selection.getOffset() is offset) + offset= selection.getOffset() + selection.getLength(); + + String prefix= extractPrefix(viewer, offset); + Region region= new Region(offset - prefix.length(), prefix.length()); + TemplateContext context= createContext(viewer, region); + if (context is null) + return new ICompletionProposal[0]; + + context.setVariable("selection", selection.getText()); // name of the selection variables {line, word}_selection //$NON-NLS-1$ + + Template[] templates= getTemplates(context.getContextType().getId()); + + List matches= new ArrayList(); + for (int i= 0; i < templates.length; i++) { + Template template_= templates[i]; + try { + context.getContextType().validate(template_.getPattern()); + } catch (TemplateException e) { + continue; + } + if (template_.matches(prefix, context.getContextType().getId())) + matches.add( cast(Object) createProposal(template_, context, cast(IRegion) region, getRelevance(template_, prefix))); + } + + Collections.sort(matches, fgProposalComparator); + + return arraycast!(ICompletionProposal)( matches.toArray()); + } + + /** + * Creates a new proposal. + *

                        + * Forwards to {@link #createProposal(Template, TemplateContext, IRegion, int)}. + * Do neither call nor override. + *

                        + * + * @param template the template to be applied by the proposal + * @param context the context for the proposal + * @param region the region the proposal applies to + * @param relevance the relevance of the proposal + * @return a new ICompletionProposal for + * template + * @deprecated use the version specifying IRegion as third parameter + * @since 3.1 + */ + protected ICompletionProposal createProposal(Template template_, TemplateContext context, Region region, int relevance) { + return createProposal(template_, context, cast(IRegion) region, relevance); + } + + /** + * Creates a new proposal. + *

                        + * The default implementation returns an instance of + * {@link TemplateProposal}. Subclasses may replace this method to provide + * their own implementations. + *

                        + * + * @param template the template to be applied by the proposal + * @param context the context for the proposal + * @param region the region the proposal applies to + * @param relevance the relevance of the proposal + * @return a new ICompletionProposal for + * template + */ + protected ICompletionProposal createProposal(Template template_, TemplateContext context, IRegion region, int relevance) { + return new TemplateProposal(template_, context, region, getImage(template_), relevance); + } + + /** + * Returns the templates valid for the context type specified by contextTypeId. + * + * @param contextTypeId the context type id + * @return the templates valid for this context type id + */ + protected abstract Template[] getTemplates(String contextTypeId); + + /** + * Creates a concrete template context for the given region in the document. This involves finding out which + * context type is valid at the given location, and then creating a context of this type. The default implementation + * returns a DocumentTemplateContext for the context type at the given location. + * + * @param viewer the viewer for which the context is created + * @param region the region into document for which the context is created + * @return a template context that can handle template insertion at the given location, or null + */ + protected TemplateContext createContext(ITextViewer viewer, IRegion region) { + TemplateContextType contextType= getContextType(viewer, region); + if (contextType !is null) { + IDocument document= viewer.getDocument(); + return new DocumentTemplateContext(contextType, document, region.getOffset(), region.getLength()); + } + return null; + } + + /** + * Returns the context type that can handle template insertion at the given region + * in the viewer's document. + * + * @param viewer the text viewer + * @param region the region into the document displayed by viewer + * @return the context type that can handle template expansion for the given location, or null if none exists + */ + protected abstract TemplateContextType getContextType(ITextViewer viewer, IRegion region); + + /** + * Returns the relevance of a template given a prefix. The default + * implementation returns a number greater than zero if the template name + * starts with the prefix, and zero otherwise. + * + * @param template the template to compute the relevance for + * @param prefix the prefix after which content assist was requested + * @return the relevance of template + * @see #extractPrefix(ITextViewer, int) + */ + protected int getRelevance(Template template_, String prefix) { + if (template_.getName().startsWith(prefix)) + return 90; + return 0; + } + + /** + * Heuristically extracts the prefix used for determining template relevance + * from the viewer's document. The default implementation returns the String from + * offset backwards that forms a java identifier. + * + * @param viewer the viewer + * @param offset offset into document + * @return the prefix to consider + * @see #getRelevance(Template, String) + */ + protected String extractPrefix(ITextViewer viewer, int offset) { + int i= offset; + IDocument document= viewer.getDocument(); + if (i > document.getLength()) + return ""; //$NON-NLS-1$ + + try { + while (i > 0) { + char ch= document.getChar(i - 1); + if (!Character.isJavaIdentifierPart(ch)) + break; + i--; + } + + return document.get(i, offset - i); + } catch (BadLocationException e) { + return ""; //$NON-NLS-1$ + } + } + + /** + * Returns the image to be used for the proposal for template. + * + * @param template the template for which an image should be returned + * @return the image for template + */ + protected abstract Image getImage(Template template_); + + /* + * @see dwtx.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(dwtx.jface.text.ITextViewer, int) + */ + public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) { + return null; + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistProcessor#getCompletionProposalAutoActivationCharacters() + */ + public char[] getCompletionProposalAutoActivationCharacters() { + return null; + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistProcessor#getContextInformationAutoActivationCharacters() + */ + public char[] getContextInformationAutoActivationCharacters() { + return null; + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistProcessor#getErrorMessage() + */ + public String getErrorMessage() { + return null; + } + + /* + * @see dwtx.jface.text.contentassist.IContentAssistProcessor#getContextInformationValidator() + */ + public IContextInformationValidator getContextInformationValidator() { + return null; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/TemplateContext.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/TemplateContext.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.templates.TemplateContext; + +import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport +import dwtx.jface.text.templates.TemplateBuffer; // packageimport +import dwtx.jface.text.templates.TemplateContextType; // packageimport +import dwtx.jface.text.templates.Template; // packageimport +import dwtx.jface.text.templates.TemplateVariable; // packageimport +import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport +import dwtx.jface.text.templates.TemplateException; // packageimport +import dwtx.jface.text.templates.TemplateTranslator; // packageimport +import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport +import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport +import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.templates.TemplateProposal; // packageimport +import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport +import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport +import dwtx.jface.text.templates.TextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateVariableType; // packageimport +import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + +import dwtx.jface.text.BadLocationException; + +/** + * Provides the context for a Template being resolved. Keeps track + * of resolved variables. + *

                        + * Clients may extend this class. + *

                        + * + * @since 3.0 + */ +public abstract class TemplateContext { + + /** The context type of this context */ + private const TemplateContextType fContextType; + /** Additional variables. */ + private const Map fVariables; + /** A flag to indicate that the context should not be modified. */ + private bool fReadOnly; + + /** + * Creates a template context of a particular context type. + * + * @param contextType the context type of this context + */ + protected this(TemplateContextType contextType) { + fVariables= new HashMap(); + fContextType= contextType; + fReadOnly= true; + } + + /** + * Returns the context type of this context. + * + * @return the context type of this context + */ + public TemplateContextType getContextType() { + return fContextType; + } + + /** + * Sets or clears the read-only flag. + * + * @param readOnly the new read-only state + */ + public void setReadOnly(bool readOnly) { + fReadOnly= readOnly; + } + + /** + * Returns true if the receiver is read-only, false otherwise. + * + * @return true if the receiver is read-only, false otherwise + */ + public bool isReadOnly() { + return fReadOnly; + } + + /** + * Defines the value of a variable. + * + * @param name the name of the variable + * @param value the value of the variable, null to un-define a variable + */ + public void setVariable(String name, String value) { + fVariables.put(name, value); + } + + /** + * Returns the value of a defined variable. + * + * @param name the name of the variable + * @return returns the value of the variable, null if the variable was not defined + */ + public String getVariable(String name) { + return stringcast( fVariables.get(name)); + } + + /** + * Evaluates the template in this context and returns a template buffer. + *

                        + * Evaluation means translating the template into a TemplateBuffer, + * resolving the defined variables in this context and possibly formatting + * the resolved buffer.

                        + * + * @param template the template to evaluate + * @return returns the buffer with the evaluated template or null if the buffer could not be created + * @throws BadLocationException if evaluation fails due to concurrently changed documents etc. + * @throws TemplateException if the template specification is not valid + */ + public abstract TemplateBuffer evaluate(Template template_); + + /** + * Tests if the specified template can be evaluated in this context. + *

                        Examples are templates defined for a different context (e.g. a javadoc + * template cannot be evaluated in Java context).

                        + * + * @param template the Template to check + * @return true if template can be evaluated + * in this context, false otherwise + */ + public abstract bool canEvaluate(Template template_); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/TemplateContextType.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/TemplateContextType.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,325 @@ +/******************************************************************************* + * 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 + * 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.text.templates.TemplateContextType; + +import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport +import dwtx.jface.text.templates.TemplateBuffer; // packageimport +import dwtx.jface.text.templates.TemplateContext; // packageimport +import dwtx.jface.text.templates.Template; // packageimport +import dwtx.jface.text.templates.TemplateVariable; // packageimport +import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport +import dwtx.jface.text.templates.TemplateException; // packageimport +import dwtx.jface.text.templates.TemplateTranslator; // packageimport +import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport +import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport +import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.templates.TemplateProposal; // packageimport +import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport +import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport +import dwtx.jface.text.templates.TextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateVariableType; // packageimport +import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + + + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.Document; +import dwtx.jface.text.IDocument; +import dwtx.text.edits.MalformedTreeException; +import dwtx.text.edits.MultiTextEdit; +import dwtx.text.edits.RangeMarker; +import dwtx.text.edits.ReplaceEdit; +import dwtx.text.edits.TextEdit; + + +/** + * A context type defines a context within which templates are resolved. It + * stores a number of TemplateVariableResolvers. A + * TemplateBuffer can be resolved in a + * TemplateContext using the + * {@link #resolve(TemplateBuffer, TemplateContext)} method. + *

                        + * Clients may extend this class. + *

                        + * + * @since 3.0 + */ +public class TemplateContextType { + + /** The id of the context type. */ + private /* final */ String fId= null; + + /** Variable resolvers used by this content type. */ + private const Map fResolvers; + + /** The name of the context type. */ + private String fName= null; + + /** + * Creates a context type with an identifier. The identifier must be unique, + * a qualified name is suggested. The id is also used as name. + * + * @param id the unique identifier of the context type + */ + public this(String id) { + this(id, id); + } + + /** + * Creates a context type with an identifier. The identifier must be unique, a qualified name is suggested. + * + * @param id the unique identifier of the context type + * @param name the name of the context type + */ + public this(String id, String name) { + fResolvers= new HashMap(); + + Assert.isNotNull(id); + Assert.isNotNull(name); + fId= id; + fName= name; + } + + /** + * Returns the id of the context type. + * + * @return the id of the receiver + */ + public String getId() { + return fId; + } + + + /** + * Returns the name of the context type. + * + * @return the name of the context type + */ + public String getName() { + return fName; + } + + /** + * Creates a context type with a null identifier. + *

                        + * This is a framework-only constructor that exists only so that context + * types can be contributed via an extension point and that should not be + * called in client code except for subclass constructors; use + * {@link #TemplateContextType(String)} instead. + *

                        + */ + public this() { + fResolvers= new HashMap(); + } + + /** + * Sets the id of this context. + *

                        + * This is a framework-only method that exists solely so that context types + * can be contributed via an extension point and that should not be called + * in client code; use {@link #TemplateContextType(String)} instead. + *

                        + * + * @param id the identifier of this context + * @throws RuntimeException an unspecified exception if the id has already + * been set on this context type + */ + public final void setId(String id) { + Assert.isNotNull(id); + Assert.isTrue(fId is null); // may only be called once when the context is instantiated + fId= id; + } + + /** + * Sets the name of the context type. + * + *

                        + * This is a framework-only method that exists solely so that context types + * can be contributed via an extension point and that should not be called + * in client code; use {@link #TemplateContextType(String, String)} instead. + *

                        + * + * @param name the name of the context type + */ + public final void setName(String name) { + Assert.isTrue(fName is null); // only initialized by extension code + fName= name; + } + + /** + * Adds a variable resolver to the context type. If there already is a resolver + * for the same type, the previous one gets replaced by resolver. + * + * @param resolver the resolver to be added under its name + */ + public void addResolver(TemplateVariableResolver resolver) { + Assert.isNotNull(resolver); + fResolvers.put(resolver.getType(), resolver); + } + + /** + * Removes a template variable from the context type. + * + * @param resolver the variable to be removed + */ + public void removeResolver(TemplateVariableResolver resolver) { + Assert.isNotNull(resolver); + fResolvers.remove(resolver.getType()); + } + + /** + * Removes all template variables from the context type. + */ + public void removeAllResolvers() { + fResolvers.clear(); + } + + /** + * Returns an iterator for the variables known to the context type. + * + * @return an iterator over the variables in this context type + */ + public Iterator resolvers() { + return Collections.unmodifiableMap(fResolvers).values().iterator(); + } + + /** + * Returns the resolver for the given type. + * + * @param type the type for which a resolver is needed + * @return a resolver for the given type, or null if none is registered + */ + protected TemplateVariableResolver getResolver(String type) { + return cast(TemplateVariableResolver) fResolvers.get(type); + } + + /** + * Validates a pattern, a TemplateException is thrown if + * validation fails. + * + * @param pattern the template pattern to validate + * @throws TemplateException if the pattern is invalid + */ + public void validate(String pattern) { + TemplateTranslator translator= new TemplateTranslator(); + TemplateBuffer buffer= translator.translate(pattern); + validateVariables(buffer.getVariables()); + } + + /** + * Validates the variables in this context type. If a variable is not valid, + * e.g. if its type is not known in this context type, a + * TemplateException is thrown. + *

                        + * The default implementation does nothing. + *

                        + * + * @param variables the variables to validate + * @throws TemplateException if one of the variables is not valid in this + * context type + */ + protected void validateVariables(TemplateVariable[] variables) { + } + + /** + * Resolves the variables in buffer within context + * and edits the template buffer to reflect the resolved variables. + * + * @param buffer the template buffer + * @param context the template context + * @throws MalformedTreeException if the positions in the buffer overlap + * @throws BadLocationException if the buffer cannot be successfully modified + */ + public void resolve(TemplateBuffer buffer, TemplateContext context) { + Assert.isNotNull(context); + TemplateVariable[] variables= buffer.getVariables(); + + List positions= variablesToPositions(variables); + List edits= new ArrayList(5); + + // iterate over all variables and try to resolve them + for (int i= 0; i !is variables.length; i++) { + TemplateVariable variable= variables[i]; + + if (!variable.isResolved()) + resolve(variable, context); + + String value= variable.getDefaultValue(); + int[] offsets= variable.getOffsets(); + // update buffer to reflect new value + for (int k= 0; k !is offsets.length; k++) + edits.add(new ReplaceEdit(offsets[k], variable.getInitialLength(), value)); + + } + + IDocument document= new Document(buffer.getString()); + MultiTextEdit edit= new MultiTextEdit(0, document.getLength()); + edit.addChildren(arraycast!(TextEdit)( positions.toArray())); + edit.addChildren(arraycast!(TextEdit)( edits.toArray())); + edit.apply(document, TextEdit.UPDATE_REGIONS); + + positionsToVariables(positions, variables); + + buffer.setContent(document.get(), variables); + } + + /** + * Resolves a single variable in a context. Resolving is delegated to the registered resolver. + * + * @param variable the variable to resolve + * @param context the context in which to resolve the variable + * @since 3.3 + */ + public void resolve(TemplateVariable variable, TemplateContext context) { + String type= variable.getType(); + TemplateVariableResolver resolver= cast(TemplateVariableResolver) fResolvers.get(type); + if (resolver is null) + resolver= new TemplateVariableResolver(type, ""); //$NON-NLS-1$ + resolver.resolve(variable, context); + } + + private static List variablesToPositions(TemplateVariable[] variables) { + List positions= new ArrayList(5); + for (int i= 0; i !is variables.length; i++) { + int[] offsets= variables[i].getOffsets(); + for (int j= 0; j !is offsets.length; j++) + positions.add(new RangeMarker(offsets[j], 0)); + } + + return positions; + } + + private static void positionsToVariables(List positions, TemplateVariable[] variables) { + Iterator iterator= positions.iterator(); + + for (int i= 0; i !is variables.length; i++) { + TemplateVariable variable= variables[i]; + + int[] offsets= new int[variable.getOffsets().length]; + for (int j= 0; j !is offsets.length; j++) + offsets[j]= (cast(TextEdit) iterator.next()).getOffset(); + + variable.setOffsets(offsets); + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/TemplateException.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/TemplateException.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.templates.TemplateException; + +import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport +import dwtx.jface.text.templates.TemplateBuffer; // packageimport +import dwtx.jface.text.templates.TemplateContext; // packageimport +import dwtx.jface.text.templates.TemplateContextType; // packageimport +import dwtx.jface.text.templates.Template; // packageimport +import dwtx.jface.text.templates.TemplateVariable; // packageimport +import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport +import dwtx.jface.text.templates.TemplateTranslator; // packageimport +import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport +import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport +import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.templates.TemplateProposal; // packageimport +import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport +import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport +import dwtx.jface.text.templates.TextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateVariableType; // packageimport +import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport + +import dwt.dwthelper.utils; + + +/** + * Thrown when a template cannot be validated. + *

                        + * Clients may instantiate this class. + *

                        + *

                        + * This class is not intended to be serialized. + *

                        + * + * @since 3.0 + */ +public class TemplateException : Exception { + + /** + * Serial version UID for this class. + *

                        + * Note: This class is not intended to be serialized. + *

                        + * @since 3.1 + */ + private static const long serialVersionUID= 3906362710416699442L; + + /** + * Creates a new template exception. + */ + public this() { + super(null); + } + + /** + * Creates a new template exception. + * + * @param message the message describing the problem that arose + */ + public this(String message) { + super(message); + } + + /** + * Creates a new template exception. + * + * @param message the message describing the problem that arose + * @param cause the original exception + */ + public this(String message, Exception cause) { + super(message, cause); + } + + /** + * Creates a new template exception. + * + * @param cause the original exception + */ + public this(Exception cause) { + super(null, cause); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/TemplateProposal.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/TemplateProposal.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,491 @@ +/******************************************************************************* + * 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.text.templates.TemplateProposal; + +import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport +import dwtx.jface.text.templates.TemplateBuffer; // packageimport +import dwtx.jface.text.templates.TemplateContext; // packageimport +import dwtx.jface.text.templates.TemplateContextType; // packageimport +import dwtx.jface.text.templates.Template; // packageimport +import dwtx.jface.text.templates.TemplateVariable; // packageimport +import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport +import dwtx.jface.text.templates.TemplateException; // packageimport +import dwtx.jface.text.templates.TemplateTranslator; // packageimport +import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport +import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport +import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport +import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport +import dwtx.jface.text.templates.TextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateVariableType; // packageimport +import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport + + +import dwt.dwthelper.utils; + + +import dwt.graphics.Image; +import dwt.graphics.Point; +import dwt.widgets.Shell; +import dwtx.core.runtime.Assert; +import dwtx.jface.dialogs.MessageDialog; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.BadPositionCategoryException; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IInformationControlCreator; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.Position; +import dwtx.jface.text.Region; +import dwtx.jface.text.contentassist.ICompletionProposal; +import dwtx.jface.text.contentassist.ICompletionProposalExtension; +import dwtx.jface.text.contentassist.ICompletionProposalExtension2; +import dwtx.jface.text.contentassist.ICompletionProposalExtension3; +import dwtx.jface.text.contentassist.IContextInformation; +import dwtx.jface.text.link.ILinkedModeListener; +import dwtx.jface.text.link.LinkedModeModel; +import dwtx.jface.text.link.LinkedModeUI; +import dwtx.jface.text.link.LinkedPosition; +import dwtx.jface.text.link.LinkedPositionGroup; +import dwtx.jface.text.link.ProposalPosition; + + +/** + * A template completion proposal. + *

                        + * Clients may subclass.

                        + * + * @since 3.0 + */ +public class TemplateProposal : ICompletionProposal, ICompletionProposalExtension, ICompletionProposalExtension2, ICompletionProposalExtension3 { + + private const Template fTemplate; + private const TemplateContext fContext; + private const Image fImage; + private const IRegion fRegion; + private int fRelevance; + + private IRegion fSelectedRegion; // initialized by apply() + private String fDisplayString; + private InclusivePositionUpdater fUpdater; + private IInformationControlCreator fInformationControlCreator; + + /** + * Creates a template proposal with a template and its context. + * + * @param template the template + * @param context the context in which the template was requested. + * @param region the region this proposal is applied to + * @param image the icon of the proposal. + */ + public this(Template template_, TemplateContext context, IRegion region, Image image) { + this(template_, context, region, image, 0); + } + + /** + * Creates a template proposal with a template and its context. + * + * @param template the template + * @param context the context in which the template was requested. + * @param image the icon of the proposal. + * @param region the region this proposal is applied to + * @param relevance the relevance of the proposal + */ + public this(Template template_, TemplateContext context, IRegion region, Image image, int relevance) { + Assert.isNotNull(template_); + Assert.isNotNull(context); + Assert.isNotNull(cast(Object)region); + + fTemplate= template_; + fContext= context; + fImage= image; + fRegion= region; + + fDisplayString= null; + + fRelevance= relevance; + } + + /** + * Sets the information control creator for this completion proposal. + * + * @param informationControlCreator the information control creator + * @since 3.1 + */ + public final void setInformationControlCreator(IInformationControlCreator informationControlCreator) { + fInformationControlCreator= informationControlCreator; + } + + /** + * Returns the template of this proposal. + * + * @return the template of this proposal + * @since 3.1 + */ + protected final Template getTemplate() { + return fTemplate; + } + + /** + * Returns the context in which the template was requested. + * + * @return the context in which the template was requested + * @since 3.1 + */ + protected final TemplateContext getContext() { + return fContext; + } + + /* + * @see ICompletionProposal#apply(IDocument) + */ + public final void apply(IDocument document) { + // not called anymore + } + + /** + * Inserts the template offered by this proposal into the viewer's document + * and sets up a LinkedModeUI on the viewer to edit any of + * the template's unresolved variables. + * + * @param viewer {@inheritDoc} + * @param trigger {@inheritDoc} + * @param stateMask {@inheritDoc} + * @param offset {@inheritDoc} + */ + public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) { + + IDocument document= viewer.getDocument(); + try { + fContext.setReadOnly(false); + int start; + TemplateBuffer templateBuffer; + { + int oldReplaceOffset= getReplaceOffset(); + try { + // this may already modify the document (e.g. add imports) + templateBuffer= fContext.evaluate(fTemplate); + } catch (TemplateException e1) { + fSelectedRegion= fRegion; + return; + } + + start= getReplaceOffset(); + int shift= start - oldReplaceOffset; + int end= Math.max(getReplaceEndOffset(), offset + shift); + + // insert template string + String templateString= templateBuffer.getString(); + document.replace(start, end - start, templateString); + } + + // translate positions + LinkedModeModel model= new LinkedModeModel(); + TemplateVariable[] variables= templateBuffer.getVariables(); + bool hasPositions= false; + for (int i= 0; i !is variables.length; i++) { + TemplateVariable variable= variables[i]; + + if (variable.isUnambiguous()) + continue; + + LinkedPositionGroup group= new LinkedPositionGroup(); + + int[] offsets= variable.getOffsets(); + int length= variable.getLength(); + + LinkedPosition first; + { + String[] values= variable.getValues(); + ICompletionProposal[] proposals= new ICompletionProposal[values.length]; + for (int j= 0; j < values.length; j++) { + ensurePositionCategoryInstalled(document, model); + Position pos= new Position(offsets[0] + start, length); + document.addPosition(getCategory(), pos); + proposals[j]= new PositionBasedCompletionProposal(values[j], pos, length); + } + + if (proposals.length > 1) + first= new ProposalPosition(document, offsets[0] + start, length, proposals); + else + first= new LinkedPosition(document, offsets[0] + start, length); + } + + for (int j= 0; j !is offsets.length; j++) + if (j is 0) + group.addPosition(first); + else + group.addPosition(new LinkedPosition(document, offsets[j] + start, length)); + + model.addGroup(group); + hasPositions= true; + } + + if (hasPositions) { + model.forceInstall(); + LinkedModeUI ui= new LinkedModeUI(model, viewer); + ui.setExitPosition(viewer, getCaretOffset(templateBuffer) + start, 0, Integer.MAX_VALUE); + ui.enter(); + + fSelectedRegion= ui.getSelectedRegion(); + } else { + ensurePositionCategoryRemoved(document); + fSelectedRegion= new Region(getCaretOffset(templateBuffer) + start, 0); + } + + } catch (BadLocationException e) { + openErrorDialog(viewer.getTextWidget().getShell(), e); + ensurePositionCategoryRemoved(document); + fSelectedRegion= fRegion; + } catch (BadPositionCategoryException e) { + openErrorDialog(viewer.getTextWidget().getShell(), e); + fSelectedRegion= fRegion; + } + + } + + private void ensurePositionCategoryInstalled(IDocument document, LinkedModeModel model) { + if (!document.containsPositionCategory(getCategory())) { + document.addPositionCategory(getCategory()); + fUpdater= new InclusivePositionUpdater(getCategory()); + document.addPositionUpdater(fUpdater); + + model.addLinkingListener(new class(document) ILinkedModeListener { + IDocument document_; + this( IDocument a ){ + document_=a; + } + /* + * @see dwtx.jface.text.link.ILinkedModeListener#left(dwtx.jface.text.link.LinkedModeModel, int) + */ + public void left(LinkedModeModel environment, int flags) { + ensurePositionCategoryRemoved(document_); + } + + public void suspend(LinkedModeModel environment) {} + public void resume(LinkedModeModel environment, int flags) {} + }); + } + } + + private void ensurePositionCategoryRemoved(IDocument document) { + if (document.containsPositionCategory(getCategory())) { + try { + document.removePositionCategory(getCategory()); + } catch (BadPositionCategoryException e) { + // ignore + } + document.removePositionUpdater(fUpdater); + } + } + + private String getCategory() { + return "TemplateProposalCategory_" ~ toString(); //$NON-NLS-1$ + } + + private int getCaretOffset(TemplateBuffer buffer) { + + TemplateVariable[] variables= buffer.getVariables(); + for (int i= 0; i !is variables.length; i++) { + TemplateVariable variable= variables[i]; + if (variable.getType().equals(GlobalTemplateVariables.Cursor.NAME)) + return variable.getOffsets()[0]; + } + + return buffer.getString().length(); + } + + /** + * Returns the offset of the range in the document that will be replaced by + * applying this template. + * + * @return the offset of the range in the document that will be replaced by + * applying this template + * @since 3.1 + */ + protected final int getReplaceOffset() { + int start; + if ( cast(DocumentTemplateContext)fContext ) { + DocumentTemplateContext docContext = cast(DocumentTemplateContext)fContext; + start= docContext.getStart(); + } else { + start= fRegion.getOffset(); + } + return start; + } + + /** + * Returns the end offset of the range in the document that will be replaced + * by applying this template. + * + * @return the end offset of the range in the document that will be replaced + * by applying this template + * @since 3.1 + */ + protected final int getReplaceEndOffset() { + int end; + if ( cast(DocumentTemplateContext)fContext ) { + DocumentTemplateContext docContext = cast(DocumentTemplateContext)fContext; + end= docContext.getEnd(); + } else { + end= fRegion.getOffset() + fRegion.getLength(); + } + return end; + } + + /* + * @see ICompletionProposal#getSelection(IDocument) + */ + public Point getSelection(IDocument document) { + return new Point(fSelectedRegion.getOffset(), fSelectedRegion.getLength()); + } + + /* + * @see ICompletionProposal#getAdditionalProposalInfo() + */ + public String getAdditionalProposalInfo() { + try { + fContext.setReadOnly(true); + TemplateBuffer templateBuffer; + try { + templateBuffer= fContext.evaluate(fTemplate); + } catch (TemplateException e) { + return null; + } + + return templateBuffer.getString(); + + } catch (BadLocationException e) { + return null; + } + } + + /* + * @see ICompletionProposal#getDisplayString() + */ + public String getDisplayString() { + if (fDisplayString is null) { + String[] arguments= [ fTemplate.getName(), fTemplate.getDescription() ]; + fDisplayString= JFaceTextTemplateMessages.getFormattedString("TemplateProposal.displayString", stringcast(arguments)); //$NON-NLS-1$ + } + return fDisplayString; + } + + /* + * @see ICompletionProposal#getImage() + */ + public Image getImage() { + return fImage; + } + + /* + * @see ICompletionProposal#getContextInformation() + */ + public IContextInformation getContextInformation() { + return null; + } + + private void openErrorDialog(Shell shell, Exception e) { + MessageDialog.openError(shell, JFaceTextTemplateMessages.getString("TemplateProposal.errorDialog.title"), e.msg); //$NON-NLS-1$ + } + + /** + * Returns the relevance. + * + * @return the relevance + */ + public int getRelevance() { + return fRelevance; + } + + /* + * @see dwtx.jface.text.contentassist.ICompletionProposalExtension3#getInformationControlCreator() + */ + public IInformationControlCreator getInformationControlCreator() { + return fInformationControlCreator; + } + + /* + * @see dwtx.jface.text.contentassist.ICompletionProposalExtension2#selected(dwtx.jface.text.ITextViewer, bool) + */ + public void selected(ITextViewer viewer, bool smartToggle) { + } + + /* + * @see dwtx.jface.text.contentassist.ICompletionProposalExtension2#unselected(dwtx.jface.text.ITextViewer) + */ + public void unselected(ITextViewer viewer) { + } + + /* + * @see dwtx.jface.text.contentassist.ICompletionProposalExtension2#validate(dwtx.jface.text.IDocument, int, dwtx.jface.text.DocumentEvent) + */ + public bool validate(IDocument document, int offset, DocumentEvent event) { + try { + int replaceOffset= getReplaceOffset(); + if (offset >= replaceOffset) { + String content= document.get(replaceOffset, offset - replaceOffset); + return fTemplate.getName().toLowerCase().startsWith(content.toLowerCase()); + } + } catch (BadLocationException e) { + // concurrent modification - ignore + } + return false; + } + + /* + * @see dwtx.jface.text.contentassist.ICompletionProposalExtension3#getPrefixCompletionText(dwtx.jface.text.IDocument, int) + */ + public CharSequence getPrefixCompletionText(IDocument document, int completionOffset) { + return new StringCharSequence( fTemplate.getName() ); + } + + /* + * @see dwtx.jface.text.contentassist.ICompletionProposalExtension3#getPrefixCompletionStart(dwtx.jface.text.IDocument, int) + */ + public int getPrefixCompletionStart(IDocument document, int completionOffset) { + return getReplaceOffset(); + } + + /* + * @see dwtx.jface.text.contentassist.ICompletionProposalExtension#apply(dwtx.jface.text.IDocument, char, int) + */ + public void apply(IDocument document, char trigger, int offset) { + // not called any longer + } + + /* + * @see dwtx.jface.text.contentassist.ICompletionProposalExtension#isValidFor(dwtx.jface.text.IDocument, int) + */ + public bool isValidFor(IDocument document, int offset) { + // not called any longer + return false; + } + + /* + * @see dwtx.jface.text.contentassist.ICompletionProposalExtension#getTriggerCharacters() + */ + public char[] getTriggerCharacters() { + // no triggers + return new char[0]; + } + + /* + * @see dwtx.jface.text.contentassist.ICompletionProposalExtension#getContextInformationPosition() + */ + public int getContextInformationPosition() { + return fRegion.getOffset(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/TemplateTranslator.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/TemplateTranslator.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,349 @@ +/******************************************************************************* + * 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.text.templates.TemplateTranslator; + +import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport +import dwtx.jface.text.templates.TemplateBuffer; // packageimport +import dwtx.jface.text.templates.TemplateContext; // packageimport +import dwtx.jface.text.templates.TemplateContextType; // packageimport +import dwtx.jface.text.templates.Template; // packageimport +import dwtx.jface.text.templates.TemplateVariable; // packageimport +import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport +import dwtx.jface.text.templates.TemplateException; // packageimport +import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport +import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport +import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.templates.TemplateProposal; // packageimport +import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport +import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport +import dwtx.jface.text.templates.TextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateVariableType; // packageimport +import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; +import dwtx.dwtxhelper.regex; + +/** + * The template translator translates a string into a template buffer. Regions marked as variables + * are translated into TemplateVariables. + *

                        + * The EBNF grammar of a valid string is as follows: + *

                        + *

                        + * template := (text | escape)*.
                        + * text := character - dollar.
                        + * escape := dollar ('{' variable '}' | dollar).
                        + * dollar := '$'.
                        + * variable := identifier | identifier ':' type.
                        + * type := qualifiedname | qualifiedname '(' arguments ')'.
                        + * arguments := (argument ',')* argument.
                        + * argument := qualifiedname | argumenttext.
                        + * qualifiedname := (identifier '.')* identifier.
                        + * argumenttext := "'" (character - "'" | "'" "'")* "'".
                        + *

                        + *

                        + * Clients may only replace the createVariable method of this class. + *

                        + * + * @since 3.0 + */ +public class TemplateTranslator { + /** + * Regex pattern for qualifiedname + * @since 3.4 + */ + private static const String QUALIFIED_NAME= "(?:\\w++\\.)*\\w++"; //$NON-NLS-1$ + + /** + * Regex pattern for argumenttext + * @since 3.4 + */ + private static const String ARGUMENT_TEXT= "'(?:(?:'')|(?:[^']))*'"; //$NON-NLS-1$ + + /** + * Regex pattern for argument + * @since 3.4 + */ + private static const String ARGUMENT= "(?:" ~ QUALIFIED_NAME ~ ")|(?:" ~ ARGUMENT_TEXT ~ ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + /** + * Precompiled regex pattern for qualified names. + * @since 3.3 + */ + private static Pattern PARAM_PATTERN_; + private static Pattern PARAM_PATTERN(){ + if( PARAM_PATTERN_ is null ){ + synchronized( TemplateTranslator.classinfo ){ + if( PARAM_PATTERN_ is null ){ + PARAM_PATTERN_ = Pattern.compile(ARGUMENT); + } + } + } + return PARAM_PATTERN_; + } + /** + * Precompiled regex pattern for valid dollar escapes (dollar literals and variables) and + * (invalid) single dollars. + * @since 3.3 + */ + private static Pattern ESCAPE_PATTERN_; + private static Pattern ESCAPE_PATTERN(){ + if( ESCAPE_PATTERN_ is null ){ + synchronized( TemplateTranslator.classinfo ){ + if( ESCAPE_PATTERN_ is null ){ + ESCAPE_PATTERN_ = Pattern.compile( + "\\$\\$|\\$\\{\\s*+" ~ // $$|${ //$NON-NLS-1$ + "(\\w*+)" ~ // variable id group (1) //$NON-NLS-1$ + "\\s*+(?::\\s*+" ~ // : //$NON-NLS-1$ + "(" ~ QUALIFIED_NAME ~ ")" ~ // variable type group (2) //$NON-NLS-1$ //$NON-NLS-2$ + "\\s*+(?:\\(\\s*+" ~ // ( //$NON-NLS-1$ + "((?:(?:" ~ ARGUMENT ~ ")\\s*+,\\s*+)*(?:" ~ ARGUMENT ~ "))" ~ // arguments group (3) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "\\s*+\\))?\\s*+)?\\}|\\$"); // )}|$ //$NON-NLS-1$ + } + } + } + return ESCAPE_PATTERN_; + } + /** + * @since 3.3 + */ + private final class VariableDescription { + const List fOffsets; + const String fName; + TemplateVariableType fType; + + this(String name, TemplateVariableType type) { + fOffsets= new ArrayList(5); + fName= name; + fType= type; + } + + void mergeType(TemplateVariableType type) { + if (type is null) + return; + if (fType is null) + fType= type; + if (!type.equals(fType)) + fail(TextTemplateMessages.getFormattedString("TemplateTranslator.error.incompatible.type", stringcast(fName))); //$NON-NLS-1$ + } + } + + /** Last translation error. */ + private String fErrorMessage; + /** + * Used to ensure compatibility with subclasses overriding + * {@link #createVariable(String, String, int[])}. + * @since 3.3 + */ + private TemplateVariableType fCurrentType; + + /** + * Returns an error message if an error occurred for the last translation, null + * otherwise. + * + * @return the error message if an error occurred during the most recent translation, + * null otherwise + */ + public String getErrorMessage() { + return fErrorMessage; + } + + /** + * Translates a template to a TemplateBuffer. null is returned if + * there was an error. getErrorMessage() retrieves the associated error message. + * + * @param template the template to translate. + * @return returns the template buffer corresponding to the string + * @see #getErrorMessage() + * @throws TemplateException if translation failed + */ + public TemplateBuffer translate(Template template_) { + return parse(template_.getPattern()); + } + + /** + * Translates a template string to TemplateBuffer. null is + * returned if there was an error. getErrorMessage() retrieves the associated + * error message. + * + * @param string the string to translate. + * @return returns the template buffer corresponding to the string + * @see #getErrorMessage() + * @throws TemplateException if translation failed + */ + public TemplateBuffer translate(String string) { + return parse(string); + } + + /** + * Internal parser. + * + * @param string the string to parse + * @return the parsed TemplateBuffer + * @throws TemplateException if the string does not conform to the template format + */ + private TemplateBuffer parse(String string) { + + fErrorMessage= null; + final StringBuffer buffer= new StringBuffer(string.length()); + final Matcher matcher= ESCAPE_PATTERN.matcher(string); + final Map variables= new LinkedHashMap(); + + int complete= 0; + while (matcher.find()) { + // append any verbatim text + buffer.append(string.substring(complete, matcher.start())); + + // check the escaped sequence + if ("$".equals(matcher.group())) { //$NON-NLS-1$ + fail(TextTemplateMessages.getString("TemplateTranslator.error.incomplete.variable")); //$NON-NLS-1$ + } else if ("$$".equals(matcher.group())) { //$NON-NLS-1$ + // escaped $ + buffer.append('$'); + } else { + // parse variable + String name= matcher.group(1); + String typeName= matcher.group(2); + String params= matcher.group(3); + TemplateVariableType type= createType(typeName, params); + + updateOrCreateVariable(variables, name, type, buffer.length()); + + buffer.append(name); + } + complete= matcher.end(); + } + // append remaining verbatim text + buffer.append(string.substring(complete)); + + TemplateVariable[] vars= createVariables(variables); + return new TemplateBuffer(buffer.toString(), vars); + } + + private TemplateVariableType createType(String typeName, String paramString) { + if (typeName is null) + return null; + + if (paramString is null) + return new TemplateVariableType(typeName); + + final Matcher matcher= PARAM_PATTERN.matcher(paramString); + List params= new ArrayList(5); + while (matcher.find()) { + String argument= matcher.group(); + if (argument.charAt(0) is '\'') { + // argumentText + argument= argument.substring(1, argument.length() - 1).replaceAll("''", "'"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + params.add(argument); + } + + return new TemplateVariableType(typeName, stringcast( params.toArray())); + } + + private void fail(String message) { + fErrorMessage= message; + throw new TemplateException(message); + } + + /** + * If there is no variable named name, a new variable with the given type, name + * and offset is created. If one exists, the offset is added to the variable and the type is + * merged with the existing type. + * + * @param variables the variables by variable name + * @param name the name of the variable + * @param type the variable type, null for not defined + * @param offset the buffer offset of the variable + * @throws TemplateException if merging the type fails + * @since 3.3 + */ + private void updateOrCreateVariable(Map variables, String name, TemplateVariableType type, int offset) { + VariableDescription varDesc= cast(VariableDescription) variables.get(name); + if (varDesc is null) { + varDesc= new VariableDescription(name, type); + variables.put(name, varDesc); + } else { + varDesc.mergeType(type); + } + varDesc.fOffsets.add(new Integer(offset)); + } + + /** + * Creates proper {@link TemplateVariable}s from the variable descriptions. + * + * @param variables the variable descriptions by variable name + * @return the corresponding variables + * @since 3.3 + */ + private TemplateVariable[] createVariables(Map variables) { + TemplateVariable[] result= new TemplateVariable[variables.size()]; + int idx= 0; + for (Iterator it= variables.values().iterator(); it.hasNext(); idx++) { + VariableDescription desc= cast(VariableDescription) it.next(); + TemplateVariableType type= desc.fType is null ? new TemplateVariableType(desc.fName) : desc.fType; + int[] offsets= new int[desc.fOffsets.size()]; + int i= 0; + for (Iterator intIt= desc.fOffsets.iterator(); intIt.hasNext(); i++) { + Integer offset= cast(Integer) intIt.next(); + offsets[i]= offset.intValue(); + } + fCurrentType= type; + /* + * Call the deprecated version of createVariable. When not overridden, it will delegate + * to the new version using fCurrentType. + */ + TemplateVariable var= createVariable(type.getName(), desc.fName, offsets); + result[idx]= var; + } + fCurrentType= null; // avoid dangling reference + return result; + } + + /** + * Hook method to create new variables. Subclasses may override to supply their custom variable + * type. + *

                        + * Clients may replace this method. + *

                        + * + * @param type the type of the new variable. + * @param name the name of the new variable. + * @param offsets the offsets where the variable occurs in the template + * @return a new instance of TemplateVariable + * @deprecated as of 3.3 use {@link #createVariable(TemplateVariableType, String, int[])} instead + */ + protected TemplateVariable createVariable(String type, String name, int[] offsets) { + return createVariable(fCurrentType, name, offsets); + } + + /** + * Hook method to create new variables. Subclasses may override to supply their custom variable + * type. + *

                        + * Clients may replace this method. + *

                        + * + * @param type the type of the new variable. + * @param name the name of the new variable. + * @param offsets the offsets where the variable occurs in the template + * @return a new instance of TemplateVariable + * @since 3.3 + */ + protected TemplateVariable createVariable(TemplateVariableType type, String name, int[] offsets) { + return new TemplateVariable(type, name, name, offsets); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/TemplateVariable.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/TemplateVariable.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,309 @@ +/******************************************************************************* + * 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.text.templates.TemplateVariable; + +import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport +import dwtx.jface.text.templates.TemplateBuffer; // packageimport +import dwtx.jface.text.templates.TemplateContext; // packageimport +import dwtx.jface.text.templates.TemplateContextType; // packageimport +import dwtx.jface.text.templates.Template; // packageimport +import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport +import dwtx.jface.text.templates.TemplateException; // packageimport +import dwtx.jface.text.templates.TemplateTranslator; // packageimport +import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport +import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport +import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.templates.TemplateProposal; // packageimport +import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport +import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport +import dwtx.jface.text.templates.TextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateVariableType; // packageimport +import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.TextUtilities; + +/** + * A TemplateVariable represents a set of positions into a + * TemplateBuffer with identical content each. TemplateVariableResolvers + * can be used to resolve a template variable to a symbol available from the + * TemplateContext. A resolved variable may have one or more possible + * {@link #getValues() values} which may be presented to the user as choices. If there is no user + * interaction the {@link #getDefaultValue() default value} is chosen as textual representation of + * the variable. + *

                        + * Clients may instantiate and extend this class. + *

                        + * + * @see TemplateVariableResolver + * @see TemplateBuffer + * @since 3.0 + */ +public class TemplateVariable { + + /** The type name of the variable */ + private const TemplateVariableType fType; + /** The name of the variable. */ + private const String fName; + /** The initial length in the template pattern. */ + private const int fInitialLength; + /** The offsets of the variable. */ + private int[] fOffsets; + /** Flag indicating if the variable has been resolved unambiguously. */ + private bool fIsUnambiguous; + /** Flag indicating if the variable has been resolved by a resolver. */ + private bool fIsResolved; + /** + * The proposal strings available for this variable. The first string is + * the default value. + */ + private String[] fValues; + + /** + * Creates a template variable. The type is used as the name of the + * variable. + * + * @param type the type of the variable + * @param defaultValue the default value of the variable + * @param offsets the array of offsets of the variable + */ + public this(String type, String defaultValue, int[] offsets) { + this(type, [ defaultValue ], offsets); + } + + /** + * Creates a template variable. + * + * @param type the type of the variable + * @param name the name of the variable + * @param defaultValue the default value of the variable + * @param offsets the array of offsets of the variable + */ + public this(String type, String name, String defaultValue, int[] offsets) { + this(type, name, [ defaultValue ], offsets); + } + + /** + * Creates a template variable. + * + * @param type the type of the variable + * @param name the name of the variable + * @param defaultValue the default value of the variable + * @param offsets the array of offsets of the variable + * @since 3.3 + */ + public this(TemplateVariableType type, String name, String defaultValue, int[] offsets) { + this(type, name, [ defaultValue ], offsets); + } + + /** + * Creates a template variable with multiple possible values. The type is + * used as the name of the template. + * + * @param type the type of the template variable + * @param values the values available at this variable, non-empty + * @param offsets the array of offsets of the variable + */ + public this(String type, String[] values, int[] offsets) { + this(type, type, values, offsets); + } + + /** + * Creates a template variable with multiple possible values. + * + * @param type the type of the variable + * @param name the name of the variable + * @param values the values available at this variable, non-empty + * @param offsets the array of offsets of the variable + */ + public this(String type, String name, String[] values, int[] offsets) { + this(new TemplateVariableType(type), name, values, offsets); + } + + /** + * Creates a template variable with multiple possible values. + * + * @param type the type of the variable + * @param name the name of the variable + * @param values the values available at this variable, non-empty + * @param offsets the array of offsets of the variable + * @since 3.3 + */ + this(TemplateVariableType type, String name, String[] values, int[] offsets) { + Assert.isNotNull(type); + Assert.isNotNull(name); + fType= type; + fName= name; + setValues(values); + setOffsets(offsets); + setUnambiguous(false); + setResolved(false); + fInitialLength= values[0].length(); + } + + /** + * Returns the type name of the variable. + * + * @return the type name of the variable + */ + public String getType() { + return fType.getName(); + } + + /** + * Returns the type of the variable. + * + * @return the type of the variable + * @since 3.3 + */ + public TemplateVariableType getVariableType() { + return fType; + } + + /** + * Returns the name of the variable. + * + * @return the name of the variable + */ + public String getName() { + return fName; + } + + /** + * Returns the default value of the variable. Typically, this is the first of + * the possible values (see {@link #getValues()}. + * + * @return the default value of the variable + */ + public String getDefaultValue() { + return getValues()[0]; + } + + /** + * Returns the possible values for this variable. The returned array is owned by this variable + * and must not be modified. The array is not empty. + * + * @return the possible values for this variable + */ + public String[] getValues() { + return fValues; + } + + /** + * Returns the length of the variable's default value. + * + * @return the length of the variable + */ + public int getLength() { + return getDefaultValue().length(); + } + + /** + * Returns the initial length of the variable. The initial length is the lenght as it occurred + * in the template pattern and is used when resolving a template to update the pattern with the + * resolved values of the variable. + * + * @return the initial length of the variable + * @since 3.3 + */ + final int getInitialLength() { + return fInitialLength; + } + + /** + * Sets the offsets of the variable. + * + * @param offsets the new offsets of the variable + */ + public void setOffsets(int[] offsets) { + fOffsets= TextUtilities.copy(offsets); + } + + /** + * Returns the offsets of the variable. The returned array is + * owned by this variable and must not be modified. + * + * @return the length of the variable + */ + public int[] getOffsets() { + return fOffsets; + } + + /** + * Resolves the variable to a single value. This is a shortcut for + * setValues(new String[] { value }). + * + * @param value the new default value + */ + public final void setValue(String value) { + setValues([ value ]); + } + + /** + * Resolves the variable to several possible values for this variable, with the first being the + * default value. + * + * @param values a non-empty array of values + */ + public void setValues(String[] values) { + Assert.isTrue(values.length > 0); + fValues= TextUtilities.copy(values); + setResolved(true); + } + + /** + * Sets the isUnambiguous flag of the variable. + * + * @param unambiguous the new unambiguous state of the variable + */ + public void setUnambiguous(bool unambiguous) { + fIsUnambiguous= unambiguous; + if (unambiguous) + setResolved(true); + } + + /** + * Returns true if the variable is unambiguously resolved, false otherwise. + * + * @return true if the variable is unambiguously resolved, false otherwise + */ + public bool isUnambiguous() { + return fIsUnambiguous; + } + + /** + * Sets the resolved flag of the variable. + * + * @param resolved the new resolved state + * @since 3.3 + */ + public void setResolved(bool resolved) { + fIsResolved= resolved; + } + + /** + * Returns true if the variable has been resolved, false + * otherwise. + * + * @return true if the variable has been resolved, false otherwise + * @since 3.3 + */ + public bool isResolved() { + return fIsResolved; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/TemplateVariableResolver.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/TemplateVariableResolver.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,196 @@ +/******************************************************************************* + * 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 + * 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.text.templates.TemplateVariableResolver; + +import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport +import dwtx.jface.text.templates.TemplateBuffer; // packageimport +import dwtx.jface.text.templates.TemplateContext; // packageimport +import dwtx.jface.text.templates.TemplateContextType; // packageimport +import dwtx.jface.text.templates.Template; // packageimport +import dwtx.jface.text.templates.TemplateVariable; // packageimport +import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport +import dwtx.jface.text.templates.TemplateException; // packageimport +import dwtx.jface.text.templates.TemplateTranslator; // packageimport +import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport +import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport +import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.templates.TemplateProposal; // packageimport +import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport +import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport +import dwtx.jface.text.templates.TextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateVariableType; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.core.runtime.Assert; + +/** + * A TemplateVariableResolver resolves TemplateVariables + * of a certain type inside a TemplateContext. + *

                        + * Clients may instantiate and extend this class. + *

                        + * + * @see TemplateVariable + * @since 3.0 + */ +public class TemplateVariableResolver { + + /** Type of this resolver. */ + private String fType= null; + + /** Description of the type resolved by this resolver. */ + private String fDescription= null; + + /** + * Creates an instance of TemplateVariableResolver. + * + * @param type the name of the type + * @param description the description for the type + */ + /+protected+/ this(String type, String description) { + setType(type); + setDescription(description); + } + + /** + * Creates an empty instance. + *

                        + * This is a framework-only constructor that exists only so that resolvers + * can be contributed via an extension point and that should not be called + * in client code except for subclass constructors; use + * {@link #TemplateVariableResolver(String, String)} instead. + *

                        + */ + public this() { + } + + /** + * Returns the type of this resolver. + * + * @return the type + */ + public String getType() { + return fType; + } + + /** + * Returns the description for the resolver. + * + * @return the description for the resolver + */ + public String getDescription() { + return fDescription; + } + + /** + * Returns an instance of the type resolved by the receiver available in context. + * To resolve means to provide a binding to a concrete text object (a + * String) in the given context. + *

                        + * The default implementation looks up the type in the context.

                        + * + * @param context the context in which to resolve the type + * @return the name of the text object of this type, or null if it cannot be determined + */ + protected String resolve(TemplateContext context) { + return context.getVariable(getType()); + } + + /** + * Returns all possible bindings available in context. The default + * implementation simply returns an array which contains the result of + * {@link #resolve(TemplateContext)}, or an empty array if that call returns + * null. + * + * @param context the context in which to resolve the type + * @return an array of possible bindings of this type in context + */ + protected String[] resolveAll(TemplateContext context) { + String binding= resolve(context); + if (binding is null) + return new String[0]; + return [ binding ]; + } + + /** + * Resolves variable in context. To resolve + * means to find a valid binding of the receiver's type in the given TemplateContext. + * If the variable can be successfully resolved, its value is set using + * {@link TemplateVariable#setValues(String[])}. + * + * @param context the context in which variable is resolved + * @param variable the variable to resolve + */ + public void resolve(TemplateVariable variable, TemplateContext context) { + String[] bindings= resolveAll(context); + if (bindings.length !is 0) + variable.setValues(bindings); + if (bindings.length > 1) + variable.setUnambiguous(false); + else + variable.setUnambiguous(isUnambiguous(context)); + variable.setResolved(true); + } + + /** + * Returns whether this resolver is able to resolve unambiguously. When + * resolving a TemplateVariable, its isUmambiguous + * state is set to the one of this resolver. By default, this method + * returns false. Clients can overwrite this method to give + * a hint about whether there should be e.g. prompting for input values for + * ambiguous variables. + * + * @param context the context in which the resolved check should be + * evaluated + * @return true if the receiver is unambiguously resolvable + * in context, false otherwise + */ + protected bool isUnambiguous(TemplateContext context) { + return false; + } + + /** + * Sets the description. + *

                        + * This is a framework-only method that exists only so that resolvers + * can be contributed via an extension point and that should not be called + * in client code; use {@link #TemplateVariableResolver(String, String)} instead. + *

                        + * + * @param description the description of this resolver + */ + public final void setDescription(String description) { + Assert.isNotNull(description); + Assert.isTrue(fDescription is null); // may only be called once when initialized + fDescription= description; + } + + /** + * Sets the type name. + *

                        + * This is a framework-only method that exists only so that resolvers + * can be contributed via an extension point and that should not be called + * in client code; use {@link #TemplateVariableResolver(String, String)} instead. + *

                        + * + * @param type the type name of this resolver + */ + public final void setType(String type) { + Assert.isNotNull(type); + Assert.isTrue(fType is null); // may only be called once when initialized + fType= type; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/TemplateVariableType.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/TemplateVariableType.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,113 @@ +/******************************************************************************* + * 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 + * 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.text.templates.TemplateVariableType; + +import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport +import dwtx.jface.text.templates.TemplateBuffer; // packageimport +import dwtx.jface.text.templates.TemplateContext; // packageimport +import dwtx.jface.text.templates.TemplateContextType; // packageimport +import dwtx.jface.text.templates.Template; // packageimport +import dwtx.jface.text.templates.TemplateVariable; // packageimport +import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport +import dwtx.jface.text.templates.TemplateException; // packageimport +import dwtx.jface.text.templates.TemplateTranslator; // packageimport +import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport +import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport +import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.templates.TemplateProposal; // packageimport +import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport +import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport +import dwtx.jface.text.templates.TextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + + +import dwtx.core.runtime.Assert; + + +/** + * Value object that represents the type of a template variable. A type is defined by its name and + * may have parameters. + * + * @since 3.3 + * @noinstantiate This class is not intended to be instantiated by clients. + */ +public final class TemplateVariableType { + + /** The name of the type. */ + private const String fName; + /** The parameter list. */ + private const List fParams; + + this(String name) { + this(name, new String[0]); + } + + this(String name, String[] params) { + Assert.isLegal(name !is null); + Assert.isLegal(params !is null); + fName= name; + fParams= Collections.unmodifiableList(new ArrayList(Arrays.asList(stringcast(params)))); + } + + /** + * Returns the type name of this variable type. + * + * @return the type name of this variable type + */ + public String getName() { + return fName; + } + + /** + * Returns the unmodifiable and possibly empty list of parameters (element type: {@link String}) + * + * @return the list of parameters + */ + public List getParams() { + return fParams; + } + + /* + * @see java.lang.Object#equals(java.lang.Object) + */ + public override int opEquals(Object obj) { + if ( cast(TemplateVariableType)obj ) { + TemplateVariableType other= cast(TemplateVariableType) obj; + return other.fName.equals(fName) && other.fParams.opEquals(cast(Object)fParams); + } + return false; + } + + /* + * @see java.lang.Object#hashCode() + */ + public override hash_t toHash() { + alias .toHash toHash; + return fName.toHash() + fParams.toHash(); + } + /* + * @see java.lang.Object#toString() + * @since 3.3 + */ + public override String toString() { + return fName ~ (cast(Object)fParams).toString(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/TextTemplateMessages.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/TextTemplateMessages.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,67 @@ +/******************************************************************************* + * 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 + * 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.text.templates.TextTemplateMessages; + +import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport +import dwtx.jface.text.templates.TemplateBuffer; // packageimport +import dwtx.jface.text.templates.TemplateContext; // packageimport +import dwtx.jface.text.templates.TemplateContextType; // packageimport +import dwtx.jface.text.templates.Template; // packageimport +import dwtx.jface.text.templates.TemplateVariable; // packageimport +import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport +import dwtx.jface.text.templates.TemplateException; // packageimport +import dwtx.jface.text.templates.TemplateTranslator; // packageimport +import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport +import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport +import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport +import dwtx.jface.text.templates.TemplateProposal; // packageimport +import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport +import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport +import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport +import dwtx.jface.text.templates.TemplateVariableType; // packageimport +import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.dwthelper.ResourceBundle; +import dwtx.dwtxhelper.MessageFormat; + +/* + * @since 3.0 + */ +class TextTemplateMessages { + +// private static const String RESOURCE_BUNDLE= TextTemplateMessages.classinfo.getName(); + private static ResourceBundle fgResourceBundle;//= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + static this() { + fgResourceBundle = ResourceBundle.getBundle( + getImportData!("dwtx.jface.text.templates.TextTemplateMessages.properties")); + } + + private this() { + } + + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return '!' ~ key ~ '!'; + } + } + + public static String getFormattedString(String key, Object[] args... ) { + return MessageFormat.format(getString(key), args); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/persistence/TemplatePersistenceData.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/persistence/TemplatePersistenceData.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,189 @@ +/******************************************************************************* + * 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 + * 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.text.templates.persistence.TemplatePersistenceData; + +import dwtx.jface.text.templates.persistence.TemplateReaderWriter; // packageimport +import dwtx.jface.text.templates.persistence.TemplatePersistenceMessages; // packageimport +import dwtx.jface.text.templates.persistence.TemplateStore; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.templates.Template; + + +/** + * TemplatePersistenceData stores information about a template. It uniquely + * references contributed templates via their id. Contributed templates may be + * deleted or modified. All template may be enabled or not. + *

                        + * Clients may use this class, although this is not usually needed except when + * implementing a custom template preference page or template store. This class + * is not intended to be subclassed. + *

                        + * + * @since 3.0 + * @noextend This class is not intended to be subclassed by clients. + */ +public class TemplatePersistenceData { + private const Template fOriginalTemplate; + private const String fId; + private const bool fOriginalIsEnabled; + + private Template fCustomTemplate= null; + private bool fIsDeleted= false; + private bool fCustomIsEnabled= true; + + /** + * Creates a new, user-added instance that is not linked to a contributed + * template. + * + * @param template the template which is stored by the new instance + * @param enabled whether the template is enabled + */ + public this(Template template_, bool enabled) { + this(template_, enabled, null); + } + + /** + * Creates a new instance. If id is not null, + * the instance is represents a template that is contributed and can be + * identified via its id. + * + * @param template the template which is stored by the new instance + * @param enabled whether the template is enabled + * @param id the id of the template, or null if a user-added + * instance should be created + */ + public this(Template template_, bool enabled, String id) { + Assert.isNotNull(template_); + fOriginalTemplate= template_; + fCustomTemplate= template_; + fOriginalIsEnabled= enabled; + fCustomIsEnabled= enabled; + fId= id; + } + + /** + * Returns the id of this template store, or null if there is none. + * + * @return the id of this template store + */ + public String getId() { + return fId; + } + + /** + * Returns the deletion state of the stored template. This is only relevant + * of contributed templates. + * + * @return the deletion state of the stored template + */ + public bool isDeleted() { + return fIsDeleted; + } + + /** + * Sets the deletion state of the stored template. + * + * @param isDeleted the deletion state of the stored template + */ + public void setDeleted(bool isDeleted) { + fIsDeleted= isDeleted; + } + + /** + * Returns the template encapsulated by the receiver. + * + * @return the template encapsulated by the receiver + */ + public Template getTemplate() { + return fCustomTemplate; + } + + + /** + * Sets the template encapsulated by the receiver. + * + * @param template the new template + */ + public void setTemplate(Template template_) { + fCustomTemplate= template_; + } + + /** + * Returns whether the receiver represents a custom template, i.e. is either + * a user-added template or a contributed template that has been modified. + * + * @return true if the contained template is a custom + * template and cannot be reconstructed from the contributed + * templates + */ + public bool isCustom() { + return fId is null + || fIsDeleted + || fOriginalIsEnabled !is fCustomIsEnabled + || !fOriginalTemplate.equals(fCustomTemplate); + } + + /** + * Returns whether the receiver represents a modified template, i.e. a + * contributed template that has been changed. + * + * @return true if the contained template is contributed but has been modified, false otherwise + */ + public bool isModified() { + return isCustom() && !isUserAdded(); + } + + /** + * Returns true if the contained template was added by a + * user, i.e. does not reference a contributed template. + * + * @return true if the contained template was added by a user, false otherwise + */ + public bool isUserAdded() { + return fId is null; + } + + + /** + * Reverts the template to its original setting. + */ + public void revert() { + fCustomTemplate= fOriginalTemplate; + fCustomIsEnabled= fOriginalIsEnabled; + fIsDeleted= false; + } + + + /** + * Returns the enablement state of the contained template. + * + * @return the enablement state of the contained template + */ + public bool isEnabled() { + return fCustomIsEnabled; + } + + /** + * Sets the enablement state of the contained template. + * + * @param isEnabled the new enablement state of the contained template + */ + public void setEnabled(bool isEnabled) { + fCustomIsEnabled= isEnabled; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/persistence/TemplatePersistenceMessages.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/persistence/TemplatePersistenceMessages.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,52 @@ +/******************************************************************************* + * 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 + * 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.text.templates.persistence.TemplatePersistenceMessages; + +import dwtx.jface.text.templates.persistence.TemplatePersistenceData; // packageimport +import dwtx.jface.text.templates.persistence.TemplateReaderWriter; // packageimport +import dwtx.jface.text.templates.persistence.TemplateStore; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.dwthelper.ResourceBundle; +import dwtx.dwtxhelper.MessageFormat; + +/** + * @since 3.0 + */ +class TemplatePersistenceMessages { + +// private static const String RESOURCE_BUNDLE= TemplatePersistenceMessages.classinfo.getName(); + private static ResourceBundle fgResourceBundle;//= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + static this() { + fgResourceBundle = ResourceBundle.getBundle( + getImportData!("dwtx.jface.text.templates.persistence.TemplatePersistenceMessages.properties")); + } + + private this() { + } + + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return '!' ~ key ~ '!'; + } + } + + public static String getFormattedString(String key, Object[] args...) { + return MessageFormat.format(getString(key), args); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/persistence/TemplatePersistenceMessages.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/persistence/TemplatePersistenceMessages.properties Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,14 @@ +############################################################################### +# Copyright (c) 2000, 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 +############################################################################### + +TemplateReaderWriter.duplicate.id= Duplicate template id +TemplateReaderWriter.error.missing_attribute= Missing required attribute +TemplateReaderWriter.error.illegal_boolean_attribute= Illegal boolean attribute, must be "true" or "false". diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/persistence/TemplateReaderWriter.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/persistence/TemplateReaderWriter.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,390 @@ +/******************************************************************************* + * 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 + * 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.text.templates.persistence.TemplateReaderWriter; + +import dwtx.jface.text.templates.persistence.TemplatePersistenceData; // packageimport +import dwtx.jface.text.templates.persistence.TemplatePersistenceMessages; // packageimport +import dwtx.jface.text.templates.persistence.TemplateStore; // packageimport + + +import dwt.dwthelper.utils; +import dwt.dwthelper.InputStream; +import dwtx.dwtxhelper.Collection; +import dwt.dwthelper.ResourceBundle; + +/+ +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; ++/ + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.templates.Template; + +/** + * Serializes templates as character or byte stream and reads the same format + * back. + *

                        + * Clients may instantiate this class, it is not intended to be + * subclassed.

                        + * + * @since 3.0 + * @noextend This class is not intended to be subclassed by clients. + */ +public class TemplateReaderWriter { + + private static const String TEMPLATE_ROOT = "templates"; //$NON-NLS-1$ + private static const String TEMPLATE_ELEMENT = "template"; //$NON-NLS-1$ + private static const String NAME_ATTRIBUTE= "name"; //$NON-NLS-1$ + private static const String ID_ATTRIBUTE= "id"; //$NON-NLS-1$ + private static const String DESCRIPTION_ATTRIBUTE= "description"; //$NON-NLS-1$ + private static const String CONTEXT_ATTRIBUTE= "context"; //$NON-NLS-1$ + private static const String ENABLED_ATTRIBUTE= "enabled"; //$NON-NLS-1$ + private static const String DELETED_ATTRIBUTE= "deleted"; //$NON-NLS-1$ + /** + * @since 3.1 + */ + private static const String AUTO_INSERTABLE_ATTRIBUTE= "autoinsert"; //$NON-NLS-1$ + + /** + * Create a new instance. + */ + public this() { + } + + /** + * Reads templates from a reader and returns them. The reader must present + * a serialized form as produced by the save method. + * + * @param reader the reader to read templates from + * @return the read templates, encapsulated in instances of TemplatePersistenceData + * @throws IOException if reading from the stream fails + */ + public TemplatePersistenceData[] read(Reader reader) { + return read(reader, null); + } + + /** + * Reads the template with identifier id from a reader and + * returns it. The reader must present a serialized form as produced by the + * save method. + * + * @param reader the reader to read templates from + * @param id the id of the template to return + * @return the read template, encapsulated in an instances of + * TemplatePersistenceData + * @throws IOException if reading from the stream fails + * @since 3.1 + */ + public TemplatePersistenceData readSingle(Reader reader, String id) { + TemplatePersistenceData[] datas= read(new InputSource(reader), null, id); + if (datas.length > 0) + return datas[0]; + return null; + } + + /** + * Reads templates from a stream and adds them to the templates. + * + * @param reader the reader to read templates from + * @param bundle a resource bundle to use for translating the read templates, or null if no translation should occur + * @return the read templates, encapsulated in instances of TemplatePersistenceData + * @throws IOException if reading from the stream fails + */ + public TemplatePersistenceData[] read(Reader reader, ResourceBundle bundle) { + return read(new InputSource(reader), bundle, null); + } + + /** + * Reads templates from a stream and adds them to the templates. + * + * @param stream the byte stream to read templates from + * @param bundle a resource bundle to use for translating the read templates, or null if no translation should occur + * @return the read templates, encapsulated in instances of TemplatePersistenceData + * @throws IOException if reading from the stream fails + */ + public TemplatePersistenceData[] read(InputStream stream, ResourceBundle bundle) { + return read(new InputSource(stream), bundle, null); + } + + /** + * Reads templates from an InputSource and adds them to the templates. + * + * @param source the input source + * @param bundle a resource bundle to use for translating the read templates, or null if no translation should occur + * @param singleId the template id to extract, or null to read in all templates + * @return the read templates, encapsulated in instances of TemplatePersistenceData + * @throws IOException if reading from the stream fails + */ + private TemplatePersistenceData[] read(InputSource source, ResourceBundle bundle, String singleId) { + try { + Collection templates= new ArrayList(); + Set ids= new HashSet(); + + DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance(); + DocumentBuilder parser= factory.newDocumentBuilder(); + Document document= parser.parse(source); + + NodeList elements= document.getElementsByTagName(TEMPLATE_ELEMENT); + + int count= elements.getLength(); + for (int i= 0; i !is count; i++) { + Node node= elements.item(i); + NamedNodeMap attributes= node.getAttributes(); + + if (attributes is null) + continue; + + String id= getStringValue(attributes, ID_ATTRIBUTE, null); + if (id !is null && ids.contains(id)) + throw new IOException(TemplatePersistenceMessages.getString("TemplateReaderWriter.duplicate.id")); //$NON-NLS-1$ + + if (singleId !is null && !singleId.equals(id)) + continue; + + bool deleted = getBooleanValue(attributes, DELETED_ATTRIBUTE, false); + + String name= getStringValue(attributes, NAME_ATTRIBUTE); + name= translateString(name, bundle); + + String description= getStringValue(attributes, DESCRIPTION_ATTRIBUTE, ""); //$NON-NLS-1$ + description= translateString(description, bundle); + + String context= getStringValue(attributes, CONTEXT_ATTRIBUTE); + + if (name is null || context is null) + throw new IOException(TemplatePersistenceMessages.getString("TemplateReaderWriter.error.missing_attribute")); //$NON-NLS-1$ + + bool enabled = getBooleanValue(attributes, ENABLED_ATTRIBUTE, true); + bool autoInsertable= getBooleanValue(attributes, AUTO_INSERTABLE_ATTRIBUTE, true); + + StringBuffer buffer= new StringBuffer(); + NodeList children= node.getChildNodes(); + for (int j= 0; j !is children.getLength(); j++) { + String value= children.item(j).getNodeValue(); + if (value !is null) + buffer.append(value); + } + String pattern= buffer.toString(); + pattern= translateString(pattern, bundle); + + Template template_= new Template(name, description, context, pattern, autoInsertable); + TemplatePersistenceData data= new TemplatePersistenceData(template_, enabled, id); + data.setDeleted(deleted); + + templates.add(data); + + if (singleId !is null && singleId.equals(id)) + break; + } + + return arraycast!(TemplatePersistenceData)( templates.toArray()); + + } catch (ParserConfigurationException e) { + Assert.isTrue(false); + } catch (SAXException e) { + Throwable t= e.getCause(); + if ( cast(IOException)t ) + throw cast(IOException) t; + else if (t !is null) + throw new IOException(t.getMessage()); + else + throw new IOException(e.getMessage()); + } + + return null; // dummy + } + + /** + * Saves the templates as XML, encoded as UTF-8 onto the given byte stream. + * + * @param templates the templates to save + * @param stream the byte output to write the templates to in XML + * @throws IOException if writing the templates fails + */ + public void save(TemplatePersistenceData[] templates, OutputStream stream) { + save(templates, new StreamResult(stream)); + } + + /** + * Saves the templates as XML. + * + * @param templates the templates to save + * @param writer the writer to write the templates to in XML + * @throws IOException if writing the templates fails + */ + public void save(TemplatePersistenceData[] templates, Writer writer) { + save(templates, new StreamResult(writer)); + } + + /** + * Saves the templates as XML. + * + * @param templates the templates to save + * @param result the stream result to write to + * @throws IOException if writing the templates fails + */ + private void save(TemplatePersistenceData[] templates, StreamResult result) { + try { + DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance(); + DocumentBuilder builder= factory.newDocumentBuilder(); + Document document= builder.newDocument(); + + Node root= document.createElement(TEMPLATE_ROOT); + document.appendChild(root); + + for (int i= 0; i < templates.length; i++) { + TemplatePersistenceData data= templates[i]; + Template template_= data.getTemplate(); + + Node node= document.createElement(TEMPLATE_ELEMENT); + root.appendChild(node); + + NamedNodeMap attributes= node.getAttributes(); + + String id= data.getId(); + if (id !is null) { + Attr idAttr= document.createAttribute(ID_ATTRIBUTE); + idAttr.setValue(id); + attributes.setNamedItem(idAttr); + } + + if (template_ !is null) { + Attr name= document.createAttribute(NAME_ATTRIBUTE); + name.setValue(template_.getName()); + attributes.setNamedItem(name); + } + + if (template_ !is null) { + Attr description= document.createAttribute(DESCRIPTION_ATTRIBUTE); + description.setValue(template_.getDescription()); + attributes.setNamedItem(description); + } + + if (template_ !is null) { + Attr context= document.createAttribute(CONTEXT_ATTRIBUTE); + context.setValue(template_.getContextTypeId()); + attributes.setNamedItem(context); + } + + Attr enabled= document.createAttribute(ENABLED_ATTRIBUTE); + enabled.setValue(data.isEnabled() ? Boolean.toString(true) : Boolean.toString(false)); + attributes.setNamedItem(enabled); + + Attr deleted= document.createAttribute(DELETED_ATTRIBUTE); + deleted.setValue(data.isDeleted() ? Boolean.toString(true) : Boolean.toString(false)); + attributes.setNamedItem(deleted); + + if (template_ !is null) { + Attr autoInsertable= document.createAttribute(AUTO_INSERTABLE_ATTRIBUTE); + autoInsertable.setValue(template_.isAutoInsertable() ? Boolean.toString(true) : Boolean.toString(false)); + attributes.setNamedItem(autoInsertable); + } + + if (template_ !is null) { + Text pattern= document.createTextNode(template_.getPattern()); + node.appendChild(pattern); + } + } + + + Transformer transformer=TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$ + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$ + DOMSource source = new DOMSource(document); + + transformer.transform(source, result); + + } catch (ParserConfigurationException e) { + Assert.isTrue(false); + } catch (TransformerException e) { + if (cast(IOException)e.getException() ) + throw cast(IOException) e.getException(); + Assert.isTrue(false); + } + } + + private bool getBooleanValue(NamedNodeMap attributes, String attribute, bool defaultValue) { + Node enabledNode= attributes.getNamedItem(attribute); + if (enabledNode is null) + return defaultValue; + else if (enabledNode.getNodeValue().equals(Boolean.toString(true))) + return true; + else if (enabledNode.getNodeValue().equals(Boolean.toString(false))) + return false; + else + throw new SAXException(TemplatePersistenceMessages.getString("TemplateReaderWriter.error.illegal_boolean_attribute")); //$NON-NLS-1$ + } + + private String getStringValue(NamedNodeMap attributes, String name) { + String val= getStringValue(attributes, name, null); + if (val is null) + throw new SAXException(TemplatePersistenceMessages.getString("TemplateReaderWriter.error.missing_attribute")); //$NON-NLS-1$ + return val; + } + + private String getStringValue(NamedNodeMap attributes, String name, String defaultValue) { + Node node= attributes.getNamedItem(name); + return node is null ? defaultValue : node.getNodeValue(); + } + + private String translateString(String str, ResourceBundle bundle) { + if (bundle is null) + return str; + + int idx= str.indexOf('%'); + if (idx is -1) { + return str; + } + StringBuffer buf= new StringBuffer(); + int k= 0; + while (idx !is -1) { + buf.append(str.substring(k, idx)); + for (k= idx + 1; k < str.length() && !Character.isWhitespace(str.charAt(k)); k++) { + // loop + } + String key= str.substring(idx + 1, k); + buf.append(getBundleString(key, bundle)); + idx= str.indexOf('%', k); + } + buf.append(str.substring(k)); + return buf.toString(); + } + + private String getBundleString(String key, ResourceBundle bundle) { + if (bundle !is null) { + try { + return bundle.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } + return TemplatePersistenceMessages.getString(key); // default messages + } +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/jface/text/templates/persistence/TemplateStore.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/templates/persistence/TemplateStore.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,463 @@ +/******************************************************************************* + * 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 + * 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.text.templates.persistence.TemplateStore; + +import dwtx.jface.text.templates.persistence.TemplatePersistenceData; // packageimport +import dwtx.jface.text.templates.persistence.TemplateReaderWriter; // packageimport +import dwtx.jface.text.templates.persistence.TemplatePersistenceMessages; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; + +import dwtx.core.runtime.Assert; +import dwtx.jface.preference.IPersistentPreferenceStore; +import dwtx.jface.preference.IPreferenceStore; +import dwtx.jface.text.templates.ContextTypeRegistry; +import dwtx.jface.text.templates.Template; +import dwtx.jface.text.templates.TemplateException; +import dwtx.jface.util.IPropertyChangeListener; +import dwtx.jface.util.PropertyChangeEvent; + +/** + * A collection of templates. Clients may instantiate this class. In order to + * load templates contributed using the dwtx.ui.editors.templates + * extension point, use a ContributionTemplateStore. + * + * @since 3.0 + */ +public class TemplateStore { + /** The stored templates. */ + private const List fTemplates= new ArrayList(); + /** The preference store. */ + private IPreferenceStore fPreferenceStore; + /** + * The key into fPreferenceStore the value of which holds custom templates + * encoded as XML. + */ + private String fKey; + /** + * The context type registry, or null if all templates regardless + * of context type should be loaded. + */ + private ContextTypeRegistry fRegistry; + /** + * Set to true if property change events should be ignored (e.g. during writing + * to the preference store). + * + * @since 3.2 + */ + private bool fIgnorePreferenceStoreChanges= false; + /** + * The property listener, if any is registered, null otherwise. + * + * @since 3.2 + */ + private IPropertyChangeListener fPropertyListener; + + + /** + * Creates a new template store. + * + * @param store the preference store in which to store custom templates + * under key + * @param key the key into store where to store custom + * templates + */ + public this(IPreferenceStore store, String key) { + Assert.isNotNull(store); + Assert.isNotNull(key); + fPreferenceStore= store; + fKey= key; + } + + /** + * Creates a new template store with a context type registry. Only templates + * that specify a context type contained in the registry will be loaded by + * this store if the registry is not null. + * + * @param registry a context type registry, or null if all + * templates should be loaded + * @param store the preference store in which to store custom templates + * under key + * @param key the key into store where to store custom + * templates + */ + public this(ContextTypeRegistry registry, IPreferenceStore store, String key) { + this(store, key); + fRegistry= registry; + } + + /** + * Loads the templates from contributions and preferences. + * + * @throws IOException if loading fails. + */ + public void load() { + fTemplates.clear(); + loadContributedTemplates(); + loadCustomTemplates(); + } + + /** + * Starts listening for property changes on the preference store. If the configured preference + * key changes, the template store is {@link #load() reloaded}. Call + * {@link #stopListeningForPreferenceChanges()} to remove any listener and stop the + * auto-updating behavior. + * + * @since 3.2 + */ + public final void startListeningForPreferenceChanges() { + if (fPropertyListener is null) { + fPropertyListener= new class() IPropertyChangeListener { + public void propertyChange(PropertyChangeEvent event) { + /* + * Don't load if we are in the process of saving ourselves. We are in sync anyway after the + * save operation, and clients may trigger reloading by listening to preference store + * updates. + */ + if (!fIgnorePreferenceStoreChanges && fKey.equals(event.getProperty())) + try { + load(); + } catch (IOException x) { + handleException(x); + } + } + }; + fPreferenceStore.addPropertyChangeListener(fPropertyListener); + } + + } + + /** + * Stops the auto-updating behavior started by calling + * {@link #startListeningForPreferenceChanges()}. + * + * @since 3.2 + */ + public final void stopListeningForPreferenceChanges() { + if (fPropertyListener !is null) { + fPreferenceStore.removePropertyChangeListener(fPropertyListener); + fPropertyListener= null; + } + } + + /** + * Handles an {@link IOException} thrown during reloading the preferences due to a preference + * store update. The default is to write to stderr. + * + * @param x the exception + * @since 3.2 + */ + protected void handleException(IOException x) { + x.printStackTrace(); + } + + /** + * Hook method to load contributed templates. Contributed templates are superseded + * by customized versions of user added templates stored in the preferences. + *

                        + * The default implementation does nothing.

                        + * + * @throws IOException if loading fails + */ + protected void loadContributedTemplates() { + } + + /** + * Adds a template to the internal store. The added templates must have + * a unique id. + * + * @param data the template data to add + */ + protected void internalAdd(TemplatePersistenceData data) { + if (!data.isCustom()) { + // check if the added template is not a duplicate id + String id= data.getId(); + for (Iterator it= fTemplates.iterator(); it.hasNext();) { + TemplatePersistenceData d2= cast(TemplatePersistenceData) it.next(); + if (d2.getId() !is null && d2.getId().equals(id)) + return; + } + fTemplates.add(data); + } + } + + /** + * Saves the templates to the preferences. + * + * @throws IOException if the templates cannot be written + */ + public void save() { + ArrayList custom= new ArrayList(); + for (Iterator it= fTemplates.iterator(); it.hasNext();) { + TemplatePersistenceData data= cast(TemplatePersistenceData) it.next(); + if (data.isCustom() && !(data.isUserAdded() && data.isDeleted())) // don't save deleted user-added templates + custom.add(data); + } + + StringWriter output= new StringWriter(); + TemplateReaderWriter writer= new TemplateReaderWriter(); + writer.save(arraycast!(TemplatePersistenceData)( custom.toArray()), output); + + fIgnorePreferenceStoreChanges= true; + try { + fPreferenceStore.setValue(fKey, output.toString()); + if ( cast(IPersistentPreferenceStore)fPreferenceStore ) + (cast(IPersistentPreferenceStore)fPreferenceStore).save(); + } finally { + fIgnorePreferenceStoreChanges= false; + } + } + + /** + * Adds a template encapsulated in its persistent form. + * + * @param data the template to add + */ + public void add(TemplatePersistenceData data) { + + if (!validateTemplate(data.getTemplate())) + return; + + if (data.isUserAdded()) { + fTemplates.add(data); + } else { + for (Iterator it= fTemplates.iterator(); it.hasNext();) { + TemplatePersistenceData d2= cast(TemplatePersistenceData) it.next(); + if (d2.getId() !is null && d2.getId().equals(data.getId())) { + d2.setTemplate(data.getTemplate()); + d2.setDeleted(data.isDeleted()); + d2.setEnabled(data.isEnabled()); + return; + } + } + + // add an id which is not contributed as add-on + if (data.getTemplate() !is null) { + TemplatePersistenceData newData= new TemplatePersistenceData(data.getTemplate(), data.isEnabled()); + fTemplates.add(newData); + } + } + } + + /** + * Removes a template from the store. + * + * @param data the template to remove + */ + public void delete_(TemplatePersistenceData data) { + if (data.isUserAdded()) + fTemplates.remove(data); + else + data.setDeleted(true); + } + + /** + * Restores all contributed templates that have been deleted. + */ + public void restoreDeleted() { + for (Iterator it= fTemplates.iterator(); it.hasNext();) { + TemplatePersistenceData data= cast(TemplatePersistenceData) it.next(); + if (data.isDeleted()) + data.setDeleted(false); + } + } + + /** + * Deletes all user-added templates and reverts all contributed templates. + */ + public void restoreDefaults() { + try { + fIgnorePreferenceStoreChanges= true; + fPreferenceStore.setToDefault(fKey); + } finally { + fIgnorePreferenceStoreChanges= false; + } + try { + load(); + } catch (IOException x) { + // can't log from jface-text + x.printStackTrace(); + } + } + + /** + * Returns all enabled templates. + * + * @return all enabled templates + */ + public Template[] getTemplates() { + return getTemplates(null); + } + + /** + * Returns all enabled templates for the given context type. + * + * @param contextTypeId the id of the context type of the requested templates, or null if all templates should be returned + * @return all enabled templates for the given context type + */ + public Template[] getTemplates(String contextTypeId) { + List templates= new ArrayList(); + for (Iterator it= fTemplates.iterator(); it.hasNext();) { + TemplatePersistenceData data= cast(TemplatePersistenceData) it.next(); + if (data.isEnabled() && !data.isDeleted() && (contextTypeId is null || contextTypeId.equals(data.getTemplate().getContextTypeId()))) + templates.add(data.getTemplate()); + } + + return arraycast!(Template)( templates.toArray()); + } + + /** + * Returns the first enabled template that matches the name. + * + * @param name the name of the template searched for + * @return the first enabled template that matches both name and context type id, or null if none is found + */ + public Template findTemplate(String name) { + return findTemplate(name, null); + } + + /** + * Returns the first enabled template that matches both name and context type id. + * + * @param name the name of the template searched for + * @param contextTypeId the context type id to clip unwanted templates, or null if any context type is OK + * @return the first enabled template that matches both name and context type id, or null if none is found + */ + public Template findTemplate(String name, String contextTypeId) { + Assert.isNotNull(name); + + for (Iterator it= fTemplates.iterator(); it.hasNext();) { + TemplatePersistenceData data= cast(TemplatePersistenceData) it.next(); + Template template_= data.getTemplate(); + if (data.isEnabled() && !data.isDeleted() + && (contextTypeId is null || contextTypeId.equals(template_.getContextTypeId())) + && name.equals(template_.getName())) + return template_; + } + + return null; + } + + /** + * Returns the first enabled template that matches the given template id. + * + * @param id the id of the template searched for + * @return the first enabled template that matches id, or null if none is found + * @since 3.1 + */ + public Template findTemplateById(String id) { + TemplatePersistenceData data= getTemplateData(id); + if (data !is null && !data.isDeleted()) + return data.getTemplate(); + + return null; + } + + /** + * Returns all template data. + * + * @param includeDeleted whether to include deleted data + * @return all template data, whether enabled or not + */ + public TemplatePersistenceData[] getTemplateData(bool includeDeleted) { + List datas= new ArrayList(); + for (Iterator it= fTemplates.iterator(); it.hasNext();) { + TemplatePersistenceData data= cast(TemplatePersistenceData) it.next(); + if (includeDeleted || !data.isDeleted()) + datas.add(data); + } + + return arraycast!(TemplatePersistenceData)( datas.toArray()); + } + + /** + * Returns the template data of the template with id id or + * null if no such template can be found. + * + * @param id the id of the template data + * @return the template data of the template with id id or null + * @since 3.1 + */ + public TemplatePersistenceData getTemplateData(String id) { + Assert.isNotNull(id); + for (Iterator it= fTemplates.iterator(); it.hasNext();) { + TemplatePersistenceData data= cast(TemplatePersistenceData) it.next(); + if (id.equals(data.getId())) + return data; + } + + return null; + } + + private void loadCustomTemplates() { + String pref= fPreferenceStore.getString(fKey); + if (pref !is null && pref.trim().length() > 0) { + Reader input= new StringReader(pref); + TemplateReaderWriter reader= new TemplateReaderWriter(); + TemplatePersistenceData[] datas= reader.read(input); + for (int i= 0; i < datas.length; i++) { + TemplatePersistenceData data= datas[i]; + add(data); + } + } + } + + /** + * Validates a template against the context type registered in the context + * type registry. Returns always true if no registry is + * present. + * + * @param template the template to validate + * @return true if validation is successful or no context + * type registry is specified, false if validation + * fails + */ + private bool validateTemplate(Template template_) { + String contextTypeId= template_.getContextTypeId(); + if (contextExists(contextTypeId)) { + if (fRegistry !is null) + try { + fRegistry.getContextType(contextTypeId).validate(template_.getPattern()); + } catch (TemplateException e) { + return false; + } + return true; + } + + return false; + } + + /** + * Returns true if a context type id specifies a valid context type + * or if no context type registry is present. + * + * @param contextTypeId the context type id to look for + * @return true if the context type specified by the id + * is present in the context type registry, or if no registry is + * specified + */ + private bool contextExists(String contextTypeId) { + return contextTypeId !is null && (fRegistry is null || fRegistry.getContextType(contextTypeId) !is null); + } + + /** + * Returns the registry. + * + * @return Returns the registry + */ + protected final ContextTypeRegistry getRegistry() { + return fRegistry; + } +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/org/osgi/framework/Bundle.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/org/osgi/framework/Bundle.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,1122 @@ +/* + * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/Bundle.java,v 1.54 2007/02/21 16:49:05 hargrave Exp $ + * + * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +module dwtx.org.osgi.framework.Bundle; + +import dwt.dwthelper.utils; + +// import java.io.IOException; +// import java.io.InputStream; +// import java.net.URL; +// import java.util.Dictionary; +// import java.util.Enumeration; + +/** + * An installed bundle in the Framework. + * + *

                        + * A Bundle object is the access point to define the lifecycle of + * an installed bundle. Each bundle installed in the OSGi environment must have + * an associated Bundle object. + * + *

                        + * A bundle must have a unique identity, a long, chosen by the + * Framework. This identity must not change during the lifecycle of a bundle, + * even when the bundle is updated. Uninstalling and then reinstalling the + * bundle must create a new unique identity. + * + *

                        + * A bundle can be in one of six states: + *

                          + *
                        • {@link #UNINSTALLED} + *
                        • {@link #INSTALLED} + *
                        • {@link #RESOLVED} + *
                        • {@link #STARTING} + *
                        • {@link #STOPPING} + *
                        • {@link #ACTIVE} + *
                        + *

                        + * Values assigned to these states have no specified ordering; they represent + * bit values that may be ORed together to determine if a bundle is in one of + * the valid states. + * + *

                        + * A bundle should only execute code when its state is one of + * STARTING,ACTIVE, or STOPPING. + * An UNINSTALLED bundle can not be set to another state; it is a + * zombie and can only be reached because references are kept somewhere. + * + *

                        + * The Framework is the only entity that is allowed to create + * Bundle objects, and these objects are only valid within the + * Framework that created them. + * + * @ThreadSafe + * @version $Revision: 1.54 $ + */ +public interface Bundle { + /** + * The bundle is uninstalled and may not be used. + * + *

                        + * The UNINSTALLED state is only visible after a bundle is + * uninstalled; the bundle is in an unusable state but references to the + * Bundle object may still be available and used for + * introspection. + *

                        + * The value of UNINSTALLED is 0x00000001. + */ + public static const int UNINSTALLED = 0x00000001; + + /** + * The bundle is installed but not yet resolved. + * + *

                        + * A bundle is in the INSTALLED state when it has been + * installed in the Framework but is not or cannot be resolved. + *

                        + * This state is visible if the bundle's code dependencies are not resolved. + * The Framework may attempt to resolve an INSTALLED bundle's + * code dependencies and move the bundle to the RESOLVED + * state. + *

                        + * The value of INSTALLED is 0x00000002. + */ + public static const int INSTALLED = 0x00000002; + + /** + * The bundle is resolved and is able to be started. + * + *

                        + * A bundle is in the RESOLVED state when the Framework has + * successfully resolved the bundle's code dependencies. These dependencies + * include: + *

                          + *
                        • The bundle's class path from its {@link Constants#BUNDLE_CLASSPATH} + * Manifest header. + *
                        • The bundle's package dependencies from its + * {@link Constants#EXPORT_PACKAGE} and {@link Constants#IMPORT_PACKAGE} + * Manifest headers. + *
                        • The bundle's required bundle dependencies from its + * {@link Constants#REQUIRE_BUNDLE} Manifest header. + *
                        • A fragment bundle's host dependency from its + * {@link Constants#FRAGMENT_HOST} Manifest header. + *
                        + *

                        + * Note that the bundle is not active yet. A bundle must be put in the + * RESOLVED state before it can be started. The Framework may + * attempt to resolve a bundle at any time. + *

                        + * The value of RESOLVED is 0x00000004. + */ + public static const int RESOLVED = 0x00000004; + + /** + * The bundle is in the process of starting. + * + *

                        + * A bundle is in the STARTING state when its + * {@link #start(int) start} method is active. A bundle must be in this + * state when the bundle's {@link BundleActivator#start} is called. If the + * BundleActivator.start method completes without exception, + * then the bundle has successfully started and must move to the + * ACTIVE state. + *

                        + * If the bundle has a + * {@link Constants#ACTIVATION_LAZY lazy activation policy}, then the + * bundle may remain in this state for some time until the activation is + * triggered. + *

                        + * The value of STARTING is 0x00000008. + */ + public static const int STARTING = 0x00000008; + + /** + * The bundle is in the process of stopping. + * + *

                        + * A bundle is in the STOPPING state when its + * {@link #stop(int) stop} method is active. A bundle must be in this state + * when the bundle's {@link BundleActivator#stop} method is called. When the + * BundleActivator.stop method completes the bundle is + * stopped and must move to the RESOLVED state. + *

                        + * The value of STOPPING is 0x00000010. + */ + public static const int STOPPING = 0x00000010; + + /** + * The bundle is now running. + * + *

                        + * A bundle is in the ACTIVE state when it has been + * successfully started and activated. + *

                        + * The value of ACTIVE is 0x00000020. + */ + public static const int ACTIVE = 0x00000020; + + /** + * The bundle start operation is transient and the persistent autostart + * setting of the bundle is not modified. + * + *

                        + * This bit may be set when calling {@link #start(int)} to notify the + * framework that the autostart setting of the bundle must not be modified. + * If this bit is not set, then the autostart setting of the bundle is + * modified. + * + * @since 1.4 + * @see #start(int) + */ + public static const int START_TRANSIENT = 0x00000001; + + /** + * The bundle start operation must activate the bundle according to the + * bundle's declared + * {@link Constants#BUNDLE_ACTIVATIONPOLICY activation policy}. + * + *

                        + * This bit may be set when calling {@link #start(int)} to notify the + * framework that the bundle must be activated using the bundle's declared + * activation policy. + * + * @since 1.4 + * @see Constants#BUNDLE_ACTIVATIONPOLICY + * @see #start(int) + */ + public static const int START_ACTIVATION_POLICY = 0x00000002; + + /** + * The bundle stop is transient and the persistent autostart setting of the + * bundle is not modified. + * + *

                        + * This bit may be set when calling {@link #stop(int)} to notify the + * framework that the autostart setting of the bundle must not be modified. + * If this bit is not set, then the autostart setting of the bundle is + * modified. + * + * @since 1.4 + * @see #stop(int) + */ + public static final int STOP_TRANSIENT = 0x00000001; + + /** + * Returns this bundle's current state. + * + *

                        + * A bundle can be in only one state at any time. + * + * @return An element of UNINSTALLED,INSTALLED, + * RESOLVED,STARTING, + * STOPPING,ACTIVE. + */ + public int getState(); + + /** + * Starts this bundle. + * + *

                        + * If this bundle's state is UNINSTALLED then an + * IllegalStateException is thrown. + *

                        + * If the Framework implements the optional Start Level service and the + * current start level is less than this bundle's start level: + *

                          + *
                        • If the {@link #START_TRANSIENT} option is set, then a + * BundleException is thrown indicating this bundle cannot be + * started due to the Framework's current start level. + * + *
                        • Otherwise, the Framework must set this bundle's persistent autostart + * setting to Started with declared activation if the + * {@link #START_ACTIVATION_POLICY} option is set or + * Started with eager activation if not set. + *
                        + *

                        + * When the Framework's current start level becomes equal to or more than + * this bundle's start level, this bundle will be started. + *

                        + * Otherwise, the following steps are required to start this bundle: + *

                          + *
                        1. If this bundle is in the process of being activated or deactivated + * then this method must wait for activation or deactivation to complete + * before continuing. If this does not occur in a reasonable time, a + * BundleException is thrown to indicate this bundle was + * unable to be started. + * + *
                        2. If this bundle's state is ACTIVE then this method + * returns immediately. + * + *
                        3. If the {@link #START_TRANSIENT} option is not set then set this + * bundle's autostart setting to Started with declared activation + * if the {@link #START_ACTIVATION_POLICY} option is set or + * Started with eager activation if not set. When the Framework + * is restarted and this bundle's autostart setting is not Stopped, + * this bundle must be automatically started. + * + *
                        4. If this bundle's state is not RESOLVED, an attempt + * is made to resolve this bundle. If the Framework cannot resolve this + * bundle, a BundleException is thrown. + * + *
                        5. If the {@link #START_ACTIVATION_POLICY} option is set and this + * bundle's declared activation policy is + * {@link Constants#ACTIVATION_LAZY lazy} then: + *
                            + *
                          • If this bundle's state is STARTING then this method + * returns immediately. + *
                          • This bundle's state is set to STARTING. + *
                          • A bundle event of type {@link BundleEvent#LAZY_ACTIVATION} is fired. + *
                          • This method returns immediately and the remaining steps will be + * followed when this bundle's activation is later triggered. + *
                          + * + *
                        6. This bundle's state is set to STARTING. + * + *
                        7. A bundle event of type {@link BundleEvent#STARTING} is fired. + * + *
                        8. The {@link BundleActivator#start} method of this bundle's + * BundleActivator, if one is specified, is called. If the + * BundleActivator is invalid or throws an exception then: + *
                            + *
                          • This bundle's state is set to STOPPING. + *
                          • A bundle event of type {@link BundleEvent#STOPPING} is fired. + *
                          • Any services registered by this bundle must be unregistered. + *
                          • Any services used by this bundle must be released. + *
                          • Any listeners registered by this bundle must be removed. + *
                          • This bundle's state is set to RESOLVED. + *
                          • A bundle event of type {@link BundleEvent#STOPPED} is fired. + *
                          • A BundleException is then thrown. + *
                          + * + *
                        9. If this bundle's state is UNINSTALLED, because this + * bundle was uninstalled while the BundleActivator.start + * method was running, a BundleException is thrown. + * + *
                        10. This bundle's state is set to ACTIVE. + * + *
                        11. A bundle event of type {@link BundleEvent#STARTED} is fired. + *
                        + * + * Preconditions + *
                          + *
                        • getState() in {INSTALLED, + * RESOLVED} or {INSTALLED, + * RESOLVED, STARTING} if this bundle has a + * lazy activation policy. + *
                        + * Postconditions, no exceptions thrown + *
                          + *
                        • Bundle autostart setting is modified unless the + * {@link #START_TRANSIENT} option was set. + *
                        • getState() in {ACTIVE} unless the + * lazy activation policy was used. + *
                        • BundleActivator.start() has been called and did not + * throw an exception unless the lazy activation policy was used. + *
                        + * Postconditions, when an exception is thrown + *
                          + *
                        • Depending on when the exception occurred, bundle autostart setting + * is modified unless the {@link #START_TRANSIENT} option was set. + *
                        • getState() not in {STARTING, + * ACTIVE}. + *
                        + * + * @param options The options for starting this bundle. See + * {@link #START_TRANSIENT} and {@link #START_ACTIVATION_POLICY}. + * The Framework must ignore unrecognized options. + * @throws BundleException If this bundle could not be started. This could + * be because a code dependency could not be resolved or the + * specified BundleActivator could not be loaded or + * threw an exception or this bundle is a fragment. + * @throws java.lang.IllegalStateException If this bundle has been + * uninstalled or this bundle tries to change its own state. + * @throws java.lang.SecurityException If the caller does not have the + * appropriate AdminPermission[this,EXECUTE], and + * the Java Runtime Environment supports permissions. + * @since 1.4 + */ + public void start(int options); + + /** + * Starts this bundle with no options. + * + *

                        + * This method calls start(0). + * + * @throws BundleException If this bundle could not be started. This could + * be because a code dependency could not be resolved or the + * specified BundleActivator could not be loaded or + * threw an exception or this bundle is a fragment. + * @throws java.lang.IllegalStateException If this bundle has been + * uninstalled or this bundle tries to change its own state. + * @throws java.lang.SecurityException If the caller does not have the + * appropriate AdminPermission[this,EXECUTE], and + * the Java Runtime Environment supports permissions. + * @see #start(int) + */ + public void start(); + + /** + * Stops this bundle. + * + *

                        + * The following steps are required to stop a bundle: + *

                          + *
                        1. If this bundle's state is UNINSTALLED then an + * IllegalStateException is thrown. + * + *
                        2. If this bundle is in the process of being activated or deactivated + * then this method must wait for activation or deactivation to complete + * before continuing. If this does not occur in a reasonable time, a + * BundleException is thrown to indicate this bundle was + * unable to be stopped. + *
                        3. If the {@link #STOP_TRANSIENT} option is not set then then set this + * bundle's persistent autostart setting to to Stopped. When the + * Framework is restarted and this bundle's autostart setting is + * Stopped, this bundle must not be automatically started. + * + *
                        4. If this bundle's state is not ACTIVE then this method + * returns immediately. + * + *
                        5. This bundle's state is set to STOPPING. + * + *
                        6. A bundle event of type {@link BundleEvent#STOPPING} is fired. + * + *
                        7. The {@link BundleActivator#stop} method of this bundle's + * BundleActivator, if one is specified, is called. If that + * method throws an exception, this method must continue to stop this + * bundle. A BundleException must be thrown after completion + * of the remaining steps. + * + *
                        8. Any services registered by this bundle must be unregistered. + *
                        9. Any services used by this bundle must be released. + *
                        10. Any listeners registered by this bundle must be removed. + * + *
                        11. If this bundle's state is UNINSTALLED, because this + * bundle was uninstalled while the BundleActivator.stop + * method was running, a BundleException must be thrown. + * + *
                        12. This bundle's state is set to RESOLVED. + * + *
                        13. A bundle event of type {@link BundleEvent#STOPPED} is fired. + *
                        + * + * Preconditions + *
                          + *
                        • getState() in {ACTIVE}. + *
                        + * Postconditions, no exceptions thrown + *
                          + *
                        • Bundle autostart setting is modified unless the + * {@link #STOP_TRANSIENT} option was set. + *
                        • getState() not in {ACTIVE, + * STOPPING}. + *
                        • BundleActivator.stop has been called and did not + * throw an exception. + *
                        + * Postconditions, when an exception is thrown + *
                          + *
                        • Bundle autostart setting is modified unless the + * {@link #STOP_TRANSIENT} option was set. + *
                        + * + * @param options The options for stoping this bundle. See + * {@link #STOP_TRANSIENT}. The Framework must ignore unrecognized + * options. + * @throws BundleException If this bundle's BundleActivator + * threw an exception or this bundle is a fragment. + * @throws java.lang.IllegalStateException If this bundle has been + * uninstalled or this bundle tries to change its own state. + * @throws java.lang.SecurityException If the caller does not have the + * appropriate AdminPermission[this,EXECUTE], and + * the Java Runtime Environment supports permissions. + * @since 1.4 + */ + public void stop(int options); + + /** + * Stops this bundle with no options. + * + *

                        + * This method calls stop(0). + * + * @throws BundleException If this bundle's BundleActivator + * threw an exception or this bundle is a fragment. + * @throws java.lang.IllegalStateException If this bundle has been + * uninstalled or this bundle tries to change its own state. + * @throws java.lang.SecurityException If the caller does not have the + * appropriate AdminPermission[this,EXECUTE], and + * the Java Runtime Environment supports permissions. + * @see #start(int) + */ + public void stop(); + + /** + * Updates this bundle. + * + *

                        + * If this bundle's state is ACTIVE, it must be stopped + * before the update and started after the update successfully completes. + * + *

                        + * If this bundle has exported any packages, these packages must not be + * updated. Instead, the previous package version must remain exported until + * the PackageAdmin.refreshPackages method has been has been + * called or the Framework is relaunched. + * + *

                        + * The following steps are required to update a bundle: + *

                          + *
                        1. If this bundle's state is UNINSTALLED then an + * IllegalStateException is thrown. + * + *
                        2. If this bundle's state is ACTIVE, + * STARTING or STOPPING, this bundle is + * stopped as described in the Bundle.stop method. If + * Bundle.stop throws an exception, the exception is rethrown + * terminating the update. + * + *
                        3. The download location of the new version of this bundle is + * determined from either this bundle's + * {@link Constants#BUNDLE_UPDATELOCATION} Manifest header (if available) or + * this bundle's original location. + * + *
                        4. The location is interpreted in an implementation dependent manner, + * typically as a URL, and the new version of this bundle is obtained from + * this location. + * + *
                        5. The new version of this bundle is installed. If the Framework is + * unable to install the new version of this bundle, the original version of + * this bundle must be restored and a BundleException must be + * thrown after completion of the remaining steps. + * + *
                        6. If this bundle has declared an Bundle-RequiredExecutionEnvironment + * header, then the listed execution environments must be verified against + * the installed execution environments. If they do not all match, the + * original version of this bundle must be restored and a + * BundleException must be thrown after completion of the + * remaining steps. + * + *
                        7. This bundle's state is set to INSTALLED. + * + *
                        8. If the new version of this bundle was successfully installed, a + * bundle event of type {@link BundleEvent#UPDATED} is fired. + * + *
                        9. If this bundle's state was originally ACTIVE, the + * updated bundle is started as described in the Bundle.start + * method. If Bundle.start throws an exception, a Framework + * event of type {@link FrameworkEvent#ERROR} is fired containing the + * exception. + *
                        + * + * Preconditions + *
                          + *
                        • getState() not in {UNINSTALLED}. + *
                        + * Postconditions, no exceptions thrown + *
                          + *
                        • getState() in {INSTALLED, + * RESOLVED,ACTIVE}. + *
                        • This bundle has been updated. + *
                        + * Postconditions, when an exception is thrown + *
                          + *
                        • getState() in {INSTALLED, + * RESOLVED,ACTIVE}. + *
                        • Original bundle is still used; no update occurred. + *
                        + * + * @throws BundleException If the update fails. + * @throws java.lang.IllegalStateException If this bundle has been + * uninstalled or this bundle tries to change its own state. + * @throws java.lang.SecurityException If the caller does not have the + * appropriate AdminPermission[this,LIFECYCLE] for + * both the current bundle and the updated bundle, and the Java + * Runtime Environment supports permissions. + * @see #stop() + * @see #start() + */ + public void update(); + +// /** +// * Updates this bundle from an InputStream. +// * +// *

                        +// * This method performs all the steps listed in Bundle.update(), +// * except the new version of this bundle must be read from the supplied +// * InputStream, rather than a URL. +// *

                        +// * This method must always close the InputStream when it is +// * done, even if an exception is thrown. +// * +// * @param in The InputStream from which to read the new +// * bundle. +// * @throws BundleException If the provided stream cannot be read or the +// * update fails. +// * @throws java.lang.IllegalStateException If this bundle has been +// * uninstalled or this bundle tries to change its own state. +// * @throws java.lang.SecurityException If the caller does not have the +// * appropriate AdminPermission[this,LIFECYCLE] for +// * both the current bundle and the updated bundle, and the Java +// * Runtime Environment supports permissions. +// * @see #update() +// */ +// public void update(InputStream in_); +// +// /** +// * Uninstalls this bundle. +// * +// *

                        +// * This method causes the Framework to notify other bundles that this bundle +// * is being uninstalled, and then puts this bundle into the +// * UNINSTALLED state. The Framework must remove any resources +// * related to this bundle that it is able to remove. +// * +// *

                        +// * If this bundle has exported any packages, the Framework must continue to +// * make these packages available to their importing bundles until the +// * PackageAdmin.refreshPackages method has been called or the +// * Framework is relaunched. +// * +// *

                        +// * The following steps are required to uninstall a bundle: +// *

                          +// *
                        1. If this bundle's state is UNINSTALLED then an +// * IllegalStateException is thrown. +// * +// *
                        2. If this bundle's state is ACTIVE, +// * STARTING or STOPPING, this bundle is +// * stopped as described in the Bundle.stop method. If +// * Bundle.stop throws an exception, a Framework event of type +// * {@link FrameworkEvent#ERROR} is fired containing the exception. +// * +// *
                        3. This bundle's state is set to UNINSTALLED. +// * +// *
                        4. A bundle event of type {@link BundleEvent#UNINSTALLED} is fired. +// * +// *
                        5. This bundle and any persistent storage area provided for this bundle +// * by the Framework are removed. +// *
                        +// * +// * Preconditions +// *
                          +// *
                        • getState() not in {UNINSTALLED}. +// *
                        +// * Postconditions, no exceptions thrown +// *
                          +// *
                        • getState() in {UNINSTALLED}. +// *
                        • This bundle has been uninstalled. +// *
                        +// * Postconditions, when an exception is thrown +// *
                          +// *
                        • getState() not in {UNINSTALLED}. +// *
                        • This Bundle has not been uninstalled. +// *
                        +// * +// * @throws BundleException If the uninstall failed. This can occur if +// * another thread is attempting to change this bundle's state and +// * does not complete in a timely manner. +// * @throws java.lang.IllegalStateException If this bundle has been +// * uninstalled or this bundle tries to change its own state. +// * @throws java.lang.SecurityException If the caller does not have the +// * appropriate AdminPermission[this,LIFECYCLE], and +// * the Java Runtime Environment supports permissions. +// * @see #stop() +// */ +// public void uninstall(); +// +// /** +// * Returns this bundle's Manifest headers and values. This method returns +// * all the Manifest headers and values from the main section of this +// * bundle's Manifest file; that is, all lines prior to the first blank line. +// * +// *

                        +// * Manifest header names are case-insensitive. The methods of the returned +// * Dictionary object must operate on header names in a +// * case-insensitive manner. +// * +// * If a Manifest header value starts with "%", it must be +// * localized according to the default locale. +// * +// *

                        +// * For example, the following Manifest headers and values are included if +// * they are present in the Manifest file: +// * +// *

                        +//      *     Bundle-Name
                        +//      *     Bundle-Vendor
                        +//      *     Bundle-Version
                        +//      *     Bundle-Description
                        +//      *     Bundle-DocURL
                        +//      *     Bundle-ContactAddress
                        +//      * 
                        +// * +// *

                        +// * This method must continue to return Manifest header information while +// * this bundle is in the UNINSTALLED state. +// * +// * @return A Dictionary object containing this bundle's +// * Manifest headers and values. +// * +// * @throws java.lang.SecurityException If the caller does not have the +// * appropriate AdminPermission[this,METADATA], and +// * the Java Runtime Environment supports permissions. +// * +// * @see Constants#BUNDLE_LOCALIZATION +// */ +// public Dictionary getHeaders(); +// +// /** +// * Returns this bundle's unique identifier. This bundle is assigned a unique +// * identifier by the Framework when it was installed in the OSGi +// * environment. +// * +// *

                        +// * A bundle's unique identifier has the following attributes: +// *

                          +// *
                        • Is unique and persistent. +// *
                        • Is a long. +// *
                        • Its value is not reused for another bundle, even after a bundle is +// * uninstalled. +// *
                        • Does not change while a bundle remains installed. +// *
                        • Does not change when a bundle is updated. +// *
                        +// * +// *

                        +// * This method must continue to return this bundle's unique identifier while +// * this bundle is in the UNINSTALLED state. +// * +// * @return The unique identifier of this bundle. +// */ +// public long getBundleId(); +// +// /** +// * Returns this bundle's location identifier. +// * +// *

                        +// * The location identifier is the location passed to +// * BundleContext.installBundle when a bundle is installed. +// * The location identifier does not change while this bundle remains +// * installed, even if this bundle is updated. +// * +// *

                        +// * This method must continue to return this bundle's location identifier +// * while this bundle is in the UNINSTALLED state. +// * +// * @return The string representation of this bundle's location identifier. +// * @throws java.lang.SecurityException If the caller does not have the +// * appropriate AdminPermission[this,METADATA], and +// * the Java Runtime Environment supports permissions. +// */ +// public String getLocation(); +// +// /** +// * Returns this bundle's ServiceReference list for all +// * services it has registered or null if this bundle has no +// * registered services. +// * +// *

                        +// * If the Java runtime supports permissions, a ServiceReference +// * object to a service is included in the returned list only if the caller +// * has the ServicePermission to get the service using at +// * least one of the named classes the service was registered under. +// * +// *

                        +// * The list is valid at the time of the call to this method, however, as the +// * Framework is a very dynamic environment, services can be modified or +// * unregistered at anytime. +// * +// * @return An array of ServiceReference objects or +// * null. +// * @throws java.lang.IllegalStateException If this bundle has been +// * uninstalled. +// * @see ServiceRegistration +// * @see ServiceReference +// * @see ServicePermission +// */ +// public ServiceReference[] getRegisteredServices(); +// +// /** +// * Returns this bundle's ServiceReference list for all +// * services it is using or returns null if this bundle is not +// * using any services. A bundle is considered to be using a service if its +// * use count for that service is greater than zero. +// * +// *

                        +// * If the Java Runtime Environment supports permissions, a +// * ServiceReference object to a service is included in the +// * returned list only if the caller has the ServicePermission +// * to get the service using at least one of the named classes the service +// * was registered under. +// *

                        +// * The list is valid at the time of the call to this method, however, as the +// * Framework is a very dynamic environment, services can be modified or +// * unregistered at anytime. +// * +// * @return An array of ServiceReference objects or +// * null. +// * @throws java.lang.IllegalStateException If this bundle has been +// * uninstalled. +// * @see ServiceReference +// * @see ServicePermission +// */ +// public ServiceReference[] getServicesInUse(); +// +// /** +// * Determines if this bundle has the specified permissions. +// * +// *

                        +// * If the Java Runtime Environment does not support permissions, this method +// * always returns true. +// *

                        +// * permission is of type Object to avoid +// * referencing the java.security.Permission class directly. +// * This is to allow the Framework to be implemented in Java environments +// * which do not support permissions. +// * +// *

                        +// * If the Java Runtime Environment does support permissions, this bundle and +// * all its resources including embedded JAR files, belong to the same +// * java.security.ProtectionDomain; that is, they must share +// * the same set of permissions. +// * +// * @param permission The permission to verify. +// * +// * @return true if this bundle has the specified permission +// * or the permissions possessed by this bundle imply the specified +// * permission; false if this bundle does not have the +// * specified permission or permission is not an +// * instanceof java.security.Permission. +// * +// * @throws java.lang.IllegalStateException If this bundle has been +// * uninstalled. +// */ +// public bool hasPermission(Object permission); +// +// /** +// * Find the specified resource from this bundle. +// * +// * This bundle's class loader is called to search for the specified +// * resource. If this bundle's state is INSTALLED, this +// * method must attempt to resolve this bundle before attempting to get the +// * specified resource. If this bundle cannot be resolved, then only this +// * bundle must be searched for the specified resource. Imported packages +// * cannot be searched when this bundle has not been resolved. If this bundle +// * is a fragment bundle then null is returned. +// * +// * @param name The name of the resource. See +// * java.lang.ClassLoader.getResource for a description +// * of the format of a resource name. +// * @return A URL to the named resource, or null if the +// * resource could not be found or if this bundle is a fragment +// * bundle or if the caller does not have the appropriate +// * AdminPermission[this,RESOURCE], and the Java +// * Runtime Environment supports permissions. +// * +// * @since 1.1 +// * @throws java.lang.IllegalStateException If this bundle has been +// * uninstalled. +// * @see #getEntry +// * @see #findEntries +// */ +// public URL getResource(String name); +// +// /** +// * Returns this bundle's Manifest headers and values localized to the +// * specified locale. +// * +// *

                        +// * This method performs the same function as +// * Bundle.getHeaders() except the manifest header values are +// * localized to the specified locale. +// * +// *

                        +// * If a Manifest header value starts with "%", it must be +// * localized according to the specified locale. If a locale is specified and +// * cannot be found, then the header values must be returned using the +// * default locale. Localizations are searched for in the following order: +// * +// *

                        +//      *   bn + "_" + Ls + "_" + Cs + "_" + Vs
                        +//      *   bn + "_" + Ls + "_" + Cs
                        +//      *   bn + "_" + Ls
                        +//      *   bn + "_" + Ld + "_" + Cd + "_" + Vd
                        +//      *   bn + "_" + Ld + "_" + Cd
                        +//      *   bn + "_" + Ld
                        +//      *     bn
                        +//      * 
                        +// * +// * Where bn is this bundle's localization basename, +// * Ls, Cs and Vs are the +// * specified locale (language, country, variant) and Ld, +// * Cd and Vd are the default locale (language, +// * country, variant). +// * +// * If null is specified as the locale string, the header +// * values must be localized using the default locale. If the empty string +// * ("") is specified as the locale string, the header values must +// * not be localized and the raw (unlocalized) header values, including any +// * leading "%", must be returned. +// * +// *

                        +// * This method must continue to return Manifest header information while +// * this bundle is in the UNINSTALLED state, however the +// * header values must only be available in the raw and default locale +// * values. +// * +// * @param locale The locale name into which the header values are to be +// * localized. If the specified locale is null then the +// * locale returned by java.util.Locale.getDefault is +// * used. If the specified locale is the empty string, this method +// * will return the raw (unlocalized) manifest headers including any +// * leading "%". +// * @return A Dictionary object containing this bundle's +// * Manifest headers and values. +// * +// * @throws java.lang.SecurityException If the caller does not have the +// * appropriate AdminPermission[this,METADATA], and +// * the Java Runtime Environment supports permissions. +// * +// * @see #getHeaders() +// * @see Constants#BUNDLE_LOCALIZATION +// * @since 1.3 +// */ +// public Dictionary getHeaders(String locale); +// +// /** +// * Returns the symbolic name of this bundle as specified by its +// * Bundle-SymbolicName manifest header. The name must be +// * unique, it is recommended to use a reverse domain name naming convention +// * like that used for java packages. If this bundle does not have a +// * specified symbolic name then null is returned. +// * +// *

                        +// * This method must continue to return this bundle's symbolic name while +// * this bundle is in the UNINSTALLED state. +// * +// * @return The symbolic name of this bundle. +// * @since 1.3 +// */ +// public String getSymbolicName(); +// +// /** +// * Loads the specified class using this bundle's classloader. +// * +// *

                        +// * If this bundle is a fragment bundle then this method must throw a +// * ClassNotFoundException. +// * +// *

                        +// * If this bundle's state is INSTALLED, this method must +// * attempt to resolve this bundle before attempting to load the class. +// * +// *

                        +// * If this bundle cannot be resolved, a Framework event of type +// * {@link FrameworkEvent#ERROR} is fired containing a +// * BundleException with details of the reason this bundle +// * could not be resolved. This method must then throw a +// * ClassNotFoundException. +// * +// *

                        +// * If this bundle's state is UNINSTALLED, then an +// * IllegalStateException is thrown. +// * +// * @param name The name of the class to load. +// * @return The Class object for the requested class. +// * @throws java.lang.ClassNotFoundException If no such class can be found or +// * if this bundle is a fragment bundle or if the caller does not +// * have the appropriate AdminPermission[this,CLASS], +// * and the Java Runtime Environment supports permissions. +// * @throws java.lang.IllegalStateException If this bundle has been +// * uninstalled. +// * @since 1.3 +// */ +// public Class loadClass(String name) throws ClassNotFoundException; +// +// /** +// * Find the specified resources from this bundle. +// * +// * This bundle's class loader is called to search for the specified +// * resources. If this bundle's state is INSTALLED, this +// * method must attempt to resolve this bundle before attempting to get the +// * specified resources. If this bundle cannot be resolved, then only this +// * bundle must be searched for the specified resources. Imported packages +// * cannot be searched when a bundle has not been resolved. If this bundle is +// * a fragment bundle then null is returned. +// * +// * @param name The name of the resource. See +// * java.lang.ClassLoader.getResources for a +// * description of the format of a resource name. +// * @return An enumeration of URLs to the named resources, or +// * null if the resource could not be found or if this +// * bundle is a fragment bundle or if the caller does not have the +// * appropriate AdminPermission[this,RESOURCE], and +// * the Java Runtime Environment supports permissions. +// * +// * @since 1.3 +// * @throws java.lang.IllegalStateException If this bundle has been +// * uninstalled. +// * @throws java.io.IOException If there is an I/O error. +// */ +// public Enumeration getResources(String name) throws IOException; +// +// /** +// * Returns an Enumeration of all the paths (String objects) +// * to entries within this bundle whose longest sub-path matches the +// * specified path. This bundle's classloader is not used to search for +// * entries. Only the contents of this bundle are searched. +// *

                        +// * The specified path is always relative to the root of this bundle and may +// * begin with a "/". A path value of "/" indicates the +// * root of this bundle. +// *

                        +// * Returned paths indicating subdirectory paths end with a "/". +// * The returned paths are all relative to the root of this bundle and must +// * not begin with "/". +// * +// * @param path The path name for which to return entry paths. +// * @return An Enumeration of the entry paths (String +// * objects) or null if no entry could be found or if +// * the caller does not have the appropriate +// * AdminPermission[this,RESOURCE] and the Java +// * Runtime Environment supports permissions. +// * @throws java.lang.IllegalStateException If this bundle has been +// * uninstalled. +// * @since 1.3 +// */ +// public Enumeration getEntryPaths(String path); +// +// /** +// * Returns a URL to the entry at the specified path in this bundle. This +// * bundle's classloader is not used to search for the entry. Only the +// * contents of this bundle are searched for the entry. +// *

                        +// * The specified path is always relative to the root of this bundle and may +// * begin with "/". A path value of "/" indicates the +// * root of this bundle. +// * +// * @param path The path name of the entry. +// * @return A URL to the entry, or null if no entry could be +// * found or if the caller does not have the appropriate +// * AdminPermission[this,RESOURCE] and the Java +// * Runtime Environment supports permissions. +// * +// * @throws java.lang.IllegalStateException If this bundle has been +// * uninstalled. +// * @since 1.3 +// */ +// public URL getEntry(String path); +// +// /** +// * Returns the time when this bundle was last modified. A bundle is +// * considered to be modified when it is installed, updated or uninstalled. +// * +// *

                        +// * The time value is the number of milliseconds since January 1, 1970, +// * 00:00:00 GMT. +// * +// * @return The time when this bundle was last modified. +// * @since 1.3 +// */ +// public long getLastModified(); +// +// /** +// * Returns entries in this bundle and its attached fragments. This bundle's +// * classloader is not used to search for entries. Only the contents of this +// * bundle and its attached fragments are searched for the specified entries. +// * +// * If this bundle's state is INSTALLED, this method must +// * attempt to resolve this bundle before attempting to find entries. +// * +// *

                        +// * This method is intended to be used to obtain configuration, setup, +// * localization and other information from this bundle. This method takes +// * into account that the "contents" of this bundle can be extended +// * with fragments. This "bundle space" is not a namespace with +// * unique members; the same entry name can be present multiple times. This +// * method therefore returns an enumeration of URL objects. These URLs can +// * come from different JARs but have the same path name. This method can +// * either return only entries in the specified path or recurse into +// * subdirectories returning entries in the directory tree beginning at the +// * specified path. Fragments can be attached after this bundle is resolved, +// * possibly changing the set of URLs returned by this method. If this bundle +// * is not resolved, only the entries in the JAR file of this bundle are +// * returned. +// *

                        +// * Examples: +// * +// *

                        +//      * // List all XML files in the OSGI-INF directory and below
                        +//      * Enumeration e = b.findEntries("OSGI-INF", "*.xml", true);
                        +//      *
                        +//      * // Find a specific localization file
                        +//      * Enumeration e = b.findEntries("OSGI-INF/l10n",
                        +//      *                               "bundle_nl_DU.properties",
                        +//      *                               false);
                        +//      * if (e.hasMoreElements())
                        +//      *  return (URL) e.nextElement();
                        +//      * 
                        +// * +// * @param path The path name in which to look. The path is always relative +// * to the root of this bundle and may begin with "/". A +// * path value of "/" indicates the root of this bundle. +// * @param filePattern The file name pattern for selecting entries in the +// * specified path. The pattern is only matched against the last +// * element of the entry path and it supports substring matching, as +// * specified in the Filter specification, using the wildcard +// * character ("*"). If null is specified, this is +// * equivalent to "*" and matches all files. +// * @param recurse If true, recurse into subdirectories. +// * Otherwise only return entries from the specified path. +// * @return An enumeration of URL objects for each matching entry, or +// * null if an entry could not be found or if the +// * caller does not have the appropriate +// * AdminPermission[this,RESOURCE], and the Java +// * Runtime Environment supports permissions. The URLs are sorted +// * such that entries from this bundle are returned first followed by +// * the entries from attached fragments in ascending bundle id order. +// * If this bundle is a fragment, then only matching entries in this +// * fragment are returned. +// * @since 1.3 +// */ +// public Enumeration findEntries(String path, String filePattern, +// bool recurse); +// +// /** +// * Returns this bundle's {@link BundleContext}. The returned +// * BundleContext can be used by the caller to act on behalf +// * of this bundle. +// * +// *

                        +// * If this bundle is not in the {@link #STARTING}, {@link #ACTIVE}, or +// * {@link #STOPPING} states or this bundle is a fragment bundle, then this +// * bundle has no valid BundleContext. This method will +// * return null if this bundle has no valid +// * BundleContext. +// * +// * @return A BundleContext for this bundle or +// * null if this bundle has no valid +// * BundleContext. +// * @throws java.lang.SecurityException If the caller does not have the +// * appropriate AdminPermission[this,CONTEXT], and +// * the Java Runtime Environment supports permissions. +// * @since 1.4 +// */ +// public BundleContext getBundleContext(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/CopySourceEdit.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/CopySourceEdit.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,336 @@ +/******************************************************************************* + * 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 + * 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.text.edits.CopySourceEdit; + +import dwtx.text.edits.MoveSourceEdit; // packageimport +import dwtx.text.edits.MoveTargetEdit; // packageimport +import dwtx.text.edits.CopyTargetEdit; // packageimport +import dwtx.text.edits.TextEditCopier; // packageimport +import dwtx.text.edits.ISourceModifier; // packageimport +import dwtx.text.edits.TextEditProcessor; // packageimport +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.TextEdit; // packageimport +import dwtx.text.edits.RangeMarker; // packageimport +import dwtx.text.edits.InsertEdit; // packageimport +import dwtx.text.edits.DeleteEdit; // packageimport +import dwtx.text.edits.MalformedTreeException; // packageimport +import dwtx.text.edits.TextEditMessages; // packageimport +import dwtx.text.edits.MultiTextEdit; // packageimport +import dwtx.text.edits.EditDocument; // packageimport +import dwtx.text.edits.ReplaceEdit; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; + +/** + * A copy source edit denotes the source of a copy operation. Copy + * source edits are only valid inside an edit tree if they have a + * corresponding target edit. Furthermore the corresponding + * target edit can't be a direct or indirect child of the source + * edit. Violating one of two requirements will result in a + * MalformedTreeException when executing the edit tree. + *

                        + * A copy source edit can manage an optional source modifier. A + * source modifier can provide a set of replace edits which will + * to applied to the source before it gets inserted at the target + * position. + * + * @see dwtx.text.edits.CopyTargetEdit + * + * @since 3.0 + */ +public final class CopySourceEdit : TextEdit { + + private CopyTargetEdit fTarget; + private ISourceModifier fModifier; + + private String fSourceContent; + private TextEdit fSourceRoot; + + private static class PartialCopier : TextEditVisitor { + TextEdit fResult; + List fParents; + TextEdit fCurrentParent; + public this(){ + fParents= new ArrayList(); + } + public static TextEdit perform(TextEdit source) { + PartialCopier copier= new PartialCopier(); + source.accept(copier); + return copier.fResult; + } + private void manageCopy(TextEdit copy) { + if (fResult is null) + fResult= copy; + if (fCurrentParent !is null) { + fCurrentParent.addChild(copy); + } + fParents.add(fCurrentParent); + fCurrentParent= copy; + } + public void postVisit(TextEdit edit) { + fCurrentParent= cast(TextEdit)fParents.remove(fParents.size() - 1); + } + public bool visitNode(TextEdit edit) { + manageCopy(edit.doCopy_package()); + return true; + } + public bool visit(CopySourceEdit edit) { + manageCopy(new RangeMarker(edit.getOffset(), edit.getLength())); + return true; + } + public bool visit(CopyTargetEdit edit) { + manageCopy(new InsertEdit(edit.getOffset(), edit.getSourceEdit().getContent())); + return true; + } + public bool visit(MoveSourceEdit edit) { + manageCopy(new DeleteEdit(edit.getOffset(), edit.getLength())); + return true; + } + public bool visit(MoveTargetEdit edit) { + manageCopy(new InsertEdit(edit.getOffset(), edit.getSourceEdit().getContent())); + return true; + } + } + + /** + * Constructs a new copy source edit. + * + * @param offset the edit's offset + * @param length the edit's length + */ + public this(int offset, int length) { + super(offset, length); + } + + /** + * Constructs a new copy source edit. + * + * @param offset the edit's offset + * @param length the edit's length + * @param target the edit's target + */ + public this(int offset, int length, CopyTargetEdit target) { + this(offset, length); + setTargetEdit(target); + } + + /* + * Copy Constructor + */ + private this(CopySourceEdit other) { + super(other); + if (other.fModifier !is null) + fModifier= other.fModifier.copy(); + } + + /** + * Returns the associated target edit or null + * if no target edit is associated yet. + * + * @return the target edit or null + */ + public CopyTargetEdit getTargetEdit() { + return fTarget; + } + + /** + * Sets the target edit. + * + * @param edit the new target edit. + * + * @exception MalformedTreeException is thrown if the target edit + * is a direct or indirect child of the source edit + */ + public void setTargetEdit(CopyTargetEdit edit) { + Assert.isNotNull(edit); + if (fTarget !is edit) { + fTarget= edit; + fTarget.setSourceEdit(this); + } + } + + /** + * Returns the current source modifier or null + * if no source modifier is set. + * + * @return the source modifier + */ + public ISourceModifier getSourceModifier() { + return fModifier; + } + + /** + * Sets the optional source modifier. + * + * @param modifier the source modifier or null + * if no source modification is need. + */ + public void setSourceModifier(ISourceModifier modifier) { + fModifier= modifier; + } + + /* + * @see TextEdit#doCopy + */ + protected TextEdit doCopy() { + return new CopySourceEdit(this); + } + + /* + * @see TextEdit#accept0 + */ + protected void accept0(TextEditVisitor visitor) { + bool visitChildren= visitor.visit(this); + if (visitChildren) { + acceptChildren(visitor); + } + } + + //---- API for CopyTargetEdit ------------------------------------------------ + + String getContent() { + // The source content can be null if the edit wasn't executed + // due to an exclusion list of the text edit processor. Return + // the empty string which can be moved without any harm. + if (fSourceContent is null) + return ""; //$NON-NLS-1$ + return fSourceContent; + } + + void clearContent() { + fSourceContent= null; + } + + /* + * @see TextEdit#postProcessCopy + */ + protected void postProcessCopy(TextEditCopier copier) { + if (fTarget !is null) { + CopySourceEdit source= cast(CopySourceEdit)copier.getCopy(this); + CopyTargetEdit target= cast(CopyTargetEdit)copier.getCopy(fTarget); + if (source !is null && target !is null) + source.setTargetEdit(target); + } + } + + //---- consistency check ---------------------------------------------------- + + int traverseConsistencyCheck(TextEditProcessor processor, IDocument document, List sourceEdits) { + int result= super.traverseConsistencyCheck(processor, document, sourceEdits); + // Since source computation takes place in a recursive fashion (see + // performSourceComputation) we only do something if we don't have a + // computed source already. + if (fSourceContent is null) { + if (sourceEdits.size() <= result) { + List list= new ArrayList(); + list.add(this); + for (int i= sourceEdits.size(); i < result; i++) + sourceEdits.add(cast(Object)null); + sourceEdits.add(cast(Object)list); + } else { + List list= cast(List)sourceEdits.get(result); + if (list is null) { + list= new ArrayList(); + sourceEdits.add(result, cast(Object)list); + } + list.add(this); + } + } + return result; + } + + void performConsistencyCheck(TextEditProcessor processor, IDocument document) { + if (fTarget is null) + throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("CopySourceEdit.no_target")); //$NON-NLS-1$ + if (fTarget.getSourceEdit() !is this) + throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("CopySourceEdit.different_source")); //$NON-NLS-1$ + /* causes ASTRewrite to fail + if (getRoot() !is fTarget.getRoot()) + throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("CopySourceEdit.different_tree")); //$NON-NLS-1$ + */ + } + + //---- source computation ------------------------------------------------------- + + void traverseSourceComputation(TextEditProcessor processor, IDocument document) { + // always perform source computation independent of processor.considerEdit + // The target might need the source and the source is computed in a + // temporary buffer. + performSourceComputation(processor, document); + } + + void performSourceComputation(TextEditProcessor processor, IDocument document) { + try { + MultiTextEdit root= new MultiTextEdit(getOffset(), getLength()); + root.internalSetChildren(internalGetChildren()); + fSourceContent= document.get(getOffset(), getLength()); + fSourceRoot= PartialCopier.perform(root); + fSourceRoot.internalMoveTree(-getOffset()); + if (fSourceRoot.hasChildren()) { + EditDocument subDocument= new EditDocument(fSourceContent); + TextEditProcessor subProcessor= TextEditProcessor.createSourceComputationProcessor(subDocument, fSourceRoot, TextEdit.NONE); + subProcessor.performEdits(); + if (needsTransformation()) + applyTransformation(subDocument); + fSourceContent= subDocument.get(); + fSourceRoot= null; + } else { + if (needsTransformation()) { + EditDocument subDocument= new EditDocument(fSourceContent); + applyTransformation(subDocument); + fSourceContent= subDocument.get(); + } + } + } catch (BadLocationException cannotHappen) { + Assert.isTrue(false); + } + } + + private bool needsTransformation() { + return fModifier !is null; + } + + private void applyTransformation(IDocument document) { + TextEdit newEdit= new MultiTextEdit(0, document.getLength()); + ReplaceEdit[] replaces= fModifier.getModifications(document.get()); + for (int i= 0; i < replaces.length; i++) { + newEdit.addChild(replaces[i]); + } + try { + newEdit.apply(document, TextEdit.NONE); + } catch (BadLocationException cannotHappen) { + Assert.isTrue(false); + } + } + + //---- document updating ---------------------------------------------------------------- + + int performDocumentUpdating(IDocument document) { + fDelta= 0; + return fDelta; + } + + //---- region updating ---------------------------------------------------------------- + + /* + * @see TextEdit#deleteChildren + */ + bool deleteChildren() { + return false; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/CopyTargetEdit.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/CopyTargetEdit.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,188 @@ +/******************************************************************************* + * 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 + * 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.text.edits.CopyTargetEdit; + +import dwtx.text.edits.MultiTextEdit; // packageimport +import dwtx.text.edits.CopySourceEdit; // packageimport +import dwtx.text.edits.MoveSourceEdit; // packageimport +import dwtx.text.edits.CopyingRangeMarker; // packageimport +import dwtx.text.edits.ReplaceEdit; // packageimport +import dwtx.text.edits.EditDocument; // packageimport +import dwtx.text.edits.UndoCollector; // packageimport +import dwtx.text.edits.DeleteEdit; // packageimport +import dwtx.text.edits.MoveTargetEdit; // packageimport +import dwtx.text.edits.TextEditCopier; // packageimport +import dwtx.text.edits.ISourceModifier; // packageimport +import dwtx.text.edits.TextEditMessages; // packageimport +import dwtx.text.edits.TextEditProcessor; // packageimport +import dwtx.text.edits.MalformedTreeException; // packageimport +import dwtx.text.edits.TreeIterationInfo; // packageimport +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.TextEditGroup; // packageimport +import dwtx.text.edits.TextEdit; // packageimport +import dwtx.text.edits.RangeMarker; // packageimport +import dwtx.text.edits.UndoEdit; // packageimport +import dwtx.text.edits.InsertEdit; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; + +/** + * A copy target edit denotes the target of a copy operation. Copy + * target edits are only valid inside an edit tree if they have a + * corresponding source edit. Furthermore a target edit can't + * can't be a direct or indirect child of the associated source edit. + * Violating one of two requirements will result in a + * MalformedTreeException when executing the edit tree. + *

                        + * Copy target edits can't be used as a parent for other edits. + * Trying to add an edit to a copy target edit results in a + * MalformedTreeException as well. + * + * @see dwtx.text.edits.CopySourceEdit + * + * @since 3.0 + */ +public final class CopyTargetEdit : TextEdit { + + private CopySourceEdit fSource; + + /** + * Constructs a new copy target edit + * + * @param offset the edit's offset + */ + public this(int offset) { + super(offset, 0); + } + + /** + * Constructs an new copy target edit + * + * @param offset the edit's offset + * @param source the corresponding source edit + */ + public this(int offset, CopySourceEdit source) { + this(offset); + setSourceEdit(source); + } + + /* + * Copy constructor + */ + private this(CopyTargetEdit other) { + super(other); + } + + /** + * Returns the associated source edit or null + * if no source edit is associated yet. + * + * @return the source edit or null + */ + public CopySourceEdit getSourceEdit() { + return fSource; + } + + /** + * Sets the source edit. + * + * @param edit the source edit + * + * @exception MalformedTreeException is thrown if the target edit + * is a direct or indirect child of the source edit + */ + public void setSourceEdit(CopySourceEdit edit) { + Assert.isNotNull(edit); + if (fSource !is edit) { + fSource= edit; + fSource.setTargetEdit(this); + TextEdit parent= getParent(); + while (parent !is null) { + if (parent is fSource) + throw new MalformedTreeException(parent, this, TextEditMessages.getString("CopyTargetEdit.wrong_parent")); //$NON-NLS-1$ + parent= parent.getParent(); + } + } + } + + /* + * @see TextEdit#doCopy + */ + protected TextEdit doCopy() { + return new CopyTargetEdit(this); + } + + /* + * @see TextEdit#postProcessCopy + */ + protected void postProcessCopy(TextEditCopier copier) { + if (fSource !is null) { + CopyTargetEdit target= cast(CopyTargetEdit)copier.getCopy(this); + CopySourceEdit source= cast(CopySourceEdit)copier.getCopy(fSource); + if (target !is null && source !is null) + target.setSourceEdit(source); + } + } + + /* + * @see TextEdit#accept0 + */ + protected void accept0(TextEditVisitor visitor) { + bool visitChildren= visitor.visit(this); + if (visitChildren) { + acceptChildren(visitor); + } + } + + /* + * @see TextEdit#traverseConsistencyCheck + */ + int traverseConsistencyCheck(TextEditProcessor processor, IDocument document, List sourceEdits) { + return super.traverseConsistencyCheck(processor, document, sourceEdits) + 1; + } + + /* + * @see TextEdit#performConsistencyCheck + */ + void performConsistencyCheck(TextEditProcessor processor, IDocument document) { + if (fSource is null) + throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("CopyTargetEdit.no_source")); //$NON-NLS-1$ + if (fSource.getTargetEdit() !is this) + throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("CopyTargetEdit.different_target")); //$NON-NLS-1$ + } + + /* + * @see TextEdit#performDocumentUpdating + */ + int performDocumentUpdating(IDocument document) { + String source= fSource.getContent(); + document.replace(getOffset(), getLength(), source); + fDelta= source.length() - getLength(); + fSource.clearContent(); + return fDelta; + } + + /* + * @see TextEdit#deleteChildren + */ + bool deleteChildren() { + return false; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/CopyingRangeMarker.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/CopyingRangeMarker.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,105 @@ +/******************************************************************************* + * 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 + * 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.text.edits.CopyingRangeMarker; + +import dwtx.text.edits.MultiTextEdit; // packageimport +import dwtx.text.edits.CopySourceEdit; // packageimport +import dwtx.text.edits.MoveSourceEdit; // packageimport +import dwtx.text.edits.ReplaceEdit; // packageimport +import dwtx.text.edits.EditDocument; // packageimport +import dwtx.text.edits.UndoCollector; // packageimport +import dwtx.text.edits.DeleteEdit; // packageimport +import dwtx.text.edits.MoveTargetEdit; // packageimport +import dwtx.text.edits.CopyTargetEdit; // packageimport +import dwtx.text.edits.TextEditCopier; // packageimport +import dwtx.text.edits.ISourceModifier; // packageimport +import dwtx.text.edits.TextEditMessages; // packageimport +import dwtx.text.edits.TextEditProcessor; // packageimport +import dwtx.text.edits.MalformedTreeException; // packageimport +import dwtx.text.edits.TreeIterationInfo; // packageimport +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.TextEditGroup; // packageimport +import dwtx.text.edits.TextEdit; // packageimport +import dwtx.text.edits.RangeMarker; // packageimport +import dwtx.text.edits.UndoEdit; // packageimport +import dwtx.text.edits.InsertEdit; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; + +/** + * A CopyingRangeMarker can be used to track positions when executing + * text edits. Additionally a copying range marker stores a local copy of the + * text it captures when it gets executed. + * + * @since 3.0 + */ +public final class CopyingRangeMarker : TextEdit { + + private String fText; + + /** + * Creates a new CopyRangeMarker for the given + * offset and length. + * + * @param offset the marker's offset + * @param length the marker's length + */ + public this(int offset, int length) { + super(offset, length); + } + + /* + * Copy constructor + */ + private this(CopyingRangeMarker other) { + super(other); + fText= other.fText; + } + + /* + * @see TextEdit#doCopy + */ + protected TextEdit doCopy() { + return new CopyingRangeMarker(this); + } + + /* + * @see TextEdit#accept0 + */ + protected void accept0(TextEditVisitor visitor) { + bool visitChildren= visitor.visit(this); + if (visitChildren) { + acceptChildren(visitor); + } + } + + /* + * @see TextEdit#performDocumentUpdating + */ + int performDocumentUpdating(IDocument document) { + fText= document.get(getOffset(), getLength()); + fDelta= 0; + return fDelta; + } + + /* + * @see TextEdit#deleteChildren + */ + bool deleteChildren() { + return false; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/DeleteEdit.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/DeleteEdit.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,102 @@ +/******************************************************************************* + * 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 + * 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.text.edits.DeleteEdit; + +import dwtx.text.edits.MultiTextEdit; // packageimport +import dwtx.text.edits.CopySourceEdit; // packageimport +import dwtx.text.edits.MoveSourceEdit; // packageimport +import dwtx.text.edits.CopyingRangeMarker; // packageimport +import dwtx.text.edits.ReplaceEdit; // packageimport +import dwtx.text.edits.EditDocument; // packageimport +import dwtx.text.edits.UndoCollector; // packageimport +import dwtx.text.edits.MoveTargetEdit; // packageimport +import dwtx.text.edits.CopyTargetEdit; // packageimport +import dwtx.text.edits.TextEditCopier; // packageimport +import dwtx.text.edits.ISourceModifier; // packageimport +import dwtx.text.edits.TextEditMessages; // packageimport +import dwtx.text.edits.TextEditProcessor; // packageimport +import dwtx.text.edits.MalformedTreeException; // packageimport +import dwtx.text.edits.TreeIterationInfo; // packageimport +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.TextEditGroup; // packageimport +import dwtx.text.edits.TextEdit; // packageimport +import dwtx.text.edits.RangeMarker; // packageimport +import dwtx.text.edits.UndoEdit; // packageimport +import dwtx.text.edits.InsertEdit; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; + +/** + * Text edit to delete a range in a document. + *

                        + * A delete edit is equivalent to ReplaceEdit( + * offset, length, ""). + * + * @since 3.0 + */ +public final class DeleteEdit : TextEdit { + + /** + * Constructs a new delete edit. + * + * @param offset the offset of the range to replace + * @param length the length of the range to replace + */ + public this(int offset, int length) { + super(offset, length); + } + + /* + * Copy constructor + */ + private this(DeleteEdit other) { + super(other); + } + + /* + * @see TextEdit#doCopy + */ + protected TextEdit doCopy() { + return new DeleteEdit(this); + } + + /* + * @see TextEdit#accept0 + */ + protected void accept0(TextEditVisitor visitor) { + bool visitChildren= visitor.visit(this); + if (visitChildren) { + acceptChildren(visitor); + } + } + + /* + * @see TextEdit#performDocumentUpdating + */ + int performDocumentUpdating(IDocument document) { + document.replace(getOffset(), getLength(), ""); //$NON-NLS-1$ + fDelta= -getLength(); + return fDelta; + } + + /* + * @see TextEdit#deleteChildren + */ + bool deleteChildren() { + return true; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/EditDocument.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/EditDocument.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,235 @@ +/******************************************************************************* + * 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 + * 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.text.edits.EditDocument; + +import dwtx.text.edits.MultiTextEdit; // packageimport +import dwtx.text.edits.CopySourceEdit; // packageimport +import dwtx.text.edits.MoveSourceEdit; // packageimport +import dwtx.text.edits.CopyingRangeMarker; // packageimport +import dwtx.text.edits.ReplaceEdit; // packageimport +import dwtx.text.edits.UndoCollector; // packageimport +import dwtx.text.edits.DeleteEdit; // packageimport +import dwtx.text.edits.MoveTargetEdit; // packageimport +import dwtx.text.edits.CopyTargetEdit; // packageimport +import dwtx.text.edits.TextEditCopier; // packageimport +import dwtx.text.edits.ISourceModifier; // packageimport +import dwtx.text.edits.TextEditMessages; // packageimport +import dwtx.text.edits.TextEditProcessor; // packageimport +import dwtx.text.edits.MalformedTreeException; // packageimport +import dwtx.text.edits.TreeIterationInfo; // packageimport +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.TextEditGroup; // packageimport +import dwtx.text.edits.TextEdit; // packageimport +import dwtx.text.edits.RangeMarker; // packageimport +import dwtx.text.edits.UndoEdit; // packageimport +import dwtx.text.edits.InsertEdit; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.BadPositionCategoryException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentListener; +import dwtx.jface.text.IDocumentPartitioner; +import dwtx.jface.text.IDocumentPartitioningListener; +import dwtx.jface.text.IPositionUpdater; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITypedRegion; +import dwtx.jface.text.Position; + +class EditDocument : IDocument { + + private StringBuffer fBuffer; + + public this(String content) { + fBuffer= new StringBuffer(content); + } + + public void addDocumentListener(IDocumentListener listener) { + throw new UnsupportedOperationException(); + } + + public void addDocumentPartitioningListener(IDocumentPartitioningListener listener) { + throw new UnsupportedOperationException(); + } + + public void addPosition(Position position) { + throw new UnsupportedOperationException(); + } + + public void addPosition(String category, Position position) { + throw new UnsupportedOperationException(); + } + + public void addPositionCategory(String category) { + throw new UnsupportedOperationException(); + } + + public void addPositionUpdater(IPositionUpdater updater) { + throw new UnsupportedOperationException(); + } + + public void addPrenotifiedDocumentListener(IDocumentListener documentAdapter) { + throw new UnsupportedOperationException(); + } + + public int computeIndexInCategory(String category, int offset) { + throw new UnsupportedOperationException(); + } + + public int computeNumberOfLines(String text) { + throw new UnsupportedOperationException(); + } + + public ITypedRegion[] computePartitioning(int offset, int length) { + throw new UnsupportedOperationException(); + } + + public bool containsPosition(String category, int offset, int length) { + throw new UnsupportedOperationException(); + } + + public bool containsPositionCategory(String category) { + throw new UnsupportedOperationException(); + } + + public String get() { + return fBuffer.toString(); + } + + public String get(int offset, int length_) { + return fBuffer.slice()[offset .. offset + length_ ]; + } + + public char getChar(int offset) { + throw new UnsupportedOperationException(); + } + + public String getContentType(int offset) { + throw new UnsupportedOperationException(); + } + + public IDocumentPartitioner getDocumentPartitioner() { + throw new UnsupportedOperationException(); + } + + public String[] getLegalContentTypes() { + throw new UnsupportedOperationException(); + } + + public String[] getLegalLineDelimiters() { + throw new UnsupportedOperationException(); + } + + public int getLength() { + return fBuffer.length(); + } + + public String getLineDelimiter(int line) { + throw new UnsupportedOperationException(); + } + + public IRegion getLineInformation(int line) { + throw new UnsupportedOperationException(); + } + + public IRegion getLineInformationOfOffset(int offset) { + throw new UnsupportedOperationException(); + } + + public int getLineLength(int line) { + throw new UnsupportedOperationException(); + } + + public int getLineOffset(int line) { + throw new UnsupportedOperationException(); + } + + public int getLineOfOffset(int offset) { + throw new UnsupportedOperationException(); + } + + public int getNumberOfLines() { + throw new UnsupportedOperationException(); + } + + public int getNumberOfLines(int offset, int length) { + throw new UnsupportedOperationException(); + } + + public ITypedRegion getPartition(int offset) { + throw new UnsupportedOperationException(); + } + + public String[] getPositionCategories() { + throw new UnsupportedOperationException(); + } + + public Position[] getPositions(String category) { + throw new UnsupportedOperationException(); + } + + public IPositionUpdater[] getPositionUpdaters() { + throw new UnsupportedOperationException(); + } + + public void insertPositionUpdater(IPositionUpdater updater, int index) { + throw new UnsupportedOperationException(); + } + + public void removeDocumentListener(IDocumentListener listener) { + throw new UnsupportedOperationException(); + } + + public void removeDocumentPartitioningListener(IDocumentPartitioningListener listener) { + throw new UnsupportedOperationException(); + } + + public void removePosition(Position position) { + throw new UnsupportedOperationException(); + } + + public void removePosition(String category, Position position) { + throw new UnsupportedOperationException(); + } + + public void removePositionCategory(String category) { + throw new UnsupportedOperationException(); + } + + public void removePositionUpdater(IPositionUpdater updater) { + throw new UnsupportedOperationException(); + } + + public void removePrenotifiedDocumentListener(IDocumentListener documentAdapter) { + throw new UnsupportedOperationException(); + } + + public void replace(int offset, int length, String text) { + fBuffer.select(offset, length ); + fBuffer.replace(text); + } + + public int search(int startOffset, String findString, bool forwardSearch, bool caseSensitive, bool wholeWord) { + throw new UnsupportedOperationException(); + } + + public void set(String text) { + throw new UnsupportedOperationException(); + } + + public void setDocumentPartitioner(IDocumentPartitioner partitioner) { + throw new UnsupportedOperationException(); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/ISourceModifier.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/ISourceModifier.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.text.edits.ISourceModifier; + +import dwtx.text.edits.ReplaceEdit; // packageimport + +import dwt.dwthelper.utils; + +/** + * A source modifier can be used to modify the source of + * a move or copy edit before it gets inserted at the target + * position. This is useful if the text to be copied has to + * be modified before it is inserted without changing the + * original source. + * + * @since 3.0 + */ +public interface ISourceModifier { + /** + * Returns the modification to be done to the passed + * string in form of replace edits. The set of returned + * replace edits must modify disjoint text regions. + * Violating this requirement will result in a + * BadLocationException while executing the + * associated move or copy edit. + *

                        + * The caller of this method is responsible to apply + * the returned edits to the passed source. + * + * @param source the source to be copied or moved + * @return an array of ReplaceEdits + * describing the modifications. + */ + public ReplaceEdit[] getModifications(String source); + + /** + * Creates a copy of this source modifier object. The copy will + * be used in a different text edit object. So it should be + * created in a way that is doesn't conflict with other text edits + * referring to this source modifier. + * + * @return the copy of the source modifier + */ + public ISourceModifier copy(); +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/InsertEdit.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/InsertEdit.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,128 @@ +/******************************************************************************* + * 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 + * 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.text.edits.InsertEdit; + +import dwtx.text.edits.MultiTextEdit; // packageimport +import dwtx.text.edits.CopySourceEdit; // packageimport +import dwtx.text.edits.MoveSourceEdit; // packageimport +import dwtx.text.edits.CopyingRangeMarker; // packageimport +import dwtx.text.edits.ReplaceEdit; // packageimport +import dwtx.text.edits.EditDocument; // packageimport +import dwtx.text.edits.UndoCollector; // packageimport +import dwtx.text.edits.DeleteEdit; // packageimport +import dwtx.text.edits.MoveTargetEdit; // packageimport +import dwtx.text.edits.CopyTargetEdit; // packageimport +import dwtx.text.edits.TextEditCopier; // packageimport +import dwtx.text.edits.ISourceModifier; // packageimport +import dwtx.text.edits.TextEditMessages; // packageimport +import dwtx.text.edits.TextEditProcessor; // packageimport +import dwtx.text.edits.MalformedTreeException; // packageimport +import dwtx.text.edits.TreeIterationInfo; // packageimport +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.TextEditGroup; // packageimport +import dwtx.text.edits.TextEdit; // packageimport +import dwtx.text.edits.RangeMarker; // packageimport +import dwtx.text.edits.UndoEdit; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; + +/** + * Text edit to insert a text at a given position in a + * document. + *

                        + * An insert edit is equivalent to ReplaceEdit(offset, 0, text) + * + * + * @since 3.0 + */ +public final class InsertEdit : TextEdit { + + private String fText; + + /** + * Constructs a new insert edit. + * + * @param offset the insertion offset + * @param text the text to insert + */ + public this(int offset, String text) { + super(offset, 0); + Assert.isNotNull(text); + fText= text; + } + + /* + * Copy constructor + */ + private this(InsertEdit other) { + super(other); + fText= other.fText; + } + + /** + * Returns the text to be inserted. + * + * @return the edit's text. + */ + public String getText() { + return fText; + } + + /* + * @see TextEdit#doCopy + */ + protected TextEdit doCopy() { + return new InsertEdit(this); + } + + /* + * @see TextEdit#accept0 + */ + protected void accept0(TextEditVisitor visitor) { + bool visitChildren= visitor.visit(this); + if (visitChildren) { + acceptChildren(visitor); + } + } + + /* + * @see TextEdit#performDocumentUpdating + */ + int performDocumentUpdating(IDocument document) { + document.replace(getOffset(), getLength(), fText); + fDelta= fText.length() - getLength(); + return fDelta; + } + + /* + * @see TextEdit#deleteChildren + */ + bool deleteChildren() { + return false; + } + + /* + * @see dwtx.text.edits.TextEdit#internalToString(java.lang.StringBuffer, int) + * @since 3.3 + */ + void internalToString(StringBuffer buffer, int indent) { + super.internalToString(buffer, indent); + buffer.append(" <<").append(fText); //$NON-NLS-1$ + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/MalformedTreeException.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/MalformedTreeException.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,95 @@ +/******************************************************************************* + * 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 + * 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.text.edits.MalformedTreeException; + +import dwtx.text.edits.MultiTextEdit; // packageimport +import dwtx.text.edits.CopySourceEdit; // packageimport +import dwtx.text.edits.MoveSourceEdit; // packageimport +import dwtx.text.edits.CopyingRangeMarker; // packageimport +import dwtx.text.edits.ReplaceEdit; // packageimport +import dwtx.text.edits.EditDocument; // packageimport +import dwtx.text.edits.UndoCollector; // packageimport +import dwtx.text.edits.DeleteEdit; // packageimport +import dwtx.text.edits.MoveTargetEdit; // packageimport +import dwtx.text.edits.CopyTargetEdit; // packageimport +import dwtx.text.edits.TextEditCopier; // packageimport +import dwtx.text.edits.ISourceModifier; // packageimport +import dwtx.text.edits.TextEditMessages; // packageimport +import dwtx.text.edits.TextEditProcessor; // packageimport +import dwtx.text.edits.TreeIterationInfo; // packageimport +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.TextEditGroup; // packageimport +import dwtx.text.edits.TextEdit; // packageimport +import dwtx.text.edits.RangeMarker; // packageimport +import dwtx.text.edits.UndoEdit; // packageimport +import dwtx.text.edits.InsertEdit; // packageimport + + +import dwt.dwthelper.utils; + +/** + * Thrown to indicate that an edit got added to a parent edit + * but the child edit somehow conflicts with the parent or + * one of it siblings. + *

                        + * This class is not intended to be serialized. + *

                        + * + * @see TextEdit#addChild(TextEdit) + * @see TextEdit#addChildren(TextEdit[]) + * + * @since 3.0 + */ +public class MalformedTreeException : RuntimeException { + + // Not intended to be serialized + private static const long serialVersionUID= 1L; + + private TextEdit fParent; + private TextEdit fChild; + + /** + * Constructs a new malformed tree exception. + * + * @param parent the parent edit + * @param child the child edit + * @param message the detail message + */ + public this(TextEdit parent, TextEdit child, String message) { + super(message); + fParent= parent; + fChild= child; + } + + /** + * Returns the parent edit that caused the exception. + * + * @return the parent edit + */ + public TextEdit getParent() { + return fParent; + } + + /** + * Returns the child edit that caused the exception. + * + * @return the child edit + */ + public TextEdit getChild() { + return fChild; + } + + void setParent(TextEdit parent) { + fParent= parent; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/Messages.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/Messages.properties Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,35 @@ +############################################################################### +# Copyright (c) 2000, 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 +############################################################################### + +TextEdit.range_outside= Range of child edit lies outside of parent edit +TextEdit.overlapping= Overlapping text edits +TextEdit.deleted_edit= Cannot add deleted edit + +CopySourceEdit.no_target= No target edit provided. +CopySourceEdit.different_source= Target edit has different source edit. +CopySourceEdit.different_tree= The source and target edits belong to a different text edit tree. + +CopyTargetEdit.no_source= No source edit provided. +CopyTargetEdit.different_target= Source edit has different target edit. +CopyTargetEdit.wrong_parent=Source edit must not be the parent of the target. + +MoveSourceEdit.no_target= No target edit provided. +MoveSourceEdit.different_source= Target edit has different source edit. +MoveSourceEdit.different_tree= The source and target edits belong to a different text edit tree. + +MoveTargetEdit.no_source= No source edit provided. +MoveTargetEdit.different_target= Source edit has different target edit. +MoveTargetEdit.wrong_parent=Source edit must not be the parent of the target. + +TextEditProcessor.invalid_length=End position lies outside document range + +UndoEdit.no_children=Cannot add children to an undo edit +UndoEdit.can_not_be_added=Cannot add an undo edit to another edit diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/MoveSourceEdit.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/MoveSourceEdit.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,451 @@ +/******************************************************************************* + * 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 + * 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.text.edits.MoveSourceEdit; + +import dwtx.text.edits.MultiTextEdit; // packageimport +import dwtx.text.edits.CopySourceEdit; // packageimport +import dwtx.text.edits.CopyingRangeMarker; // packageimport +import dwtx.text.edits.ReplaceEdit; // packageimport +import dwtx.text.edits.EditDocument; // packageimport +import dwtx.text.edits.UndoCollector; // packageimport +import dwtx.text.edits.DeleteEdit; // packageimport +import dwtx.text.edits.MoveTargetEdit; // packageimport +import dwtx.text.edits.CopyTargetEdit; // packageimport +import dwtx.text.edits.TextEditCopier; // packageimport +import dwtx.text.edits.ISourceModifier; // packageimport +import dwtx.text.edits.TextEditMessages; // packageimport +import dwtx.text.edits.TextEditProcessor; // packageimport +import dwtx.text.edits.MalformedTreeException; // packageimport +import dwtx.text.edits.TreeIterationInfo; // packageimport +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.TextEditGroup; // packageimport +import dwtx.text.edits.TextEdit; // packageimport +import dwtx.text.edits.RangeMarker; // packageimport +import dwtx.text.edits.UndoEdit; // packageimport +import dwtx.text.edits.InsertEdit; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + + + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.Region; + +/** + * A move source edit denotes the source of a move operation. Move + * source edits are only valid inside an edit tree if they have a + * corresponding target edit. Furthermore the corresponding target + * edit can't be a direct or indirect child of the source edit. + * Violating one of two requirements will result in a + * MalformedTreeException when executing the edit tree. + *

                        + * A move source edit can manage an optional source modifier. A + * source modifier can provide a set of replace edits which will + * to applied to the source before it gets inserted at the target + * position. + * + * @see dwtx.text.edits.MoveTargetEdit + * @see dwtx.text.edits.CopySourceEdit + * + * @since 3.0 + */ +public final class MoveSourceEdit : TextEdit { + + private MoveTargetEdit fTarget; + private ISourceModifier fModifier; + + private String fSourceContent; + private MultiTextEdit fSourceRoot; + + /** + * Constructs a new move source edit. + * + * @param offset the edit's offset + * @param length the edit's length + */ + public this(int offset, int length) { + super(offset, length); + } + + /** + * Constructs a new copy source edit. + * + * @param offset the edit's offset + * @param length the edit's length + * @param target the edit's target + */ + public this(int offset, int length, MoveTargetEdit target) { + this(offset, length); + setTargetEdit(target); + } + + /* + * Copy constructor + */ + private this(MoveSourceEdit other) { + super(other); + if (other.fModifier !is null) + fModifier= other.fModifier.copy(); + } + + /** + * Returns the associated target edit or null + * if no target edit is associated yet. + * + * @return the target edit or null + */ + public MoveTargetEdit getTargetEdit() { + return fTarget; + } + + /** + * Sets the target edit. + * + * @param edit the new target edit. + * + * @exception MalformedTreeException is thrown if the target edit + * is a direct or indirect child of the source edit + */ + public void setTargetEdit(MoveTargetEdit edit) { + fTarget= edit; + fTarget.setSourceEdit(this); + } + + /** + * Returns the current source modifier or null + * if no source modifier is set. + * + * @return the source modifier + */ + public ISourceModifier getSourceModifier() { + return fModifier; + } + + /** + * Sets the optional source modifier. + * + * @param modifier the source modifier or null + * if no source modification is need. + */ + public void setSourceModifier(ISourceModifier modifier) { + fModifier= modifier; + } + + //---- API for MoveTargetEdit --------------------------------------------- + + String getContent() { + // The source content can be null if the edit wasn't executed + // due to an exclusion list of the text edit processor. Return + // the empty string which can be moved without any harm. + if (fSourceContent is null) + return ""; //$NON-NLS-1$ + return fSourceContent; + } + + MultiTextEdit getSourceRoot() { + return fSourceRoot; + } + + void clearContent() { + fSourceContent= null; + fSourceRoot= null; + } + + //---- Copying ------------------------------------------------------------- + + /* + * @see TextEdit#doCopy + */ + protected TextEdit doCopy() { + return new MoveSourceEdit(this); + } + + /* + * @see TextEdit#postProcessCopy + */ + protected void postProcessCopy(TextEditCopier copier) { + if (fTarget !is null) { + MoveSourceEdit source= cast(MoveSourceEdit)copier.getCopy(this); + MoveTargetEdit target= cast(MoveTargetEdit)copier.getCopy(fTarget); + if (source !is null && target !is null) + source.setTargetEdit(target); + } + } + + //---- Visitor ------------------------------------------------------------- + + /* + * @see TextEdit#accept0 + */ + protected void accept0(TextEditVisitor visitor) { + bool visitChildren= visitor.visit(this); + if (visitChildren) { + acceptChildren(visitor); + } + } + + //---- consistency check ---------------------------------------------------------------- + + int traverseConsistencyCheck(TextEditProcessor processor, IDocument document, List sourceEdits) { + int result= super.traverseConsistencyCheck(processor, document, sourceEdits); + // Since source computation takes place in a recursive fashion (see + // performSourceComputation) we only do something if we don't have a + // computed source already. + if (fSourceContent is null) { + if (sourceEdits.size() <= result) { + List list= new ArrayList(); + list.add(this); + for (int i= sourceEdits.size(); i < result; i++) + sourceEdits.add(cast(Object)null); + sourceEdits.add(cast(Object)list); + } else { + List list= cast(List)sourceEdits.get(result); + if (list is null) { + list= new ArrayList(); + sourceEdits.add(result, cast(Object)list); + } + list.add(this); + } + } + return result; + } + + void performConsistencyCheck(TextEditProcessor processor, IDocument document) { + if (fTarget is null) + throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("MoveSourceEdit.no_target")); //$NON-NLS-1$ + if (fTarget.getSourceEdit() !is this) + throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("MoveSourceEdit.different_source")); //$NON-NLS-1$ + /* Causes AST rewrite to fail + if (getRoot() !is fTarget.getRoot()) + throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("MoveSourceEdit.different_tree")); //$NON-NLS-1$ + */ + } + + //---- source computation -------------------------------------------------------------- + + void traverseSourceComputation(TextEditProcessor processor, IDocument document) { + // always perform source computation independent of processor.considerEdit + // The target might need the source and the source is computed in a + // temporary buffer. + performSourceComputation(processor, document); + } + + void performSourceComputation(TextEditProcessor processor, IDocument document) { + try { + TextEdit[] children= removeChildren(); + if (children.length > 0) { + String content= document.get(getOffset(), getLength()); + EditDocument subDocument= new EditDocument(content); + fSourceRoot= new MultiTextEdit(getOffset(), getLength()); + fSourceRoot.addChildren(children); + fSourceRoot.internalMoveTree(-getOffset()); + int processingStyle= getStyle(processor); + TextEditProcessor subProcessor= TextEditProcessor.createSourceComputationProcessor(subDocument, fSourceRoot, processingStyle); + subProcessor.performEdits(); + if (needsTransformation()) + applyTransformation(subDocument, processingStyle); + fSourceContent= subDocument.get(); + } else { + fSourceContent= document.get(getOffset(), getLength()); + if (needsTransformation()) { + EditDocument subDocument= new EditDocument(fSourceContent); + applyTransformation(subDocument, getStyle(processor)); + fSourceContent= subDocument.get(); + } + } + } catch (BadLocationException cannotHappen) { + Assert.isTrue(false); + } + } + + private int getStyle(TextEditProcessor processor) { + // we never need undo while performing local edits. + if ((processor.getStyle() & TextEdit.UPDATE_REGIONS) !is 0) + return TextEdit.UPDATE_REGIONS; + return TextEdit.NONE; + } + + //---- document updating ---------------------------------------------------------------- + + int performDocumentUpdating(IDocument document) { + document.replace(getOffset(), getLength(), ""); //$NON-NLS-1$ + fDelta= -getLength(); + return fDelta; + } + + //---- region updating -------------------------------------------------------------- + + /* + * @see TextEdit#deleteChildren + */ + bool deleteChildren() { + return false; + } + + //---- content transformation -------------------------------------------------- + + private bool needsTransformation() { + return fModifier !is null; + } + + private void applyTransformation(IDocument document, int style) { + if ((style & TextEdit.UPDATE_REGIONS) !is 0 && fSourceRoot !is null) { + Map editMap= new HashMap(); + TextEdit newEdit= createEdit(editMap); + List replaces= new ArrayList(Arrays.asList(fModifier.getModifications(document.get()))); + insertEdits(newEdit, replaces); + try { + newEdit.apply(document, style); + } catch (BadLocationException cannotHappen) { + Assert.isTrue(false); + } + restorePositions(editMap); + } else { + MultiTextEdit newEdit= new MultiTextEdit(0, document.getLength()); + TextEdit[] replaces= fModifier.getModifications(document.get()); + for (int i= 0; i < replaces.length; i++) { + newEdit.addChild(replaces[i]); + } + try { + newEdit.apply(document, style); + } catch (BadLocationException cannotHappen) { + Assert.isTrue(false); + } + } + } + + private TextEdit createEdit(Map editMap) { + MultiTextEdit result= new MultiTextEdit(0, fSourceRoot.getLength()); + editMap.put(result, fSourceRoot); + createEdit(fSourceRoot, result, editMap); + return result; + } + + private static void createEdit(TextEdit source, TextEdit target, Map editMap) { + TextEdit[] children= source.getChildren(); + for (int i= 0; i < children.length; i++) { + TextEdit child= children[i]; + // a deleted child remains deleted even if the temporary buffer + // gets modified. + if (child.isDeleted()) + continue; + RangeMarker marker= new RangeMarker(child.getOffset(), child.getLength()); + target.addChild(marker); + editMap.put(marker, child); + createEdit(child, marker, editMap); + } + } + + private void insertEdits(TextEdit root, List edits) { + while(edits.size() > 0) { + ReplaceEdit edit= cast(ReplaceEdit)edits.remove(0); + insert(root, edit, edits); + } + } + private static void insert(TextEdit parent, ReplaceEdit edit, List edits) { + if (!parent.hasChildren()) { + parent.addChild(edit); + return; + } + TextEdit[] children= parent.getChildren(); + // First dive down to find the right parent. + int removed= 0; + for (int i= 0; i < children.length; i++) { + TextEdit child= children[i]; + if (child.covers(edit)) { + insert(child, edit, edits); + return; + } else if (edit.covers(child)) { + parent.removeChild(i - removed++); + edit.addChild(child); + } else { + IRegion intersect= intersect(edit, child); + if (intersect !is null) { + ReplaceEdit[] splits= splitEdit(edit, intersect); + insert(child, splits[0], edits); + edits.add(splits[1]); + return; + } + } + } + parent.addChild(edit); + } + + public static IRegion intersect(TextEdit op1, TextEdit op2) { + int offset1= op1.getOffset(); + int length1= op1.getLength(); + int end1= offset1 + length1 - 1; + int offset2= op2.getOffset(); + if (end1 < offset2) + return null; + int length2= op2.getLength(); + int end2= offset2 + length2 - 1; + if (end2 < offset1) + return null; + + int end= Math.min(end1, end2); + if (offset1 < offset2) { + return new Region(offset2, end - offset2 + 1); + } + return new Region(offset1, end - offset1 + 1); + } + + private static ReplaceEdit[] splitEdit(ReplaceEdit edit, IRegion intersect) { + if (edit.getOffset() !is intersect.getOffset()) + return splitIntersectRight(edit, intersect); + return splitIntersectLeft(edit, intersect); + } + + private static ReplaceEdit[] splitIntersectRight(ReplaceEdit edit, IRegion intersect) { + ReplaceEdit[] result= new ReplaceEdit[2]; + // this is the actual delete. We use replace to only deal with one type + result[0]= new ReplaceEdit(intersect.getOffset(), intersect.getLength(), ""); //$NON-NLS-1$ + result[1]= new ReplaceEdit( + edit.getOffset(), + intersect.getOffset() - edit.getOffset(), + edit.getText()); + return result; + } + + private static ReplaceEdit[] splitIntersectLeft(ReplaceEdit edit, IRegion intersect) { + ReplaceEdit[] result= new ReplaceEdit[2]; + result[0]= new ReplaceEdit(intersect.getOffset(), intersect.getLength(), edit.getText()); + result[1]= new ReplaceEdit( // this is the actual delete. We use replace to only deal with one type + intersect.getOffset() + intersect.getLength(), + edit.getLength() - intersect.getLength(), + ""); //$NON-NLS-1$ + return result; + } + + private static void restorePositions(Map editMap) { + for (Iterator iter= editMap.keySet().iterator(); iter.hasNext();) { + TextEdit marker= cast(TextEdit)iter.next(); + TextEdit edit= cast(TextEdit)editMap.get(marker); + if (marker.isDeleted()) { + edit.markAsDeleted(); + } else { + edit.adjustOffset(marker.getOffset() - edit.getOffset()); + edit.adjustLength(marker.getLength() - edit.getLength()); + } + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/MoveTargetEdit.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/MoveTargetEdit.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,219 @@ +/******************************************************************************* + * 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 + * 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.text.edits.MoveTargetEdit; + +import dwtx.text.edits.MultiTextEdit; // packageimport +import dwtx.text.edits.CopySourceEdit; // packageimport +import dwtx.text.edits.MoveSourceEdit; // packageimport +import dwtx.text.edits.CopyingRangeMarker; // packageimport +import dwtx.text.edits.ReplaceEdit; // packageimport +import dwtx.text.edits.EditDocument; // packageimport +import dwtx.text.edits.UndoCollector; // packageimport +import dwtx.text.edits.DeleteEdit; // packageimport +import dwtx.text.edits.CopyTargetEdit; // packageimport +import dwtx.text.edits.TextEditCopier; // packageimport +import dwtx.text.edits.ISourceModifier; // packageimport +import dwtx.text.edits.TextEditMessages; // packageimport +import dwtx.text.edits.TextEditProcessor; // packageimport +import dwtx.text.edits.MalformedTreeException; // packageimport +import dwtx.text.edits.TreeIterationInfo; // packageimport +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.TextEditGroup; // packageimport +import dwtx.text.edits.TextEdit; // packageimport +import dwtx.text.edits.RangeMarker; // packageimport +import dwtx.text.edits.UndoEdit; // packageimport +import dwtx.text.edits.InsertEdit; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; + +/** + * A move target edit denotes the target of a move operation. Move + * target edits are only valid inside an edit tree if they have a + * corresponding source edit. Furthermore a target edit can't + * can't be a direct or indirect child of its associated source edit. + * Violating one of two requirements will result in a + * MalformedTreeException when executing the edit tree. + *

                        + * Move target edits can't be used as a parent for other edits. + * Trying to add an edit to a move target edit results in a + * MalformedTreeException as well. + * + * @see dwtx.text.edits.MoveSourceEdit + * @see dwtx.text.edits.CopyTargetEdit + * + * @since 3.0 + */ +public final class MoveTargetEdit : TextEdit { + + private MoveSourceEdit fSource; + + /** + * Constructs a new move target edit + * + * @param offset the edit's offset + */ + public this(int offset) { + super(offset, 0); + } + + /** + * Constructs an new move target edit + * + * @param offset the edit's offset + * @param source the corresponding source edit + */ + public this(int offset, MoveSourceEdit source) { + this(offset); + setSourceEdit(source); + } + + /* + * Copy constructor + */ + private this(MoveTargetEdit other) { + super(other); + } + + /** + * Returns the associated source edit or null + * if no source edit is associated yet. + * + * @return the source edit or null + */ + public MoveSourceEdit getSourceEdit() { + return fSource; + } + + /** + * Sets the source edit. + * + * @param edit the source edit + * + * @exception MalformedTreeException is thrown if the target edit + * is a direct or indirect child of the source edit + */ + public void setSourceEdit(MoveSourceEdit edit) { + if (fSource !is edit) { + fSource= edit; + fSource.setTargetEdit(this); + TextEdit parent= getParent(); + while (parent !is null) { + if (parent is fSource) + throw new MalformedTreeException(parent, this, TextEditMessages.getString("MoveTargetEdit.wrong_parent")); //$NON-NLS-1$ + parent= parent.getParent(); + } + } + } + + /* + * @see TextEdit#doCopy + */ + protected TextEdit doCopy() { + return new MoveTargetEdit(this); + } + + /* + * @see TextEdit#postProcessCopy + */ + protected void postProcessCopy(TextEditCopier copier) { + if (fSource !is null) { + MoveTargetEdit target= cast(MoveTargetEdit)copier.getCopy(this); + MoveSourceEdit source= cast(MoveSourceEdit)copier.getCopy(fSource); + if (target !is null && source !is null) + target.setSourceEdit(source); + } + } + + /* + * @see TextEdit#accept0 + */ + protected void accept0(TextEditVisitor visitor) { + bool visitChildren= visitor.visit(this); + if (visitChildren) { + acceptChildren(visitor); + } + } + + //---- consistency check ---------------------------------------------------------- + + /* + * @see TextEdit#traverseConsistencyCheck + */ + int traverseConsistencyCheck(TextEditProcessor processor, IDocument document, List sourceEdits) { + return super.traverseConsistencyCheck(processor, document, sourceEdits) + 1; + } + + /* + * @see TextEdit#performConsistencyCheck + */ + void performConsistencyCheck(TextEditProcessor processor, IDocument document) { + if (fSource is null) + throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("MoveTargetEdit.no_source")); //$NON-NLS-1$ + if (fSource.getTargetEdit() !is this) + throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("MoveTargetEdit.different_target")); //$NON-NLS-1$ + } + + //---- document updating ---------------------------------------------------------------- + + /* + * @see TextEdit#performDocumentUpdating + */ + int performDocumentUpdating(IDocument document) { + String source= fSource.getContent(); + document.replace(getOffset(), getLength(), source); + fDelta= source.length() - getLength(); + + MultiTextEdit sourceRoot= fSource.getSourceRoot(); + if (sourceRoot !is null) { + sourceRoot.internalMoveTree(getOffset()); + TextEdit[] sourceChildren= sourceRoot.removeChildren(); + List children= new ArrayList(sourceChildren.length); + for (int i= 0; i < sourceChildren.length; i++) { + TextEdit child= sourceChildren[i]; + child.internalSetParent(this); + children.add(child); + } + internalSetChildren(children); + } + fSource.clearContent(); + return fDelta; + } + + //---- region updating -------------------------------------------------------------- + + /* + * @see dwtx.text.edits.TextEdit#traversePassThree + */ + int traverseRegionUpdating(TextEditProcessor processor, IDocument document, int accumulatedDelta, bool delete_) { + // the children got already updated / normalized while they got removed + // from the source edit. So we only have to adjust the offset computed to + // far. + if (delete_) { + deleteTree(); + } else { + internalMoveTree(accumulatedDelta); + } + return accumulatedDelta + fDelta; + } + + bool deleteChildren() { + return false; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/MultiTextEdit.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/MultiTextEdit.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,254 @@ +/******************************************************************************* + * 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 + * 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.text.edits.MultiTextEdit; + +import dwtx.text.edits.CopySourceEdit; // packageimport +import dwtx.text.edits.MoveSourceEdit; // packageimport +import dwtx.text.edits.CopyingRangeMarker; // packageimport +import dwtx.text.edits.ReplaceEdit; // packageimport +import dwtx.text.edits.EditDocument; // packageimport +import dwtx.text.edits.UndoCollector; // packageimport +import dwtx.text.edits.DeleteEdit; // packageimport +import dwtx.text.edits.MoveTargetEdit; // packageimport +import dwtx.text.edits.CopyTargetEdit; // packageimport +import dwtx.text.edits.TextEditCopier; // packageimport +import dwtx.text.edits.ISourceModifier; // packageimport +import dwtx.text.edits.TextEditMessages; // packageimport +import dwtx.text.edits.TextEditProcessor; // packageimport +import dwtx.text.edits.MalformedTreeException; // packageimport +import dwtx.text.edits.TreeIterationInfo; // packageimport +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.TextEditGroup; // packageimport +import dwtx.text.edits.TextEdit; // packageimport +import dwtx.text.edits.RangeMarker; // packageimport +import dwtx.text.edits.UndoEdit; // packageimport +import dwtx.text.edits.InsertEdit; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; + +/** + * A multi-text edit can be used to aggregate several edits into + * one edit. The edit itself doesn't modify a document. + *

                        + * Note that this method should only be called by the edit + * framework and not by normal clients.

                        + *

                        + * This default implementation does nothing. Subclasses may override + * if needed.

                        + * + * @exception MalformedTreeException if the edit isn't in a valid state + * and can therefore not be executed + */ + protected void checkIntegrity() { + // does nothing + } + + /** + * {@inheritDoc} + */ + final bool isDefined() { + if (fDefined) + return true; + return hasChildren(); + } + + /** + * {@inheritDoc} + */ + public final int getOffset() { + if (fDefined) + return super.getOffset(); + + List/**/ children= internalGetChildren(); + if (children is null || children.size() is 0) + return 0; + // the children are already sorted + return (cast(TextEdit)children.get(0)).getOffset(); + } + + /** + * {@inheritDoc} + */ + public final int getLength() { + if (fDefined) + return super.getLength(); + + List/**/ children= internalGetChildren(); + if (children is null || children.size() is 0) + return 0; + // the children are already sorted + TextEdit first= cast(TextEdit)children.get(0); + TextEdit last= cast(TextEdit)children.get(children.size() - 1); + return last.getOffset() - first.getOffset() + last.getLength(); + } + + /** + * {@inheritDoc} + */ + public final bool covers(TextEdit other) { + if (fDefined) + return super.covers(other); + // an undefined multiple text edit covers everything + return true; + } + + /* + * @see dwtx.text.edits.TextEdit#canZeroLengthCover() + */ + protected bool canZeroLengthCover() { + return true; + } + + /* + * @see TextEdit#copy + */ + protected TextEdit doCopy() { + Assert.isTrue(MultiTextEdit.classinfo is this.classinfo, "Subclasses must reimplement copy0"); //$NON-NLS-1$ + return new MultiTextEdit(this); + } + + /* + * @see TextEdit#accept0 + */ + protected void accept0(TextEditVisitor visitor) { + bool visitChildren= visitor.visit(this); + if (visitChildren) { + acceptChildren(visitor); + } + } + + /* + * @see dwtx.text.edits.TextEdit#adjustOffset(int) + * @since 3.1 + */ + void adjustOffset(int delta) { + if (fDefined) + super.adjustOffset(delta); + } + + /* + * @see dwtx.text.edits.TextEdit#adjustLength(int) + * @since 3.1 + */ + void adjustLength(int delta) { + if (fDefined) + super.adjustLength(delta); + } + + /* + * @see TextEdit#performConsistencyCheck + */ + void performConsistencyCheck(TextEditProcessor processor, IDocument document) { + checkIntegrity(); + } + + /* + * @see TextEdit#performDocumentUpdating + */ + int performDocumentUpdating(IDocument document) { + fDelta= 0; + return fDelta; + } + + /* + * @see TextEdit#deleteChildren + */ + bool deleteChildren() { + return false; + } + + void aboutToBeAdded(TextEdit parent) { + defineRegion(parent.getOffset()); + } + + void defineRegion(int parentOffset) { + if (fDefined) + return; + if (hasChildren()) { + IRegion region= getCoverage(getChildren()); + internalSetOffset(region.getOffset()); + internalSetLength(region.getLength()); + } else { + internalSetOffset(parentOffset); + internalSetLength(0); + } + fDefined= true; + } + + /* + * @see dwtx.text.edits.TextEdit#internalToString(java.lang.StringBuffer, int) + * @since 3.3 + */ + void internalToString(StringBuffer buffer, int indent) { + super.internalToString(buffer, indent); + if (! fDefined) + buffer.append(" [undefined]"); //$NON-NLS-1$ + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/RangeMarker.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/RangeMarker.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,99 @@ +/******************************************************************************* + * 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 + * 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.text.edits.RangeMarker; + +import dwtx.text.edits.MultiTextEdit; // packageimport +import dwtx.text.edits.CopySourceEdit; // packageimport +import dwtx.text.edits.MoveSourceEdit; // packageimport +import dwtx.text.edits.CopyingRangeMarker; // packageimport +import dwtx.text.edits.ReplaceEdit; // packageimport +import dwtx.text.edits.EditDocument; // packageimport +import dwtx.text.edits.UndoCollector; // packageimport +import dwtx.text.edits.DeleteEdit; // packageimport +import dwtx.text.edits.MoveTargetEdit; // packageimport +import dwtx.text.edits.CopyTargetEdit; // packageimport +import dwtx.text.edits.TextEditCopier; // packageimport +import dwtx.text.edits.ISourceModifier; // packageimport +import dwtx.text.edits.TextEditMessages; // packageimport +import dwtx.text.edits.TextEditProcessor; // packageimport +import dwtx.text.edits.MalformedTreeException; // packageimport +import dwtx.text.edits.TreeIterationInfo; // packageimport +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.TextEditGroup; // packageimport +import dwtx.text.edits.TextEdit; // packageimport +import dwtx.text.edits.UndoEdit; // packageimport +import dwtx.text.edits.InsertEdit; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; + +/** + * A range marker can be used to track positions when executing + * text edits. + * + * @since 3.0 + */ +public final class RangeMarker : TextEdit { + + /** + * Creates a new range marker for the given offset and length. + * + * @param offset the marker's offset + * @param length the marker's length + */ + public this(int offset, int length) { + super(offset, length); + } + + /* + * Copy constructor + */ + private this(RangeMarker other) { + super(other); + } + + /* + * @see TextEdit#copy + */ + protected TextEdit doCopy() { + return new RangeMarker(this); + } + + /* + * @see TextEdit#accept0 + */ + protected void accept0(TextEditVisitor visitor) { + bool visitChildren= visitor.visit(this); + if (visitChildren) { + acceptChildren(visitor); + } + } + + /* + * @see TextEdit#performDocumentUpdating + */ + int performDocumentUpdating(IDocument document) { + fDelta= 0; + return fDelta; + } + + /* + * @see TextEdit#deleteChildren + */ + bool deleteChildren() { + return false; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/ReplaceEdit.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/ReplaceEdit.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,110 @@ +/******************************************************************************* + * 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 + * 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.text.edits.ReplaceEdit; + +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.TextEdit; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; + +/** + * Text edit to replace a range in a document with a different + * string. + * + * @since 3.0 + */ +public final class ReplaceEdit : TextEdit { + + private String fText; + + /** + * Constructs a new replace edit. + * + * @param offset the offset of the range to replace + * @param length the length of the range to replace + * @param text the new text + */ + public this(int offset, int length, String text) { + super(offset, length); + Assert.isNotNull(text); + fText= text; + } + + /* + * Copy constructor + * + * @param other the edit to copy from + */ + private this(ReplaceEdit other) { + super(other); + fText= other.fText; + } + + /** + * Returns the new text replacing the text denoted + * by the edit. + * + * @return the edit's text. + */ + public String getText() { + return fText; + } + + /* + * @see TextEdit#doCopy + */ + protected TextEdit doCopy() { + return new ReplaceEdit(this); + } + + /* + * @see TextEdit#accept0 + */ + protected void accept0(TextEditVisitor visitor) { + bool visitChildren= visitor.visit(this); + if (visitChildren) { + acceptChildren(visitor); + } + } + + /* + * @see TextEdit#performDocumentUpdating + */ + int performDocumentUpdating(IDocument document) { + document.replace(getOffset(), getLength(), fText); + fDelta= fText.length() - getLength(); + return fDelta; + } + + /* + * @see TextEdit#deleteChildren + */ + bool deleteChildren() { + return true; + } + + /* + * @see dwtx.text.edits.TextEdit#internalToString(java.lang.StringBuffer, int) + * @since 3.3 + */ + void internalToString(StringBuffer buffer, int indent) { + super.internalToString(buffer, indent); + buffer.append(" <<").append(fText); //$NON-NLS-1$ + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/TextEdit.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/TextEdit.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,991 @@ +/******************************************************************************* + * 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 + * 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.text.edits.TextEdit; + +import dwtx.text.edits.TextEditCopier; // packageimport +import dwtx.text.edits.TextEditProcessor; // packageimport +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.UndoEdit; // packageimport +import dwtx.text.edits.MalformedTreeException; // packageimport +import dwtx.text.edits.TextEditMessages; // packageimport + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; +import tango.text.convert.Format; + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.Region; + + +/** + * A text edit describes an elementary text manipulation operation. Edits are + * executed by applying them to a document (e.g. an instance of IDocument + * ). + *

                        + * Text edits form a tree. Clients can navigate the tree upwards, from child to + * parent, as well as downwards. Newly created edits are un-parented. New edits + * are added to the tree by calling one of the add methods on a parent + * edit. + *

                        + *

                        + * An edit tree is well formed in the following sense: + *

                          + *
                        • a parent edit covers all its children
                        • + *
                        • children don't overlap
                        • + *
                        • an edit with length 0 can't have any children
                        • + *
                        + * Any manipulation of the tree that violates one of the above requirements results + * in a MalformedTreeException. + *

                        + *

                        + * Insert edits are represented by an edit of length 0. If more than one insert + * edit exists at the same offset then the edits are executed in the order in which + * they have been added to a parent. The following code example: + *

                        + *    IDocument document= new Document("org");
                        + *    MultiTextEdit edit= new MultiTextEdit();
                        + *    edit.addChild(new InsertEdit(0, "www."));
                        + *    edit.addChild(new InsertEdit(0, "eclipse."));
                        + *    edit.apply(document);
                        + * 
                        + * therefore results in string: "www.eclipse.org". + *

                        + *

                        + * Text edits can be executed in a mode where the edit's region is updated to + * reflect the edit's position in the changed document. Region updating is enabled + * by default or can be requested by passing UPDATE_REGIONS to the + * {@link #apply(IDocument, int) apply(IDocument, int)} method. In the above example + * the region of the InsertEdit(0, "eclipse.") edit after executing + * the root edit is [3, 8]. If the region of an edit got deleted during + * change execution the region is set to [-1, -1] and the method {@link + * #isDeleted() isDeleted} returns true. + *

                        + * This class isn't intended to be subclassed outside of the edit framework. Clients + * are only allowed to subclass MultiTextEdit. + * + * @since 3.0 + * @noextend This class is not intended to be subclassed by clients. + */ +public abstract class TextEdit { + + /** + * Flags indicating that neither CREATE_UNDO nor + * UPDATE_REGIONS is set. + */ + public static const int NONE= 0; + + /** + * Flags indicating that applying an edit tree to a document + * is supposed to create a corresponding undo edit. If not + * specified null is returned from method + * apply. + */ + public static const int CREATE_UNDO= 1 << 0; + + /** + * Flag indicating that the edit's region will be updated to + * reflect its position in the changed document. If not specified + * when applying an edit tree to a document the edit's region will + * be arbitrary. It is even not guaranteed that the tree is still + * well formed. + */ + public static const int UPDATE_REGIONS= 1 << 1; + + private static class InsertionComparator : Comparator { + public int compare(Object o1, Object o2) { + TextEdit edit1= cast(TextEdit)o1; + TextEdit edit2= cast(TextEdit)o2; + + int offset1= edit1.getOffset(); + int length1= edit1.getLength(); + + int offset2= edit2.getOffset(); + int length2= edit2.getLength(); + + if (offset1 is offset2 && length1 is 0 && length2 is 0) { + return 0; + } + if (offset1 + length1 <= offset2) { + return -1; + } + if (offset2 + length2 <= offset1) { + return 1; + } + throw new MalformedTreeException( + null, edit1, + TextEditMessages.getString("TextEdit.overlapping")); //$NON-NLS-1$ + } + } + + private static const TextEdit[] EMPTY_ARRAY; + private static /+const+/ InsertionComparator INSERTION_COMPARATOR; + + private static const int DELETED_VALUE= -1; + + private int fOffset; + private int fLength; + + private TextEdit fParent; + private List fChildren; + + int fDelta; + + /** + * Create a new text edit. Parent is initialized to + * null and the edit doesn't have any children. + * + * @param offset the edit's offset + * @param length the edit's length + */ + protected this(int offset, int length) { + if( INSERTION_COMPARATOR is null ) INSERTION_COMPARATOR= new InsertionComparator(); + Assert.isTrue(offset >= 0 && length >= 0); + fOffset= offset; + fLength= length; + fDelta= 0; + } + + /** + * Copy constructor + * + * @param source the source to copy form + */ + protected this(TextEdit source) { + if( INSERTION_COMPARATOR is null ) INSERTION_COMPARATOR= new InsertionComparator(); + fOffset= source.fOffset; + fLength= source.fLength; + fDelta= 0; + } + + //---- Region management ----------------------------------------------- + + /** + * Returns the range that this edit is manipulating. The returned + * IRegion contains the edit's offset and length at + * the point in time when this call is made. Any subsequent changes + * to the edit's offset and length aren't reflected in the returned + * region object. + *

                        + * Creating a region for a deleted edit will result in an assertion + * failure. + * + * @return the manipulated region + */ + public final IRegion getRegion() { + return new Region(getOffset(), getLength()); + } + + /** + * Returns the offset of the edit. An offset is a 0-based + * character index. Returns -1 if the edit + * is marked as deleted. + * + * @return the offset of the edit + */ + public int getOffset() { + return fOffset; + } + + /** + * Returns the length of the edit. Returns -1 + * if the edit is marked as deleted. + * + * @return the length of the edit + */ + public int getLength() { + return fLength; + } + + /** + * Returns the inclusive end position of this edit. The inclusive end + * position denotes the last character of the region manipulated by + * this edit. The returned value is the result of the following + * calculation: + *

                        +     *   getOffset() + getLength() - 1;
                        +     * 
                        +     *
                        +     * @return the inclusive end position
                        +     */
                        +    public final int getInclusiveEnd() {
                        +        return getOffset() + getLength() - 1;
                        +    }
                        +
                        +    /**
                        +     * Returns the exclusive end position of this edit. The exclusive end
                        +     * position denotes the next character of the region manipulated by
                        +     * this edit. The returned value is the result of the following
                        +     * calculation:
                        +     * 
                        +     *   getOffset() + getLength();
                        +     * 
                        + * + * @return the exclusive end position + */ + public final int getExclusiveEnd() { + return getOffset() + getLength(); + } + + /** + * Returns whether this edit has been deleted or not. + * + * @return true if the edit has been + * deleted; otherwise false is returned. + */ + public final bool isDeleted() { + return fOffset is DELETED_VALUE && fLength is DELETED_VALUE; + } + + /** + * Move all offsets in the tree by the given delta. This node must be a + * root node. The resulting offsets must be greater or equal to zero. + * + * @param delta the delta + * @since 3.1 + */ + public final void moveTree(int delta) { + Assert.isTrue(fParent is null); + Assert.isTrue(getOffset() + delta >= 0); + internalMoveTree(delta); + } + + /** + * Returns true if the edit covers the given edit + * other. It is up to the concrete text edit to + * decide if a edit of length zero can cover another edit. + * + * @param other the other edit + * @return true if the edit covers the other edit; + * otherwise false is returned. + */ + public bool covers(TextEdit other) { + if (getLength() is 0 && !canZeroLengthCover()) + return false; + + if (!other.isDefined()) + return true; + + int thisOffset= getOffset(); + int otherOffset= other.getOffset(); + return thisOffset <= otherOffset && otherOffset + other.getLength() <= thisOffset + getLength(); + } + + /** + * Returns true if an edit with length zero can cover + * another edit. Returns false otherwise. + * + * @return whether an edit of length zero can cover another edit + */ + protected bool canZeroLengthCover() { + return false; + } + + /** + * Returns whether the region of this edit is defined or not. + * + * @return whether the region of this edit is defined or not + * + * @since 3.1 + */ + bool isDefined() { + return true; + } + + //---- parent and children management ----------------------------- + + /** + * Returns the edit's parent. The method returns null + * if this edit hasn't been add to another edit. + * + * @return the edit's parent + */ + public final TextEdit getParent() { + return fParent; + } + + /** + * Returns the root edit of the edit tree. + * + * @return the root edit of the edit tree + * @since 3.1 + */ + public final TextEdit getRoot() { + TextEdit result= this; + while (result.fParent !is null) { + result= result.fParent; + } + return result; + } + + /** + * Adds the given edit child to this edit. + * + * @param child the child edit to add + * @exception MalformedTreeException is thrown if the child + * edit can't be added to this edit. This is the case if the child + * overlaps with one of its siblings or if the child edit's region + * isn't fully covered by this edit. + */ + public final void addChild(TextEdit child) { + internalAdd(child); + } + + /** + * Adds all edits in edits to this edit. + * + * @param edits the text edits to add + * @exception MalformedTreeException is thrown if one of + * the given edits can't be added to this edit. + * + * @see #addChild(TextEdit) + */ + public final void addChildren(TextEdit[] edits) { + for (int i= 0; i < edits.length; i++) { + internalAdd(edits[i]); + } + } + + /** + * Removes the edit specified by the given index from the list + * of children. Returns the child edit that was removed from + * the list of children. The parent of the returned edit is + * set to null. + * + * @param index the index of the edit to remove + * @return the removed edit + * @exception IndexOutOfBoundsException if the index + * is out of range + */ + public final TextEdit removeChild(int index) { + if (fChildren is null) + throw new IndexOutOfBoundsException(Format("Index: {} Size: 0", index )); //$NON-NLS-1$//$NON-NLS-2$ + TextEdit result= cast(TextEdit)fChildren.remove(index); + result.internalSetParent(null); + if (fChildren.isEmpty()) + fChildren= null; + return result; + } + + /** + * Removes the first occurrence of the given child from the list + * of children. + * + * @param child the child to be removed + * @return true if the edit contained the given + * child; otherwise false is returned + */ + public final bool removeChild(TextEdit child) { + Assert.isNotNull(child); + if (fChildren is null) + return false; + bool result= fChildren.remove(child); + if (result) { + child.internalSetParent(null); + if (fChildren.isEmpty()) + fChildren= null; + } + return result; + } + + /** + * Removes all child edits from and returns them. The parent + * of the removed edits is set to null. + * + * @return an array of the removed edits + */ + public final TextEdit[] removeChildren() { + if (fChildren is null) + return EMPTY_ARRAY; + int size= fChildren.size(); + TextEdit[] result= new TextEdit[size]; + for (int i= 0; i < size; i++) { + result[i]= cast(TextEdit)fChildren.get(i); + result[i].internalSetParent(null); + } + fChildren= null; + return result; + } + + /** + * Returns true if this edit has children. Otherwise + * false is returned. + * + * @return true if this edit has children; otherwise + * false is returned + */ + public final bool hasChildren() { + return fChildren !is null && ! fChildren.isEmpty(); + } + + /** + * Returns the edit's children. If the edit doesn't have any + * children an empty array is returned. + * + * @return the edit's children + */ + public final TextEdit[] getChildren() { + if (fChildren is null) + return EMPTY_ARRAY; + return arraycast!(TextEdit)(fChildren.toArray()); + } + + /** + * Returns the size of the managed children. + * + * @return the size of the children + */ + public final int getChildrenSize() { + if (fChildren is null) + return 0; + return fChildren.size(); + } + + /** + * Returns the text range spawned by the given array of text edits. + * The method requires that the given array contains at least one + * edit. If all edits passed are deleted the method returns + * null. + * + * @param edits an array of edits + * @return the text range spawned by the given array of edits or + * null if all edits are marked as deleted + */ + public static IRegion getCoverage(TextEdit[] edits) { + Assert.isTrue(edits !is null && edits.length > 0); + + int offset= Integer.MAX_VALUE; + int end= Integer.MIN_VALUE; + int deleted= 0; + for (int i= 0; i < edits.length; i++) { + TextEdit edit= edits[i]; + if (edit.isDeleted()) { + deleted++; + } else { + offset= Math.min(offset, edit.getOffset()); + end= Math.max(end, edit.getExclusiveEnd()); + } + } + if (edits.length is deleted) + return null; + + return new Region(offset, end - offset); + } + + /* + * Hook called before this edit gets added to the passed + * parent. + */ + void aboutToBeAdded(TextEdit parent) { + } + + //---- Object methods ------------------------------------------------------ + + /** + * The Edit implementation of this Object + * method uses object identity (is). + * + * @param obj the other object + * @return true iff this is obj; otherwise + * false is returned + * + * @see Object#equals(java.lang.Object) + */ + public final bool equals(Object obj) { + return this is obj; // equivalent to Object.equals + } + + /** + * The Edit implementation of this Object + * method calls uses Object#hashCode() to compute its + * hash code. + * + * @return the object's hash code value + * + * @see Object#hashCode() + */ + public final override hash_t toHash() { + return super.toHash(); + } + + /* + * @see java.lang.Object#toString() + */ + public override String toString() { + StringBuffer buffer= new StringBuffer(); + toStringWithChildren(buffer, 0); + return buffer.toString(); + } + + /** + * Adds the string representation of this text edit without + * children information to the given string buffer. + * + * @param buffer the string buffer + * @param indent the indent level in number of spaces + * @since 3.3 + */ + void internalToString(StringBuffer buffer, int indent) { + for (int i= indent; i > 0; i--) { + buffer.append(" "); //$NON-NLS-1$ + } + buffer.append("{"); //$NON-NLS-1$ + String name= this.classinfo.name; + int index= name.lastIndexOf('.'); + if (index !is -1) { + buffer.append(name.substring(index + 1)); + } else { + buffer.append(name); + } + buffer.append("} "); //$NON-NLS-1$ + if (isDeleted()) { + buffer.append("[deleted]"); //$NON-NLS-1$ + } else { + buffer.append("["); //$NON-NLS-1$ + buffer.append(getOffset()); + buffer.append(","); //$NON-NLS-1$ + buffer.append(getLength()); + buffer.append("]"); //$NON-NLS-1$ + } + } + + /** + * Adds the string representation for this text edit + * and its children to the given string buffer. + * + * @param buffer the string buffer + * @param indent the indent level in number of spaces + * @since 3.3 + */ + private void toStringWithChildren(StringBuffer buffer, int indent) { + internalToString(buffer, indent); + if (fChildren !is null) { + for (Iterator iterator= fChildren.iterator(); iterator.hasNext();) { + TextEdit child= cast(TextEdit) iterator.next(); + buffer.append('\n'); + child.toStringWithChildren(buffer, indent + 1); + } + } + } + + //---- Copying ------------------------------------------------------------- + + /** + * Creates a deep copy of the edit tree rooted at this + * edit. + * + * @return a deep copy of the edit tree + * @see #doCopy() + */ + public final TextEdit copy() { + TextEditCopier copier= new TextEditCopier(this); + return copier.perform(); + } + + /** + * Creates and returns a copy of this edit. The copy method should be + * implemented in a way so that the copy can executed without causing + * any harm to the original edit. Implementors of this method are + * responsible for creating deep or shallow copies of referenced + * object to fulfill this requirement. + *

                        + * Implementers of this method should use the copy constructor + * Edit#Edit(Edit source) to initialize the edit part of the copy. + * Implementors aren't responsible to actually copy the children or + * to set the right parent. + *

                        + * This method should not be called from outside the framework. + * Please use copy to create a copy of a edit tree. + * + * @return a copy of this edit. + * @see #copy() + * @see #postProcessCopy(TextEditCopier) + * @see TextEditCopier + */ + protected abstract TextEdit doCopy(); + package TextEdit doCopy_package(){ + return doCopy(); + } + + /** + * This method is called on every edit of the copied tree to do some + * post-processing like connected an edit to a different edit in the tree. + *

                        + * This default implementation does nothing + * + * @param copier the copier that manages a map between original and + * copied edit. + * @see TextEditCopier + */ + protected void postProcessCopy(TextEditCopier copier) { + } + package void postProcessCopy_package(TextEditCopier copier) { + postProcessCopy(copier); + } + + //---- Visitor support ------------------------------------------------- + + /** + * Accepts the given visitor on a visit of the current edit. + * + * @param visitor the visitor object + * @exception IllegalArgumentException if the visitor is null + */ + public final void accept(TextEditVisitor visitor) { + Assert.isNotNull(visitor); + // begin with the generic pre-visit + visitor.preVisit(this); + // dynamic dispatch to internal method for type-specific visit/endVisit + accept0(visitor); + // end with the generic post-visit + visitor.postVisit(this); + } + + /** + * Accepts the given visitor on a type-specific visit of the current edit. + * This method must be implemented in all concrete text edits. + *

                        + * General template for implementation on each concrete TextEdit class: + *

                        +     * 
                        +     * bool visitChildren= visitor.visit(this);
                        +     * if (visitChildren) {
                        +     *    acceptChildren(visitor);
                        +     * }
                        +     * 
                        +     * 
                        + * Note that the caller (accept) takes care of invoking + * visitor.preVisit(this) and visitor.postVisit(this). + *

                        + * + * @param visitor the visitor object + */ + protected abstract void accept0(TextEditVisitor visitor); + + + /** + * Accepts the given visitor on the edits children. + *

                        + * This method must be used by the concrete implementations of + * accept to traverse list-values properties; it + * encapsulates the proper handling of on-the-fly changes to the list. + *

                        + * + * @param visitor the visitor object + */ + protected final void acceptChildren(TextEditVisitor visitor) { + if (fChildren is null) + return; + Iterator iterator= fChildren.iterator(); + while (iterator.hasNext()) { + TextEdit curr= cast(TextEdit) iterator.next(); + curr.accept(visitor); + } + } + + //---- Execution ------------------------------------------------------- + + /** + * Applies the edit tree rooted by this edit to the given document. To check + * if the edit tree can be applied to the document either catch + * MalformedTreeException or use TextEditProcessor to + * execute an edit tree. + * + * @param document the document to be manipulated + * @param style flags controlling the execution of the edit tree. Valid + * flags are: CREATE_UNDO and
                        UPDATE_REGIONS
                        . + * @return a undo edit, if CREATE_UNDO is specified. Otherwise + * null is returned. + * + * @exception MalformedTreeException is thrown if the tree isn't + * in a valid state. This exception is thrown before any edit + * is executed. So the document is still in its original state. + * @exception BadLocationException is thrown if one of the edits + * in the tree can't be executed. The state of the document is + * undefined if this exception is thrown. + * + * @see TextEditProcessor#performEdits() + */ + public final UndoEdit apply(IDocument document, int style) { + try { + TextEditProcessor processor= new TextEditProcessor(document, this, style); + return processor.performEdits(); + } finally { + // disconnect from text edit processor + fParent= null; + } + } + + /** + * Applies the edit tree rooted by this edit to the given document. This + * method is a convenience method for apply(document, CREATE_UNDO | UPDATE_REGIONS) + * + * + * @param document the document to which to apply this edit + * @return a undo edit, if CREATE_UNDO is specified. Otherwise + * null is returned. + * @exception MalformedTreeException is thrown if the tree isn't + * in a valid state. This exception is thrown before any edit + * is executed. So the document is still in its original state. + * @exception BadLocationException is thrown if one of the edits + * in the tree can't be executed. The state of the document is + * undefined if this exception is thrown. + * @see #apply(IDocument, int) + */ + public final UndoEdit apply(IDocument document) { + return apply(document, CREATE_UNDO | UPDATE_REGIONS); + } + + UndoEdit dispatchPerformEdits(TextEditProcessor processor) { + return processor.executeDo(); + } + + void dispatchCheckIntegrity(TextEditProcessor processor) { + processor.checkIntegrityDo(); + } + + //---- internal state accessors ---------------------------------------------------------- + + void internalSetParent(TextEdit parent) { + if (parent !is null) + Assert.isTrue(fParent is null); + fParent= parent; + } + + void internalSetOffset(int offset) { + Assert.isTrue(offset >= 0); + fOffset= offset; + } + + void internalSetLength(int length) { + Assert.isTrue(length >= 0); + fLength= length; + } + + List internalGetChildren() { + return fChildren; + } + + void internalSetChildren(List children) { + fChildren= children; + } + + void internalAdd(TextEdit child) { + child.aboutToBeAdded(this); + if (child.isDeleted()) + throw new MalformedTreeException(this, child, TextEditMessages.getString("TextEdit.deleted_edit")); //$NON-NLS-1$ + if (!covers(child)) + throw new MalformedTreeException(this, child, TextEditMessages.getString("TextEdit.range_outside")); //$NON-NLS-1$ + if (fChildren is null) { + fChildren= new ArrayList(2); + } + int index= computeInsertionIndex(child); + fChildren.add(index, child); + child.internalSetParent(this); + } + + private int computeInsertionIndex(TextEdit edit) { + int size= fChildren.size(); + if (size is 0) + return 0; + int lastIndex= size - 1; + TextEdit last= cast(TextEdit)fChildren.get(lastIndex); + if (last.getExclusiveEnd() <= edit.getOffset()) + return size; + try { + + int index= Collections.binarySearch(fChildren, edit, INSERTION_COMPARATOR); + + if (index < 0) + // edit is not in fChildren + return -index - 1; + + // edit is already in fChildren + // make sure that multiple insertion points at the same offset are inserted last. + while (index < lastIndex && INSERTION_COMPARATOR.compare(fChildren.get(index), fChildren.get(index + 1)) is 0) + index++; + + return index + 1; + + } catch(MalformedTreeException e) { + e.setParent(this); + throw e; + } + } + + //---- Offset & Length updating ------------------------------------------------- + + /** + * Adjusts the edits offset according to the given + * delta. This method doesn't update any children. + * + * @param delta the delta of the text replace operation + */ + void adjustOffset(int delta) { + if (isDeleted()) + return; + fOffset+= delta; + Assert.isTrue(fOffset >= 0); + } + + /** + * Adjusts the edits length according to the given + * delta. This method doesn't update any children. + * + * @param delta the delta of the text replace operation + */ + void adjustLength(int delta) { + if (isDeleted()) + return; + fLength+= delta; + Assert.isTrue(fLength >= 0); + } + + /** + * Marks the edit as deleted. This method doesn't update + * any children. + */ + void markAsDeleted() { + fOffset= DELETED_VALUE; + fLength= DELETED_VALUE; + } + + //---- Edit processing ---------------------------------------------- + + /** + * Traverses the edit tree to perform the consistency check. + * + * @param processor the text edit processor + * @param document the document to be manipulated + * @param sourceEdits the list of source edits to be performed before + * the actual tree is applied to the document + * + * @return the number of indirect move or copy target edit children + */ + int traverseConsistencyCheck(TextEditProcessor processor, IDocument document, List sourceEdits) { + int result= 0; + if (fChildren !is null) { + for (int i= fChildren.size() - 1; i >= 0; i--) { + TextEdit child= cast(TextEdit)fChildren.get(i); + result= Math.max(result, child.traverseConsistencyCheck(processor, document, sourceEdits)); + } + } + if (processor.considerEdit_package(this)) { + performConsistencyCheck(processor, document); + } + return result; + } + + void performConsistencyCheck(TextEditProcessor processor, IDocument document) { + } + + void traverseSourceComputation(TextEditProcessor processor, IDocument document) { + } + + void performSourceComputation(TextEditProcessor processor, IDocument document) { + } + + int traverseDocumentUpdating(TextEditProcessor processor, IDocument document) { + int delta= 0; + if (fChildren !is null) { + for (int i= fChildren.size() - 1; i >= 0; i--) { + TextEdit child= cast(TextEdit)fChildren.get(i); + delta+= child.traverseDocumentUpdating(processor, document); + childDocumentUpdated(); + } + } + if (processor.considerEdit_package(this)) { + if (delta !is 0) + adjustLength(delta); + int r= performDocumentUpdating(document); + if (r !is 0) + adjustLength(r); + delta+= r; + } + return delta; + } + + /** + * Hook method called when the document updating of a child edit has been + * completed. When a client calls {@link #apply(IDocument)} or + * {@link #apply(IDocument, int)} this method is called + * {@link #getChildrenSize()} times. + *

                        + * May be overridden by subclasses of {@link MultiTextEdit}. + * + * @since 3.1 + */ + protected void childDocumentUpdated() { + } + + abstract int performDocumentUpdating(IDocument document) ; + + int traverseRegionUpdating(TextEditProcessor processor, IDocument document, int accumulatedDelta, bool delete_) { + performRegionUpdating(accumulatedDelta, delete_); + if (fChildren !is null) { + bool childDelete= delete_ || deleteChildren(); + for (Iterator iter= fChildren.iterator(); iter.hasNext();) { + TextEdit child= cast(TextEdit)iter.next(); + accumulatedDelta= child.traverseRegionUpdating(processor, document, accumulatedDelta, childDelete); + childRegionUpdated(); + } + } + return accumulatedDelta + fDelta; + } + + /** + * Hook method called when the region updating of a child edit has been + * completed. When a client calls {@link #apply(IDocument)} this method is + * called {@link #getChildrenSize()} times. When calling + * {@link #apply(IDocument, int)} this method is called + * {@link #getChildrenSize()} times, when the style parameter contains the + * {@link #UPDATE_REGIONS} flag. + *

                        + * May be overridden by subclasses of {@link MultiTextEdit}. + * + * @since 3.1 + */ + protected void childRegionUpdated() { + } + + void performRegionUpdating(int accumulatedDelta, bool delete_) { + if (delete_) + markAsDeleted(); + else + adjustOffset(accumulatedDelta); + } + + abstract bool deleteChildren(); + + void internalMoveTree(int delta) { + adjustOffset(delta); + if (fChildren !is null) { + for (Iterator iter= fChildren.iterator(); iter.hasNext();) { + (cast(TextEdit)iter.next()).internalMoveTree(delta); + } + } + } + + void deleteTree() { + markAsDeleted(); + if (fChildren !is null) { + for (Iterator iter= fChildren.iterator(); iter.hasNext();) { + TextEdit child= cast(TextEdit)iter.next(); + child.deleteTree(); + } + } + } +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/TextEditCopier.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/TextEditCopier.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,127 @@ +/******************************************************************************* + * 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 + * 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.text.edits.TextEditCopier; + +import dwtx.text.edits.MultiTextEdit; // packageimport +import dwtx.text.edits.CopySourceEdit; // packageimport +import dwtx.text.edits.MoveSourceEdit; // packageimport +import dwtx.text.edits.CopyingRangeMarker; // packageimport +import dwtx.text.edits.ReplaceEdit; // packageimport +import dwtx.text.edits.EditDocument; // packageimport +import dwtx.text.edits.UndoCollector; // packageimport +import dwtx.text.edits.DeleteEdit; // packageimport +import dwtx.text.edits.MoveTargetEdit; // packageimport +import dwtx.text.edits.CopyTargetEdit; // packageimport +import dwtx.text.edits.ISourceModifier; // packageimport +import dwtx.text.edits.TextEditMessages; // packageimport +import dwtx.text.edits.TextEditProcessor; // packageimport +import dwtx.text.edits.MalformedTreeException; // packageimport +import dwtx.text.edits.TreeIterationInfo; // packageimport +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.TextEditGroup; // packageimport +import dwtx.text.edits.TextEdit; // packageimport +import dwtx.text.edits.RangeMarker; // packageimport +import dwtx.text.edits.UndoEdit; // packageimport +import dwtx.text.edits.InsertEdit; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + + + +import dwtx.core.runtime.Assert; + + +/** + * Copies a tree of text edits. A text edit copier keeps a map + * between original and new text edits. It can be used to map + * a copy back to its original edit. + * + * @since 3.0 + */ +public final class TextEditCopier { + + private TextEdit fEdit; + private Map fCopies; + + /** + * Constructs a new TextEditCopier for the + * given edit. The actual copy is done by calling + * perform. + * + * @param edit the edit to copy + * + * @see #perform() + */ + public this(TextEdit edit) { +// super(); + Assert.isNotNull(edit); + fEdit= edit; + fCopies= new HashMap(); + } + + /** + * Performs the actual copying. + * + * @return the copy + */ + public TextEdit perform() { + TextEdit result= doCopy(fEdit); + if (result !is null) { + for (Iterator iter= fCopies.keySet().iterator(); iter.hasNext();) { + TextEdit edit= cast(TextEdit)iter.next(); + edit.postProcessCopy_package(this); + } + } + return result; + } + + /** + * Returns the copy for the original text edit. + * + * @param original the original for which the copy + * is requested + * @return the copy of the original edit or null + * if the original isn't managed by this copier + */ + public TextEdit getCopy(TextEdit original) { + Assert.isNotNull(original); + return cast(TextEdit)fCopies.get(original); + } + + //---- helper methods -------------------------------------------- + + private TextEdit doCopy(TextEdit edit) { + TextEdit result= edit.doCopy_package(); + List children= edit.internalGetChildren(); + if (children !is null) { + List newChildren= new ArrayList(children.size()); + for (Iterator iter= children.iterator(); iter.hasNext();) { + TextEdit childCopy= doCopy(cast(TextEdit)iter.next()); + childCopy.internalSetParent(result); + newChildren.add(childCopy); + } + result.internalSetChildren(newChildren); + } + addCopy(edit, result); + return result; + } + + private void addCopy(TextEdit original, TextEdit copy) { + fCopies.put(original, copy); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/TextEditGroup.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/TextEditGroup.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,190 @@ +/******************************************************************************* + * 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 + * 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.text.edits.TextEditGroup; + +import dwtx.text.edits.MultiTextEdit; // packageimport +import dwtx.text.edits.CopySourceEdit; // packageimport +import dwtx.text.edits.MoveSourceEdit; // packageimport +import dwtx.text.edits.CopyingRangeMarker; // packageimport +import dwtx.text.edits.ReplaceEdit; // packageimport +import dwtx.text.edits.EditDocument; // packageimport +import dwtx.text.edits.UndoCollector; // packageimport +import dwtx.text.edits.DeleteEdit; // packageimport +import dwtx.text.edits.MoveTargetEdit; // packageimport +import dwtx.text.edits.CopyTargetEdit; // packageimport +import dwtx.text.edits.TextEditCopier; // packageimport +import dwtx.text.edits.ISourceModifier; // packageimport +import dwtx.text.edits.TextEditMessages; // packageimport +import dwtx.text.edits.TextEditProcessor; // packageimport +import dwtx.text.edits.MalformedTreeException; // packageimport +import dwtx.text.edits.TreeIterationInfo; // packageimport +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.TextEdit; // packageimport +import dwtx.text.edits.RangeMarker; // packageimport +import dwtx.text.edits.UndoEdit; // packageimport +import dwtx.text.edits.InsertEdit; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.IRegion; + + +/** + * A text edit group combines a list of {@link TextEdit}s + * and a name into a single object. The name must be a human + * readable string use to present the text edit group in the + * user interface. + *

                        + * Clients may extend this class to add extra information to + * a text edit group. + *

                        + * + * @since 3.0 + */ +public class TextEditGroup { + + private String fDescription; + private List fEdits; + + /** + * Creates a new text edit group with the given name. + * + * @param name the name of the text edit group. Must be + * a human readable string + */ + public this(String name) { +// super(); + Assert.isNotNull(name); + fDescription= name; + fEdits= new ArrayList(3); + } + + /** + * Creates a new text edit group with a name and a single + * {@link TextEdit}. + * + * @param name the name of the text edit group. Must be + * a human readable string + * @param edit the edit to manage + */ + public this(String name, TextEdit edit) { + Assert.isNotNull(name); + Assert.isNotNull(edit); + fDescription= name; + fEdits= new ArrayList(1); + fEdits.add(edit); + } + + /** + * Creates a new text edit group with the given name and + * array of edits. + * + * @param name the name of the text edit group. Must be + * a human readable string + * @param edits the array of edits + */ + public this(String name, TextEdit[] edits) { +// super(); + Assert.isNotNull(name); + Assert.isTrue(edits !is null); + fDescription= name; + fEdits= new ArrayList(Arrays.asList(edits)); + } + + /** + * Returns the edit group's name. + * + * @return the edit group's name + */ + public String getName() { + return fDescription; + } + + /** + * Adds the given {@link TextEdit} to this group. + * + * @param edit the edit to add + */ + public void addTextEdit(TextEdit edit) { + fEdits.add(edit); + } + + /** + * Removes the given {@link TextEdit} from this group. + * + * @param edit the edit to remove + * @return true if this group contained the specified edit. + * @since 3.3 + */ + public bool removeTextEdit(TextEdit edit) { + return fEdits.remove(edit); + } + + /** + * Removes all text edits from this group. + * + * @since 3.3 + */ + public void clearTextEdits() { + fEdits.clear(); + } + + + + /** + * Returns true if the list of managed + * {@link TextEdit}s is empty; otherwise false + * is returned. + * + * @return whether the list of managed text edits is + * empty or not + */ + public bool isEmpty() { + return fEdits.isEmpty(); + } + + /** + * Returns an array of {@link TextEdit}s containing + * the edits managed by this group. + * + * @return the managed text edits + */ + public TextEdit[] getTextEdits() { + return arraycast!(TextEdit)( fEdits.toArray()); + } + + /** + * Returns the text region covered by the edits managed via this + * edit group. If the group doesn't manage any edits null + * is returned. + * + * @return the text region covered by this edit group or + * null if no edits are managed + */ + public IRegion getRegion() { + int size= fEdits.size(); + if (size is 0) { + return null; + } else if (size is 1) { + return (cast(TextEdit)fEdits.get(0)).getRegion(); + } else { + return TextEdit.getCoverage(arraycast!(TextEdit)(fEdits.toArray())); + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/TextEditMessages.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/TextEditMessages.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,68 @@ +/******************************************************************************* + * 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 + * 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.text.edits.TextEditMessages; + +import dwtx.text.edits.MultiTextEdit; // packageimport +import dwtx.text.edits.CopySourceEdit; // packageimport +import dwtx.text.edits.MoveSourceEdit; // packageimport +import dwtx.text.edits.CopyingRangeMarker; // packageimport +import dwtx.text.edits.ReplaceEdit; // packageimport +import dwtx.text.edits.EditDocument; // packageimport +import dwtx.text.edits.UndoCollector; // packageimport +import dwtx.text.edits.DeleteEdit; // packageimport +import dwtx.text.edits.MoveTargetEdit; // packageimport +import dwtx.text.edits.CopyTargetEdit; // packageimport +import dwtx.text.edits.TextEditCopier; // packageimport +import dwtx.text.edits.ISourceModifier; // packageimport +import dwtx.text.edits.TextEditProcessor; // packageimport +import dwtx.text.edits.MalformedTreeException; // packageimport +import dwtx.text.edits.TreeIterationInfo; // packageimport +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.TextEditGroup; // packageimport +import dwtx.text.edits.TextEdit; // packageimport +import dwtx.text.edits.RangeMarker; // packageimport +import dwtx.text.edits.UndoEdit; // packageimport +import dwtx.text.edits.InsertEdit; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.dwthelper.ResourceBundle; +import dwtx.dwtxhelper.MessageFormat; + +class TextEditMessages { + +// private static const String BUNDLE_NAME= "dwtx.text.edits.Messages"; //$NON-NLS-1$ + + private static const ResourceBundle RESOURCE_BUNDLE;//= ResourceBundle.getBundle(BUNDLE_NAME); + + static this() { + RESOURCE_BUNDLE = ResourceBundle.getBundle( + getImportData!("dwtx.text.edits.TextEditMessages.properties")); + } + + private this() { + } + + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' ~ key ~ '!'; + } + } + + public static String getFormattedString(String key, Object[] args...) { + return MessageFormat.format(getString(key), args); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/TextEditProcessor.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/TextEditProcessor.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,262 @@ +/******************************************************************************* + * 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 + * 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.text.edits.TextEditProcessor; + +import dwtx.text.edits.MultiTextEdit; // packageimport +import dwtx.text.edits.CopySourceEdit; // packageimport +import dwtx.text.edits.MoveSourceEdit; // packageimport +import dwtx.text.edits.CopyingRangeMarker; // packageimport +import dwtx.text.edits.ReplaceEdit; // packageimport +import dwtx.text.edits.EditDocument; // packageimport +import dwtx.text.edits.UndoCollector; // packageimport +import dwtx.text.edits.DeleteEdit; // packageimport +import dwtx.text.edits.MoveTargetEdit; // packageimport +import dwtx.text.edits.CopyTargetEdit; // packageimport +import dwtx.text.edits.TextEditCopier; // packageimport +import dwtx.text.edits.ISourceModifier; // packageimport +import dwtx.text.edits.TextEditMessages; // packageimport +import dwtx.text.edits.MalformedTreeException; // packageimport +import dwtx.text.edits.TreeIterationInfo; // packageimport +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.TextEditGroup; // packageimport +import dwtx.text.edits.TextEdit; // packageimport +import dwtx.text.edits.RangeMarker; // packageimport +import dwtx.text.edits.UndoEdit; // packageimport +import dwtx.text.edits.InsertEdit; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; + + +/** + * A TextEditProcessor manages a set of edits and applies + * them as a whole to an IDocument. + *

                        + * This class isn't intended to be subclassed.

                        + * + * @see dwtx.text.edits.TextEdit#apply(IDocument) + * + * @since 3.0 + * @noextend This class is not intended to be subclassed by clients. + */ +public class TextEditProcessor { + + private IDocument fDocument; + private TextEdit fRoot; + private int fStyle; + + private bool fChecked; + private MalformedTreeException fException; + + private List fSourceEdits; + + /** + * Constructs a new edit processor for the given + * document. + * + * @param document the document to manipulate + * @param root the root of the text edit tree describing + * the modifications. By passing a text edit a a text edit + * processor the ownership of the edit is transfered to the + * text edit processors. Clients must not modify the edit + * (e.g adding new children) any longer. + * + * @param style {@link TextEdit#NONE}, {@link TextEdit#CREATE_UNDO} or {@link TextEdit#UPDATE_REGIONS}) + */ + public this(IDocument document, TextEdit root, int style) { + this(document, root, style, false); + } + + private this(IDocument document, TextEdit root, int style, bool secondary) { + Assert.isNotNull(cast(Object)document); + Assert.isNotNull(root); + fDocument= document; + fRoot= root; + if ( auto mte = cast(MultiTextEdit)fRoot ) + mte.defineRegion(0); + fStyle= style; + if (secondary) { + fChecked= true; + fSourceEdits= new ArrayList(); + } + } + + /** + * Creates a special internal processor used to during source computation inside + * move source and copy source edits + * + * @param document the document to be manipulated + * @param root the edit tree + * @param style {@link TextEdit#NONE}, {@link TextEdit#CREATE_UNDO} or {@link TextEdit#UPDATE_REGIONS}) + * @return a secondary text edit processor + * @since 3.1 + */ + static TextEditProcessor createSourceComputationProcessor(IDocument document, TextEdit root, int style) { + return new TextEditProcessor(document, root, style, true); + } + + /** + * Returns the document to be manipulated. + * + * @return the document + */ + public IDocument getDocument() { + return fDocument; + } + + /** + * Returns the edit processor's root edit. + * + * @return the processor's root edit + */ + public TextEdit getRoot() { + return fRoot; + } + + /** + * Returns the style bits of the text edit processor + * + * @return the style bits + * @see TextEdit#CREATE_UNDO + * @see TextEdit#UPDATE_REGIONS + */ + public int getStyle() { + return fStyle; + } + + /** + * Checks if the processor can execute all its edits. + * + * @return true if the edits can be executed. Return false + * otherwise. One major reason why edits cannot be executed are wrong + * offset or length values of edits. Calling perform in this case will very + * likely end in a BadLocationException. + */ + public bool canPerformEdits() { + try { + fRoot.dispatchCheckIntegrity(this); + fChecked= true; + } catch (MalformedTreeException e) { + fException= e; + return false; + } + return true; + } + + /** + * Executes the text edits. + * + * @return an object representing the undo of the executed edits + * @exception MalformedTreeException is thrown if the edit tree isn't + * in a valid state. This exception is thrown before any edit is executed. + * So the document is still in its original state. + * @exception BadLocationException is thrown if one of the edits in the + * tree can't be executed. The state of the document is undefined if this + * exception is thrown. + */ + public UndoEdit performEdits() { + if (!fChecked) { + fRoot.dispatchCheckIntegrity(this); + } else { + if (fException !is null) + throw fException; + } + return fRoot.dispatchPerformEdits(this); + } + + /* + * Class isn't intended to be sub-lcassed + */ + protected bool considerEdit(TextEdit edit) { + return true; + } + package bool considerEdit_package(TextEdit edit) { + return considerEdit(edit); + } + + + //---- checking -------------------------------------------------------------------- + + void checkIntegrityDo() { + fSourceEdits= new ArrayList(); + fRoot.traverseConsistencyCheck(this, fDocument, fSourceEdits); + if (fRoot.getExclusiveEnd() > fDocument.getLength()) + throw new MalformedTreeException(null, fRoot, TextEditMessages.getString("TextEditProcessor.invalid_length")); //$NON-NLS-1$ + } + + void checkIntegrityUndo() { + if (fRoot.getExclusiveEnd() > fDocument.getLength()) + throw new MalformedTreeException(null, fRoot, TextEditMessages.getString("TextEditProcessor.invalid_length")); //$NON-NLS-1$ + } + + //---- execution -------------------------------------------------------------------- + + UndoEdit executeDo() { + UndoCollector collector= new UndoCollector(fRoot); + try { + if (createUndo()) + collector.connect(fDocument); + computeSources(); + fRoot.traverseDocumentUpdating(this, fDocument); + if (updateRegions()) { + fRoot.traverseRegionUpdating(this, fDocument, 0, false); + } + } finally { + collector.disconnect(fDocument); + } + return collector.undo_package; + } + + private void computeSources() { + for (Iterator iter= fSourceEdits.iterator(); iter.hasNext();) { + List list= cast(List)iter.next(); + if (list !is null) { + for (Iterator edits= list.iterator(); edits.hasNext();) { + TextEdit edit= cast(TextEdit)edits.next(); + edit.traverseSourceComputation(this, fDocument); + } + } + } + } + + UndoEdit executeUndo() { + UndoCollector collector= new UndoCollector(fRoot); + try { + if (createUndo()) + collector.connect(fDocument); + TextEdit[] edits= fRoot.getChildren(); + for (int i= edits.length - 1; i >= 0; i--) { + edits[i].performDocumentUpdating(fDocument); + } + } finally { + collector.disconnect(fDocument); + } + return collector.undo_package; + } + + private bool createUndo() { + return (fStyle & TextEdit.CREATE_UNDO) !is 0; + } + + private bool updateRegions() { + return (fStyle & TextEdit.UPDATE_REGIONS) !is 0; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/TextEditVisitor.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/TextEditVisitor.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,252 @@ +/******************************************************************************* + * 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 + * 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.text.edits.TextEditVisitor; + +import dwtx.text.edits.MultiTextEdit; // packageimport +import dwtx.text.edits.CopySourceEdit; // packageimport +import dwtx.text.edits.MoveSourceEdit; // packageimport +import dwtx.text.edits.CopyingRangeMarker; // packageimport +import dwtx.text.edits.ReplaceEdit; // packageimport +import dwtx.text.edits.EditDocument; // packageimport +import dwtx.text.edits.UndoCollector; // packageimport +import dwtx.text.edits.DeleteEdit; // packageimport +import dwtx.text.edits.MoveTargetEdit; // packageimport +import dwtx.text.edits.CopyTargetEdit; // packageimport +import dwtx.text.edits.TextEditCopier; // packageimport +import dwtx.text.edits.ISourceModifier; // packageimport +import dwtx.text.edits.TextEditMessages; // packageimport +import dwtx.text.edits.TextEditProcessor; // packageimport +import dwtx.text.edits.MalformedTreeException; // packageimport +import dwtx.text.edits.TreeIterationInfo; // packageimport +import dwtx.text.edits.TextEditGroup; // packageimport +import dwtx.text.edits.TextEdit; // packageimport +import dwtx.text.edits.RangeMarker; // packageimport +import dwtx.text.edits.UndoEdit; // packageimport +import dwtx.text.edits.InsertEdit; // packageimport + + +import dwt.dwthelper.utils; + +/** + * A visitor for text edits. + *

                        + * For each different concrete text edit type T there is a method: + *

                          + *
                        • public bool visit(T node) - Visits the given edit to + * perform some arbitrary operation. If true is returned, the given edit's + * child edits will be visited next; however, if false is returned, the + * given edit's child edits will not be visited. The default implementation provided by + * this class calls a generic method visitNode(TextEdit node). + * Subclasses may reimplement these method as needed.
                        • + *
                        + *

                        + *

                        + * In addition, there are methods for visiting text edits in the + * abstract, regardless of node type: + *

                          + *
                        • public void preVisit(TextEdit edit) - Visits + * the given edit to perform some arbitrary operation. + * This method is invoked prior to the appropriate type-specific + * visit method. + * The default implementation of this method does nothing. + * Subclasses may reimplement this method as needed.
                        • + * + *
                        • public void postVisit(TextEdit edit) - Visits + * the given edit to perform some arbitrary operation. + * This method is invoked after the appropriate type-specific + * endVisit method. + * The default implementation of this method does nothing. + * Subclasses may reimplement this method as needed.
                        • + *
                        + *

                        + *

                        + * For edits with children, the child nodes are visited in increasing order. + *

                        + * + * @see TextEdit#accept(TextEditVisitor) + * @since 3.0 + */ +public class TextEditVisitor { + + /** + * Visits the given text edit prior to the type-specific visit. + * (before visit). + *

                        + * The default implementation does nothing. Subclasses may reimplement. + *

                        + * + * @param edit the node to visit + */ + public void preVisit(TextEdit edit) { + // default implementation: do nothing + } + + /** + * Visits the given text edit following the type-specific visit + * (after endVisit). + *

                        + * The default implementation does nothing. Subclasses may reimplement. + *

                        + * + * @param edit the node to visit + */ + public void postVisit(TextEdit edit) { + // default implementation: do nothing + } + + /** + * Visits the given text edit. This method is called by default from + * type-specific visits. It is not called by an edit's accept method. + * The default implementation returns true. + * + * @param edit the node to visit + * @return If true is returned, the given node's child + * nodes will be visited next; however, if false is + * returned, the given node's child nodes will not be visited. + */ + public bool visitNode(TextEdit edit) { + return true; + } + + /** + * Visits a CopySourceEdit instance. + * + * @param edit the node to visit + * @return If true is returned, the given node's child + * nodes will be visited next; however, if false is + * returned, the given node's child nodes will not be visited. + */ + public bool visit(CopySourceEdit edit) { + return visitNode(edit); + } + + /** + * Visits a CopyTargetEdit instance. + * + * @param edit the node to visit + * @return If true is returned, the given node's child + * nodes will be visited next; however, if false is + * returned, the given node's child nodes will not be visited. + */ + public bool visit(CopyTargetEdit edit) { + return visitNode(edit); + } + + /** + * Visits a MoveSourceEdit instance. + * + * @param edit the node to visit + * @return If true is returned, the given node's child + * nodes will be visited next; however, if false is + * returned, the given node's child nodes will not be visited. + */ + public bool visit(MoveSourceEdit edit) { + return visitNode(edit); + } + + /** + * Visits a MoveTargetEdit instance. + * + * @param edit the node to visit + * @return If true is returned, the given node's child + * nodes will be visited next; however, if false is + * returned, the given node's child nodes will not be visited. + */ + public bool visit(MoveTargetEdit edit) { + return visitNode(edit); + } + + /** + * Visits a RangeMarker instance. + * + * @param edit the node to visit + * @return If true is returned, the given node's child + * nodes will be visited next; however, if false is + * returned, the given node's child nodes will not be visited. + */ + public bool visit(RangeMarker edit) { + return visitNode(edit); + } + + /** + * Visits a CopyingRangeMarker instance. + * + * @param edit the node to visit + * @return If true is returned, the given node's child + * nodes will be visited next; however, if false is + * returned, the given node's child nodes will not be visited. + */ + public bool visit(CopyingRangeMarker edit) { + return visitNode(edit); + } + + /** + * Visits a DeleteEdit instance. + * + * @param edit the node to visit + * @return If true is returned, the given node's child + * nodes will be visited next; however, if false is + * returned, the given node's child nodes will not be visited. + */ + public bool visit(DeleteEdit edit) { + return visitNode(edit); + } + + /** + * Visits a InsertEdit instance. + * + * @param edit the node to visit + * @return If true is returned, the given node's child + * nodes will be visited next; however, if false is + * returned, the given node's child nodes will not be visited. + */ + public bool visit(InsertEdit edit) { + return visitNode(edit); + } + + /** + * Visits a ReplaceEdit instance. + * + * @param edit the node to visit + * @return If true is returned, the given node's child + * nodes will be visited next; however, if false is + * returned, the given node's child nodes will not be visited. + */ + public bool visit(ReplaceEdit edit) { + return visitNode(edit); + } + + /** + * Visits a UndoEdit instance. + * + * @param edit the node to visit + * @return If true is returned, the given node's child + * nodes will be visited next; however, if false is + * returned, the given node's child nodes will not be visited. + */ + public bool visit(UndoEdit edit) { + return visitNode(edit); + } + + /** + * Visits a MultiTextEdit instance. + * + * @param edit the node to visit + * @return If true is returned, the given node's child + * nodes will be visited next; however, if false is + * returned, the given node's child nodes will not be visited. + */ + public bool visit(MultiTextEdit edit) { + return visitNode(edit); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/TreeIterationInfo.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/TreeIterationInfo.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,91 @@ +/******************************************************************************* + * 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 + * 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.text.edits.TreeIterationInfo; + +import dwtx.text.edits.MultiTextEdit; // packageimport +import dwtx.text.edits.CopySourceEdit; // packageimport +import dwtx.text.edits.MoveSourceEdit; // packageimport +import dwtx.text.edits.CopyingRangeMarker; // packageimport +import dwtx.text.edits.ReplaceEdit; // packageimport +import dwtx.text.edits.EditDocument; // packageimport +import dwtx.text.edits.UndoCollector; // packageimport +import dwtx.text.edits.DeleteEdit; // packageimport +import dwtx.text.edits.MoveTargetEdit; // packageimport +import dwtx.text.edits.CopyTargetEdit; // packageimport +import dwtx.text.edits.TextEditCopier; // packageimport +import dwtx.text.edits.ISourceModifier; // packageimport +import dwtx.text.edits.TextEditMessages; // packageimport +import dwtx.text.edits.TextEditProcessor; // packageimport +import dwtx.text.edits.MalformedTreeException; // packageimport +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.TextEditGroup; // packageimport +import dwtx.text.edits.TextEdit; // packageimport +import dwtx.text.edits.RangeMarker; // packageimport +import dwtx.text.edits.UndoEdit; // packageimport +import dwtx.text.edits.InsertEdit; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.core.runtime.Assert; + + +class TreeIterationInfo { + + interface Visitor { + void visit(TextEdit edit); + } + + private int fMark= -1; + private TextEdit[][] fEditStack; + private int[] fIndexStack; + + public this(){ + fEditStack= new TextEdit[][](10); + fIndexStack= new int[10]; + } + + public int getSize() { + return fMark + 1; + } + public void push(TextEdit[] edits) { + if (++fMark is fEditStack.length) { + TextEdit[][] t1= new TextEdit[][](fEditStack.length * 2); + SimpleType!(TextEdit[]).arraycopy(fEditStack, 0, t1, 0, fEditStack.length); + fEditStack= t1; + int[] t2= new int[fEditStack.length]; + System.arraycopy(fIndexStack, 0, t2, 0, fIndexStack.length); + fIndexStack= t2; + } + fEditStack[fMark]= edits; + fIndexStack[fMark]= -1; + } + public void setIndex(int index) { + fIndexStack[fMark]= index; + } + public void pop() { + fEditStack[fMark]= null; + fIndexStack[fMark]= -1; + fMark--; + } + public void accept(Visitor visitor) { + for (int i= fMark; i >= 0; i--) { + Assert.isTrue(fIndexStack[i] >= 0); + int start= fIndexStack[i] + 1; + TextEdit[] edits= fEditStack[i]; + for (int s= start; s < edits.length; s++) { + visitor.visit(edits[s]); + } + } + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/UndoCollector.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/UndoCollector.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,115 @@ +/******************************************************************************* + * 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 + * 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.text.edits.UndoCollector; + +import dwtx.text.edits.MultiTextEdit; // packageimport +import dwtx.text.edits.CopySourceEdit; // packageimport +import dwtx.text.edits.MoveSourceEdit; // packageimport +import dwtx.text.edits.CopyingRangeMarker; // packageimport +import dwtx.text.edits.ReplaceEdit; // packageimport +import dwtx.text.edits.EditDocument; // packageimport +import dwtx.text.edits.DeleteEdit; // packageimport +import dwtx.text.edits.MoveTargetEdit; // packageimport +import dwtx.text.edits.CopyTargetEdit; // packageimport +import dwtx.text.edits.TextEditCopier; // packageimport +import dwtx.text.edits.ISourceModifier; // packageimport +import dwtx.text.edits.TextEditMessages; // packageimport +import dwtx.text.edits.TextEditProcessor; // packageimport +import dwtx.text.edits.MalformedTreeException; // packageimport +import dwtx.text.edits.TreeIterationInfo; // packageimport +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.TextEditGroup; // packageimport +import dwtx.text.edits.TextEdit; // packageimport +import dwtx.text.edits.RangeMarker; // packageimport +import dwtx.text.edits.UndoEdit; // packageimport +import dwtx.text.edits.InsertEdit; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentListener; + + +class UndoCollector : IDocumentListener { + + protected UndoEdit undo; + + package UndoEdit undo_package(){ + return undo; + } + + private int fOffset; + private int fLength; + + /** + * @since 3.1 + */ + private String fLastCurrentText; + + public this(TextEdit root) { + fOffset= root.getOffset(); + fLength= root.getLength(); + } + + public void connect(IDocument document) { + document.addDocumentListener(this); + undo= new UndoEdit(); + } + + public void disconnect(IDocument document) { + if (undo !is null) { + document.removeDocumentListener(this); + undo.defineRegion(fOffset, fLength); + } + } + + public void documentChanged(DocumentEvent event) { + fLength+= getDelta(event); + } + + private static int getDelta(DocumentEvent event) { + String text= event.getText(); + return text is null ? -event.getLength() : (text.length() - event.getLength()); + } + + public void documentAboutToBeChanged(DocumentEvent event) { + int offset= event.getOffset(); + int currentLength= event.getLength(); + String currentText= null; + try { + currentText= event.getDocument().get(offset, currentLength); + } catch (BadLocationException cannotHappen) { + Assert.isTrue(false, "Can't happen"); //$NON-NLS-1$ + } + + /* + * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=93634 + * If the same string is replaced on many documents (e.g. rename + * package), the size of the undo can be reduced by using the same + * String instance in all edits, instead of using the unique String + * returned from IDocument.get(int, int). + */ + if (fLastCurrentText !is null && fLastCurrentText.equals(currentText)) + currentText= fLastCurrentText; + else + fLastCurrentText= currentText; + + String newText= event.getText(); + undo.add(new ReplaceEdit(offset, newText !is null ? newText.length() : 0, currentText)); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/edits/UndoEdit.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/edits/UndoEdit.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,134 @@ +/******************************************************************************* + * 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 + * 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.text.edits.UndoEdit; + +import dwtx.text.edits.MultiTextEdit; // packageimport +import dwtx.text.edits.CopySourceEdit; // packageimport +import dwtx.text.edits.MoveSourceEdit; // packageimport +import dwtx.text.edits.CopyingRangeMarker; // packageimport +import dwtx.text.edits.ReplaceEdit; // packageimport +import dwtx.text.edits.EditDocument; // packageimport +import dwtx.text.edits.UndoCollector; // packageimport +import dwtx.text.edits.DeleteEdit; // packageimport +import dwtx.text.edits.MoveTargetEdit; // packageimport +import dwtx.text.edits.CopyTargetEdit; // packageimport +import dwtx.text.edits.TextEditCopier; // packageimport +import dwtx.text.edits.ISourceModifier; // packageimport +import dwtx.text.edits.TextEditMessages; // packageimport +import dwtx.text.edits.TextEditProcessor; // packageimport +import dwtx.text.edits.MalformedTreeException; // packageimport +import dwtx.text.edits.TreeIterationInfo; // packageimport +import dwtx.text.edits.TextEditVisitor; // packageimport +import dwtx.text.edits.TextEditGroup; // packageimport +import dwtx.text.edits.TextEdit; // packageimport +import dwtx.text.edits.RangeMarker; // packageimport +import dwtx.text.edits.InsertEdit; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; + + +/** + * This class encapsulates the reverse changes of an executed text + * edit tree. To apply an undo memento to a document use method + * apply(IDocument). + *

                        + * Clients can't add additional children to an undo edit nor can they + * add an undo edit as a child to another edit. Doing so results in + * both cases in a MalformedTreeException. + * + * @since 3.0 + * @noinstantiate This class is not intended to be instantiated by clients. + */ +public final class UndoEdit : TextEdit { + + this() { + super(0, Integer.MAX_VALUE); + } + + private this(UndoEdit other) { + super(other); + } + + /* + * @see dwtx.text.edits.TextEdit#internalAdd(dwtx.text.edits.TextEdit) + */ + void internalAdd(TextEdit child) { + throw new MalformedTreeException(null, this, TextEditMessages.getString("UndoEdit.no_children")); //$NON-NLS-1$ + } + + /* + * @see dwtx.text.edits.MultiTextEdit#aboutToBeAdded(dwtx.text.edits.TextEdit) + */ + void aboutToBeAdded(TextEdit parent) { + throw new MalformedTreeException(parent, this, TextEditMessages.getString("UndoEdit.can_not_be_added")); //$NON-NLS-1$ + } + + UndoEdit dispatchPerformEdits(TextEditProcessor processor) { + return processor.executeUndo(); + } + + void dispatchCheckIntegrity(TextEditProcessor processor) { + processor.checkIntegrityUndo(); + } + + /* + * @see dwtx.text.edits.TextEdit#doCopy() + */ + protected TextEdit doCopy() { + return new UndoEdit(this); + } + + /* + * @see TextEdit#accept0 + */ + protected void accept0(TextEditVisitor visitor) { + bool visitChildren= visitor.visit(this); + if (visitChildren) { + acceptChildren(visitor); + } + } + + /* + * @see TextEdit#performDocumentUpdating + */ + int performDocumentUpdating(IDocument document) { + fDelta= 0; + return fDelta; + } + + void add(ReplaceEdit edit) { + List children= internalGetChildren(); + if (children is null) { + children= new ArrayList(2); + internalSetChildren(children); + } + children.add(edit); + } + + void defineRegion(int offset, int length) { + internalSetOffset(offset); + internalSetLength(length); + } + + bool deleteChildren() { + return false; + } +} + diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/undo/DocumentUndoEvent.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/undo/DocumentUndoEvent.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,175 @@ +/******************************************************************************* + * 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 + * 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.text.undo.DocumentUndoEvent; + +// import dwtx.text.undo.DocumentUndoManager; // packageimport +// import dwtx.text.undo.DocumentUndoManagerRegistry; // packageimport +// import dwtx.text.undo.IDocumentUndoListener; // packageimport +// import dwtx.text.undo.UndoMessages; // packageimport +// import dwtx.text.undo.IDocumentUndoManager; // packageimport + + +import dwt.dwthelper.utils; + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.IDocument; + + +/** + * Describes document changes initiated by undo or redo. + *

                        + * Clients are not supposed to subclass or create instances of this class. + *

                        + * + * @see IDocumentUndoManager + * @see IDocumentUndoListener + * @since 3.2 + * @noinstantiate This class is not intended to be instantiated by clients. + * @noextend This class is not intended to be subclassed by clients. + */ +public class DocumentUndoEvent { + + /** + * Indicates that the described document event is about to be + * undone. + */ + public static const int ABOUT_TO_UNDO= 1 << 0; + + /** + * Indicates that the described document event is about to be + * redone. + */ + public static const int ABOUT_TO_REDO= 1 << 1; + + /** + * Indicates that the described document event has been undone. + */ + public static const int UNDONE= 1 << 2; + + /** + * Indicates that the described document event has been redone. + */ + public static const int REDONE= 1 << 3; + + /** + * Indicates that the described document event is a compound undo + * or redo event. + */ + public static const int COMPOUND= 1 << 4; + + /** The changed document. */ + private IDocument fDocument; + + /** The document offset where the change begins. */ + private int fOffset; + + /** Text inserted into the document. */ + private String fText; + + /** Text replaced in the document. */ + private String fPreservedText; + + /** Bit mask of event types describing the event */ + private int fEventType; + + /** The source that triggered this event or null if unknown. */ + private Object fSource; + + /** + * Creates a new document event. + * + * @param doc the changed document + * @param offset the offset of the replaced text + * @param text the substitution text + * @param preservedText the replaced text + * @param eventType a bit mask describing the type(s) of event + * @param source the source that triggered this event or null if unknown + */ + this(IDocument doc, int offset, String text, String preservedText, int eventType, Object source) { + + Assert.isNotNull(cast(Object)doc); + Assert.isTrue(offset >= 0); + + fDocument= doc; + fOffset= offset; + fText= text; + fPreservedText= preservedText; + fEventType= eventType; + fSource= source; + } + + /** + * Returns the changed document. + * + * @return the changed document + */ + public IDocument getDocument() { + return fDocument; + } + + /** + * Returns the offset of the change. + * + * @return the offset of the change + */ + public int getOffset() { + return fOffset; + } + + /** + * Returns the text that has been inserted. + * + * @return the text that has been inserted + */ + public String getText() { + return fText; + } + + /** + * Returns the text that has been replaced. + * + * @return the text that has been replaced + */ + public String getPreservedText() { + return fPreservedText; + } + + /** + * Returns the type of event that is occurring. + * + * @return the bit mask that indicates the type (or types) of the event + */ + public int getEventType() { + return fEventType; + } + + /** + * Returns the source that triggered this event. + * + * @return the source that triggered this event. + */ + public Object getSource() { + return fSource; + } + + /** + * Returns whether the change was a compound change or not. + * + * @return true if the undo or redo change is a + * compound change, false if it is not + */ + public bool isCompound() { + return (fEventType & COMPOUND) !is 0; + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/undo/DocumentUndoManager.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/undo/DocumentUndoManager.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,1297 @@ +/******************************************************************************* + * 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 + * 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.text.undo.DocumentUndoManager; + +import dwtx.text.undo.DocumentUndoManagerRegistry; // packageimport +import dwtx.text.undo.DocumentUndoEvent; // packageimport +import dwtx.text.undo.IDocumentUndoListener; // packageimport +import dwtx.text.undo.UndoMessages; // packageimport +import dwtx.text.undo.IDocumentUndoManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + +import dwtx.core.commands.ExecutionException; +import dwtx.core.commands.operations.AbstractOperation; +import dwtx.core.commands.operations.IContextReplacingOperation; +import dwtx.core.commands.operations.IOperationHistory; +import dwtx.core.commands.operations.IOperationHistoryListener; +import dwtx.core.commands.operations.IUndoContext; +import dwtx.core.commands.operations.IUndoableOperation; +import dwtx.core.commands.operations.ObjectUndoContext; +import dwtx.core.commands.operations.OperationHistoryEvent; +import dwtx.core.commands.operations.OperationHistoryFactory; +import dwtx.core.runtime.Assert; +import dwtx.core.runtime.IAdaptable; +import dwtx.core.runtime.IProgressMonitor; +import dwtx.core.runtime.IStatus; +import dwtx.core.runtime.ListenerList; +import dwtx.core.runtime.Status; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.DocumentEvent; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentExtension4; +import dwtx.jface.text.IDocumentListener; +import dwtx.jface.text.TextUtilities; + +/** + * A standard implementation of a document-based undo manager that + * creates an undo history based on changes to its document. + *

                        + * Based on the 3.1 implementation of DefaultUndoManager, it was implemented + * using the document-related manipulations defined in the original + * DefaultUndoManager, by separating the document manipulations from the + * viewer-specific processing.

                        + *

                        + * The classes representing individual text edits (formerly text commands) + * were promoted from inner types to their own classes in order to support + * reassignment to a different undo manager.

                        + *

                        + * This class is not intended to be subclassed. + *

                        + * + * @see IDocumentUndoManager + * @see DocumentUndoManagerRegistry + * @see IDocumentUndoListener + * @see dwtx.jface.text.IDocument + * @since 3.2 + * @noextend This class is not intended to be subclassed by clients. + */ +public class DocumentUndoManager : IDocumentUndoManager { + + + /** + * Represents an undo-able text change, described as the + * replacement of some preserved text with new text. + *

                        + * Based on the DefaultUndoManager.TextCommand from R3.1. + *

                        + */ + private static class UndoableTextChange : AbstractOperation { + + /** The start index of the replaced text. */ + protected int fStart= -1; + + /** The end index of the replaced text. */ + protected int fEnd= -1; + + /** The newly inserted text. */ + protected String fText; + + /** The replaced text. */ + protected String fPreservedText; + + /** The undo modification stamp. */ + protected long fUndoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; + + /** The redo modification stamp. */ + protected long fRedoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; + + /** The undo manager that generated the change. */ + protected DocumentUndoManager fDocumentUndoManager; + + /** + * Creates a new text change. + * + * @param manager the undo manager for this change + */ + this(DocumentUndoManager manager) { + super(UndoMessages.getString("DocumentUndoManager.operationLabel")); //$NON-NLS-1$ + this.fDocumentUndoManager= manager; + addContext(manager.getUndoContext()); + } + + /** + * Re-initializes this text change. + */ + protected void reinitialize() { + fStart= fEnd= -1; + fText= fPreservedText= null; + fUndoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; + fRedoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; + } + + /** + * Sets the start and the end index of this change. + * + * @param start the start index + * @param end the end index + */ + protected void set(int start, int end) { + fStart= start; + fEnd= end; + fText= null; + fPreservedText= null; + } + + /* + * @see dwtx.core.commands.operations.IUndoableOperation#dispose() + */ + public void dispose() { + reinitialize(); + } + + /** + * Undo the change described by this change. + */ + protected void undoTextChange() { + try { + if (auto de4 = cast(IDocumentExtension4)fDocumentUndoManager.fDocument ) + de4.replace(fStart, fText + .length(), fPreservedText, fUndoModificationStamp); + else + fDocumentUndoManager.fDocument.replace(fStart, fText.length(), + fPreservedText); + } catch (BadLocationException x) { + } + } + + /* + * @see dwtx.core.commands.operations.IUndoableOperation#canUndo() + */ + public bool canUndo() { + if (isValid()) { + if (cast(IDocumentExtension4)fDocumentUndoManager.fDocument) { + long docStamp= (cast(IDocumentExtension4) fDocumentUndoManager.fDocument) + .getModificationStamp(); + + // Normal case: an undo is valid if its redo will restore + // document to its current modification stamp + bool canUndo= docStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP + || docStamp is getRedoModificationStamp(); + + /* + * Special case to check if the answer is false. If the last + * document change was empty, then the document's modification + * stamp was incremented but nothing was committed. The + * operation being queried has an older stamp. In this case + * only, the comparison is different. A sequence of document + * changes that include an empty change is handled correctly + * when a valid commit follows the empty change, but when + * #canUndo() is queried just after an empty change, we must + * special case the check. The check is very specific to prevent + * false positives. see + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=98245 + */ + if (!canUndo + && this is fDocumentUndoManager.fHistory + .getUndoOperation(fDocumentUndoManager.fUndoContext) + // this is the latest operation + && this !is fDocumentUndoManager.fCurrent + // there is a more current operation not on the stack + && !fDocumentUndoManager.fCurrent.isValid() + // the current operation is not a valid document + // modification + && fDocumentUndoManager.fCurrent.fUndoModificationStamp !is + // the invalid current operation has a document stamp + IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP) { + canUndo= fDocumentUndoManager.fCurrent.fRedoModificationStamp is docStamp; + } + /* + * When the composite is the current operation, it may hold the + * timestamp of a no-op change. We check this here rather than + * in an override of canUndo() in UndoableCompoundTextChange simply to + * keep all the special case checks in one place. + */ + if (!canUndo + && this is fDocumentUndoManager.fHistory + .getUndoOperation(fDocumentUndoManager.fUndoContext) + && // this is the latest operation + null !is cast(UndoableCompoundTextChange)this + && this is fDocumentUndoManager.fCurrent + && // this is the current operation + this.fStart is -1 + && // the current operation text is not valid + fDocumentUndoManager.fCurrent.fRedoModificationStamp !is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP) { + // but it has a redo stamp + canUndo= fDocumentUndoManager.fCurrent.fRedoModificationStamp is docStamp; + } + return canUndo; + + } + // if there is no timestamp to check, simply return true per the + // 3.0.1 behavior + return true; + } + return false; + } + + /* + * @see dwtx.core.commands.operations.IUndoableOperation#canRedo() + */ + public bool canRedo() { + if (isValid()) { + if (cast(IDocumentExtension4)fDocumentUndoManager.fDocument ) { + long docStamp= (cast(IDocumentExtension4) fDocumentUndoManager.fDocument) + .getModificationStamp(); + return docStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP + || docStamp is getUndoModificationStamp(); + } + // if there is no timestamp to check, simply return true per the + // 3.0.1 behavior + return true; + } + return false; + } + + /* + * @see dwtx.core.commands.operations.IUndoableOperation#canExecute() + */ + public bool canExecute() { + return fDocumentUndoManager.isConnected(); + } + + /* + * @see dwtx.core.commands.operations.IUndoableOperation.IUndoableOperation#execute(IProgressMonitor, IAdaptable) + */ + public IStatus execute(IProgressMonitor monitor, IAdaptable uiInfo) { + // Text changes execute as they are typed, so executing one has no + // effect. + return Status.OK_STATUS; + } + + /** + * {@inheritDoc} + * Notifies clients about the undo. + */ + public IStatus undo(IProgressMonitor monitor, IAdaptable uiInfo) { + if (isValid()) { + fDocumentUndoManager.fireDocumentUndo(fStart, fPreservedText, fText, cast(Object)uiInfo, DocumentUndoEvent.ABOUT_TO_UNDO, false); + undoTextChange(); + fDocumentUndoManager.resetProcessChangeState(); + fDocumentUndoManager.fireDocumentUndo(fStart, fPreservedText, fText, cast(Object)uiInfo, DocumentUndoEvent.UNDONE, false); + return Status.OK_STATUS; + } + return IOperationHistory.OPERATION_INVALID_STATUS; + } + + /** + * Re-applies the change described by this change. + */ + protected void redoTextChange() { + try { + if (cast(IDocumentExtension4)fDocumentUndoManager.fDocument) + (cast(IDocumentExtension4) fDocumentUndoManager.fDocument).replace(fStart, fEnd - fStart, fText, fRedoModificationStamp); + else + fDocumentUndoManager.fDocument.replace(fStart, fEnd - fStart, fText); + } catch (BadLocationException x) { + } + } + + /** + * Re-applies the change described by this change that was previously + * undone. Also notifies clients about the redo. + * + * @param monitor the progress monitor to use if necessary + * @param uiInfo an adaptable that can provide UI info if needed + * @return the status + */ + public IStatus redo(IProgressMonitor monitor, IAdaptable uiInfo) { + if (isValid()) { + fDocumentUndoManager.fireDocumentUndo(fStart, fText, fPreservedText, cast(Object)uiInfo, DocumentUndoEvent.ABOUT_TO_REDO, false); + redoTextChange(); + fDocumentUndoManager.resetProcessChangeState(); + fDocumentUndoManager.fireDocumentUndo(fStart, fText, fPreservedText, cast(Object)uiInfo, DocumentUndoEvent.REDONE, false); + return Status.OK_STATUS; + } + return IOperationHistory.OPERATION_INVALID_STATUS; + } + + /** + * Update the change in response to a commit. + */ + + protected void updateTextChange() { + fText= fDocumentUndoManager.fTextBuffer.toString(); + fDocumentUndoManager.fTextBuffer.clear(); + fPreservedText= fDocumentUndoManager.fPreservedTextBuffer.toString(); + fDocumentUndoManager.fPreservedTextBuffer.clear(); + } + + /** + * Creates a new uncommitted text change depending on whether a compound + * change is currently being executed. + * + * @return a new, uncommitted text change or a compound text change + */ + protected UndoableTextChange createCurrent() { + if (fDocumentUndoManager.fFoldingIntoCompoundChange) + return new UndoableCompoundTextChange(fDocumentUndoManager); + return new UndoableTextChange(fDocumentUndoManager); + } + + /** + * Commits the current change into this one. + */ + protected void commit() { + if (fStart < 0) { + if (fDocumentUndoManager.fFoldingIntoCompoundChange) { + fDocumentUndoManager.fCurrent= createCurrent(); + } else { + reinitialize(); + } + } else { + updateTextChange(); + fDocumentUndoManager.fCurrent= createCurrent(); + } + fDocumentUndoManager.resetProcessChangeState(); + } + + /** + * Updates the text from the buffers without resetting the buffers or adding + * anything to the stack. + */ + protected void pretendCommit() { + if (fStart > -1) { + fText= fDocumentUndoManager.fTextBuffer.toString(); + fPreservedText= fDocumentUndoManager.fPreservedTextBuffer.toString(); + } + } + + /** + * Attempt a commit of this change and answer true if a new fCurrent was + * created as a result of the commit. + * + * @return true if the change was committed and created + * a new fCurrent, false if not + */ + protected bool attemptCommit() { + pretendCommit(); + if (isValid()) { + fDocumentUndoManager.commit(); + return true; + } + return false; + } + + /** + * Checks whether this text change is valid for undo or redo. + * + * @return true if the change is valid for undo or redo + */ + protected bool isValid() { + return fStart > -1 && fEnd > -1 && fText !is null; + } + + /* + * @see java.lang.Object#toString() + */ + public override String toString() { + String delimiter= ", "; //$NON-NLS-1$ + StringBuffer text= new StringBuffer(super.toString()); + text.append("\n"); //$NON-NLS-1$ + text.append(this.classinfo.name); + text.append(" undo modification stamp: "); //$NON-NLS-1$ + text.append(fUndoModificationStamp); + text.append(" redo modification stamp: "); //$NON-NLS-1$ + text.append(fRedoModificationStamp); + text.append(" start: "); //$NON-NLS-1$ + text.append(fStart); + text.append(delimiter); + text.append("end: "); //$NON-NLS-1$ + text.append(fEnd); + text.append(delimiter); + text.append("text: '"); //$NON-NLS-1$ + text.append(fText); + text.append('\''); + text.append(delimiter); + text.append("preservedText: '"); //$NON-NLS-1$ + text.append(fPreservedText); + text.append('\''); + return text.toString(); + } + + /** + * Return the undo modification stamp + * + * @return the undo modification stamp for this change + */ + protected long getUndoModificationStamp() { + return fUndoModificationStamp; + } + + /** + * Return the redo modification stamp + * + * @return the redo modification stamp for this change + */ + protected long getRedoModificationStamp() { + return fRedoModificationStamp; + } + } + + + /** + * Represents an undo-able text change consisting of several individual + * changes. + */ + private static class UndoableCompoundTextChange : UndoableTextChange { + + /** The list of individual changes */ + private List fChanges; + + /** + * Creates a new compound text change. + * + * @param manager + * the undo manager for this change + */ + this(DocumentUndoManager manager) { + fChanges= new ArrayList(); + super(manager); + } + + /** + * Adds a new individual change to this compound change. + * + * @param change the change to be added + */ + protected void add(UndoableTextChange change) { + fChanges.add(change); + } + + /* + * @see dwtx.text.undo.UndoableTextChange#undo(dwtx.core.runtime.IProgressMonitor, dwtx.core.runtime.IAdaptable) + */ + public IStatus undo(IProgressMonitor monitor, IAdaptable uiInfo) { + + int size= fChanges.size(); + if (size > 0) { + UndoableTextChange c; + + c= cast(UndoableTextChange) fChanges.get(0); + fDocumentUndoManager.fireDocumentUndo(c.fStart, c.fPreservedText, c.fText, cast(Object)uiInfo, DocumentUndoEvent.ABOUT_TO_UNDO, true); + + for (int i= size - 1; i >= 0; --i) { + c= cast(UndoableTextChange) fChanges.get(i); + c.undoTextChange(); + } + fDocumentUndoManager.resetProcessChangeState(); + fDocumentUndoManager.fireDocumentUndo(c.fStart, c.fPreservedText, c.fText, cast(Object)uiInfo, + DocumentUndoEvent.UNDONE, true); + } + return Status.OK_STATUS; + } + + /* + * @see dwtx.text.undo.UndoableTextChange#redo(dwtx.core.runtime.IProgressMonitor, dwtx.core.runtime.IAdaptable) + */ + public IStatus redo(IProgressMonitor monitor, IAdaptable uiInfo) { + + int size= fChanges.size(); + if (size > 0) { + + UndoableTextChange c; + c= cast(UndoableTextChange) fChanges.get(size - 1); + fDocumentUndoManager.fireDocumentUndo(c.fStart, c.fText, c.fPreservedText, cast(Object)uiInfo, DocumentUndoEvent.ABOUT_TO_REDO, true); + + for (int i= 0; i <= size - 1; ++i) { + c= cast(UndoableTextChange) fChanges.get(i); + c.redoTextChange(); + } + fDocumentUndoManager.resetProcessChangeState(); + fDocumentUndoManager.fireDocumentUndo(c.fStart, c.fText, c.fPreservedText, cast(Object)uiInfo, DocumentUndoEvent.REDONE, true); + } + + return Status.OK_STATUS; + } + + /* + * @see dwtx.text.undo.UndoableTextChange#updateTextChange() + */ + protected void updateTextChange() { + // first gather the data from the buffers + super.updateTextChange(); + + // the result of the update is stored as a child change + UndoableTextChange c= new UndoableTextChange(fDocumentUndoManager); + c.fStart= fStart; + c.fEnd= fEnd; + c.fText= fText; + c.fPreservedText= fPreservedText; + c.fUndoModificationStamp= fUndoModificationStamp; + c.fRedoModificationStamp= fRedoModificationStamp; + add(c); + + // clear out all indexes now that the child is added + reinitialize(); + } + + /* + * @see dwtx.text.undo.UndoableTextChange#createCurrent() + */ + protected UndoableTextChange createCurrent() { + + if (!fDocumentUndoManager.fFoldingIntoCompoundChange) + return new UndoableTextChange(fDocumentUndoManager); + + reinitialize(); + return this; + } + + /* + * @see dwtx.text.undo.UndoableTextChange#commit() + */ + protected void commit() { + // if there is pending data, update the text change + if (fStart > -1) + updateTextChange(); + fDocumentUndoManager.fCurrent= createCurrent(); + fDocumentUndoManager.resetProcessChangeState(); + } + + /* + * @see dwtx.text.undo.UndoableTextChange#isValid() + */ + protected bool isValid() { + return fStart > -1 || fChanges.size() > 0; + } + + /* + * @see dwtx.text.undo.UndoableTextChange#getUndoModificationStamp() + */ + protected long getUndoModificationStamp() { + if (fStart > -1) + return super.getUndoModificationStamp(); + else if (fChanges.size() > 0) + return (cast(UndoableTextChange) fChanges.get(0)) + .getUndoModificationStamp(); + + return fUndoModificationStamp; + } + + /* + * @see dwtx.text.undo.UndoableTextChange#getRedoModificationStamp() + */ + protected long getRedoModificationStamp() { + if (fStart > -1) + return super.getRedoModificationStamp(); + else if (fChanges.size() > 0) + return (cast(UndoableTextChange) fChanges.get(fChanges.size() - 1)) + .getRedoModificationStamp(); + + return fRedoModificationStamp; + } + } + + + /** + * Internal listener to document changes. + */ + private class DocumentListener : IDocumentListener { + + private String fReplacedText; + + /* + * @see dwtx.jface.text.IDocumentListener#documentAboutToBeChanged(dwtx.jface.text.DocumentEvent) + */ + public void documentAboutToBeChanged(DocumentEvent event) { + try { + fReplacedText= event.getDocument().get(event.getOffset(), + event.getLength()); + fPreservedUndoModificationStamp= event.getModificationStamp(); + } catch (BadLocationException x) { + fReplacedText= null; + } + } + + /* + * @see dwtx.jface.text.IDocumentListener#documentChanged(dwtx.jface.text.DocumentEvent) + */ + public void documentChanged(DocumentEvent event) { + fPreservedRedoModificationStamp= event.getModificationStamp(); + + // record the current valid state for the top operation in case it + // remains the + // top operation but changes state. + IUndoableOperation op= fHistory.getUndoOperation(fUndoContext); + bool wasValid= false; + if (op !is null) + wasValid= op.canUndo(); + // Process the change, providing the before and after timestamps + processChange(event.getOffset(), event.getOffset() + + event.getLength(), event.getText(), fReplacedText, + fPreservedUndoModificationStamp, + fPreservedRedoModificationStamp); + + // now update fCurrent with the latest buffers from the document + // change. + fCurrent.pretendCommit(); + + if (op is fCurrent) { + // if the document change did not cause a new fCurrent to be + // created, then we should + // notify the history that the current operation changed if its + // validity has changed. + if (wasValid !is fCurrent.isValid()) + fHistory.operationChanged(op); + } else { + // if the change created a new fCurrent that we did not yet add + // to the + // stack, do so if it's valid and we are not in the middle of a + // compound change. + if (fCurrent !is fLastAddedTextEdit && fCurrent.isValid()) { + addToOperationHistory(fCurrent); + } + } + } + } + + /* + * @see IOperationHistoryListener + */ + private class HistoryListener : IOperationHistoryListener { + + private IUndoableOperation fOperation; + + public void historyNotification(OperationHistoryEvent event) { + final int type= event.getEventType(); + switch (type) { + case OperationHistoryEvent.ABOUT_TO_UNDO: + case OperationHistoryEvent.ABOUT_TO_REDO: + // if this is one of our operations + if (event.getOperation().hasContext(fUndoContext)) { + // if we are undoing/redoing an operation we generated, then + // ignore + // the document changes associated with this undo or redo. + if (cast(UndoableTextChange)event.getOperation() ) { + listenToTextChanges(false); + + // in the undo case only, make sure compounds are closed + if (type is OperationHistoryEvent.ABOUT_TO_UNDO) { + if (fFoldingIntoCompoundChange) { + endCompoundChange(); + } + } + } else { + // the undo or redo has our context, but it is not one + // of our edits. We will listen to the changes, but will + // reset the state that tracks the undo/redo history. + commit(); + fLastAddedTextEdit= null; + } + fOperation= event.getOperation(); + } + break; + case OperationHistoryEvent.UNDONE: + case OperationHistoryEvent.REDONE: + case OperationHistoryEvent.OPERATION_NOT_OK: + if (event.getOperation() is fOperation) { + listenToTextChanges(true); + fOperation= null; + } + break; + } + } + + } + + + /** + * The undo context for this document undo manager. + */ + private ObjectUndoContext fUndoContext; + + /** + * The document whose changes are being tracked. + */ + private IDocument fDocument; + + /** + * The currently constructed edit. + */ + private UndoableTextChange fCurrent; + + /** + * The internal document listener. + */ + private DocumentListener fDocumentListener; + + /** + * Indicates whether the current change belongs to a compound change. + */ + private bool fFoldingIntoCompoundChange= false; + + /** + * The operation history being used to store the undo history. + */ + private IOperationHistory fHistory; + + /** + * The operation history listener used for managing undo and redo before and + * after the individual edits are performed. + */ + private IOperationHistoryListener fHistoryListener; + + /** + * The text edit last added to the operation history. This must be tracked + * internally instead of asking the history, since outside parties may be + * placing items on our undo/redo history. + */ + private UndoableTextChange fLastAddedTextEdit= null; + + /** + * The document modification stamp for redo. + */ + private long fPreservedRedoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; + + /** + * Text buffer to collect viewer content which has been replaced + */ + private StringBuffer fPreservedTextBuffer; + + /** + * The document modification stamp for undo. + */ + private long fPreservedUndoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; + + /** + * The last delete text edit. + */ + private UndoableTextChange fPreviousDelete; + + /** + * Text buffer to collect text which is inserted into the viewer + */ + private StringBuffer fTextBuffer; + + /** Indicates inserting state. */ + private bool fInserting= false; + + /** Indicates overwriting state. */ + private bool fOverwriting= false; + + /** The registered document listeners. */ + private ListenerList fDocumentUndoListeners; + + /** The list of clients connected. */ + private List fConnected; + + /** + * + * Create a DocumentUndoManager for the given document. + * + * @param document the document whose undo history is being managed. + */ + public this(IDocument document) { +// super(); + Assert.isNotNull(cast(Object)document); + fDocument= document; + fHistory= OperationHistoryFactory.getOperationHistory(); + fUndoContext= new ObjectUndoContext(cast(Object)fDocument); + fConnected= new ArrayList(); + fDocumentUndoListeners= new ListenerList(ListenerList.IDENTITY); + } + + /* + * @see dwtx.jface.text.IDocumentUndoManager#addDocumentUndoListener(dwtx.jface.text.IDocumentUndoListener) + */ + public void addDocumentUndoListener(IDocumentUndoListener listener) { + fDocumentUndoListeners.add(cast(Object)listener); + } + + /* + * @see dwtx.jface.text.IDocumentUndoManager#removeDocumentUndoListener(dwtx.jface.text.IDocumentUndoListener) + */ + public void removeDocumentUndoListener(IDocumentUndoListener listener) { + fDocumentUndoListeners.remove(cast(Object)listener); + } + + /* + * @see dwtx.jface.text.IDocumentUndoManager#getUndoContext() + */ + public IUndoContext getUndoContext() { + return fUndoContext; + } + + /* + * @see dwtx.jface.text.IDocumentUndoManager#commit() + */ + public void commit() { + // if fCurrent has never been placed on the history, do so now. + // this can happen when there are multiple programmatically commits in a + // single document change. + if (fLastAddedTextEdit !is fCurrent) { + fCurrent.pretendCommit(); + if (fCurrent.isValid()) + addToOperationHistory(fCurrent); + } + fCurrent.commit(); + } + + /* + * @see dwtx.text.undo.IDocumentUndoManager#reset() + */ + public void reset() { + if (isConnected()) { + shutdown(); + initialize(); + } + } + + /* + * @see dwtx.text.undo.IDocumentUndoManager#redoable() + */ + public bool redoable() { + return OperationHistoryFactory.getOperationHistory().canRedo(fUndoContext); + } + + /* + * @see dwtx.text.undo.IDocumentUndoManager#undoable() + */ + public bool undoable() { + return OperationHistoryFactory.getOperationHistory().canUndo(fUndoContext); + } + + /* + * @see dwtx.text.undo.IDocumentUndoManager#undo() + */ + public void redo() { + if (isConnected() && redoable()) + OperationHistoryFactory.getOperationHistory().redo(getUndoContext(), null, null); + } + + /* + * @see dwtx.text.undo.IDocumentUndoManager#undo() + */ + public void undo() { + if (undoable()) + OperationHistoryFactory.getOperationHistory().undo(fUndoContext, null, null); + } + + /* + * @see dwtx.jface.text.IDocumentUndoManager#connect(java.lang.Object) + */ + public void connect(Object client) { + if (!isConnected()) { + initialize(); + } + if (!fConnected.contains(client)) + fConnected.add(client); + } + + /* + * @see dwtx.jface.text.IDocumentUndoManager#disconnect(java.lang.Object) + */ + public void disconnect(Object client) { + fConnected.remove(client); + if (!isConnected()) { + shutdown(); + } + } + + /* + * @see dwtx.jface.text.IDocumentUndoManager#beginCompoundChange() + */ + public void beginCompoundChange() { + if (isConnected()) { + fFoldingIntoCompoundChange= true; + commit(); + } + } + + /* + * @see dwtx.jface.text.IDocumentUndoManager#endCompoundChange() + */ + public void endCompoundChange() { + if (isConnected()) { + fFoldingIntoCompoundChange= false; + commit(); + } + } + + /* + * @see dwtx.jface.text.IDocumentUndoManager#setUndoLimit(int) + */ + public void setMaximalUndoLevel(int undoLimit) { + fHistory.setLimit(fUndoContext, undoLimit); + } + + /** + * Fires a document undo event to all registered document undo listeners. + * Uses a robust iterator. + * + * @param offset the document offset + * @param text the text that was inserted + * @param preservedText the text being replaced + * @param source the source which triggered the event + * @param eventType the type of event causing the change + * @param isCompound a flag indicating whether the change is a compound change + * @see IDocumentUndoListener + */ + void fireDocumentUndo(int offset, String text, String preservedText, Object source, int eventType, bool isCompound) { + eventType= isCompound ? eventType | DocumentUndoEvent.COMPOUND : eventType; + DocumentUndoEvent event= new DocumentUndoEvent(fDocument, offset, text, preservedText, eventType, source); + Object[] listeners= fDocumentUndoListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) { + (cast(IDocumentUndoListener)listeners[i]).documentUndoNotification(event); + } + } + + /** + * Adds any listeners needed to track the document and the operations + * history. + */ + private void addListeners() { + fHistoryListener= new HistoryListener(); + fHistory.addOperationHistoryListener(fHistoryListener); + listenToTextChanges(true); + } + + /** + * Removes any listeners that were installed by the document. + */ + private void removeListeners() { + listenToTextChanges(false); + fHistory.removeOperationHistoryListener(fHistoryListener); + fHistoryListener= null; + } + + /** + * Adds the given text edit to the operation history if it is not part of a + * compound change. + * + * @param edit + * the edit to be added + */ + private void addToOperationHistory(UndoableTextChange edit) { + if (!fFoldingIntoCompoundChange + || cast(UndoableCompoundTextChange)edit ) { + fHistory.add(edit); + fLastAddedTextEdit= edit; + } + } + + /** + * Disposes the undo history. + */ + private void disposeUndoHistory() { + fHistory.dispose(fUndoContext, true, true, true); + } + + /** + * Initializes the undo history. + */ + private void initializeUndoHistory() { + if (fHistory !is null && fUndoContext !is null) + fHistory.dispose(fUndoContext, true, true, false); + + } + + /** + * Checks whether the given text starts with a line delimiter and + * subsequently contains a white space only. + * + * @param text the text to check + * @return true if the text is a line delimiter followed by + * whitespace, false otherwise + */ + private bool isWhitespaceText(String text) { + + if (text is null || text.length() is 0) + return false; + + String[] delimiters= fDocument.getLegalLineDelimiters(); + int index= TextUtilities.startsWith(delimiters, text); + if (index > -1) { + char c; + int length= text.length(); + for (int i= delimiters[index].length; i < length; i++) { + c= text.charAt(i); + if (c !is ' ' && c !is '\t') + return false; + } + return true; + } + + return false; + } + + /** + * Switches the state of whether there is a text listener or not. + * + * @param listen the state which should be established + */ + private void listenToTextChanges(bool listen) { + if (listen) { + if (fDocumentListener is null && fDocument !is null) { + fDocumentListener= new DocumentListener(); + fDocument.addDocumentListener(fDocumentListener); + } + } else if (!listen) { + if (fDocumentListener !is null && fDocument !is null) { + fDocument.removeDocumentListener(fDocumentListener); + fDocumentListener= null; + } + } + } + + private void processChange(int modelStart, int modelEnd, + String insertedText, String replacedText, + long beforeChangeModificationStamp, + long afterChangeModificationStamp) { + + if (insertedText is null) + insertedText= ""; //$NON-NLS-1$ + + if (replacedText is null) + replacedText= ""; //$NON-NLS-1$ + + int length= insertedText.length(); + int diff= modelEnd - modelStart; + + if (fCurrent.fUndoModificationStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP) + fCurrent.fUndoModificationStamp= beforeChangeModificationStamp; + + // normalize + if (diff < 0) { + int tmp= modelEnd; + modelEnd= modelStart; + modelStart= tmp; + } + + if (modelStart is modelEnd) { + // text will be inserted + if ((length is 1) || isWhitespaceText(insertedText)) { + // by typing or whitespace + if (!fInserting + || (modelStart !is fCurrent.fStart + + fTextBuffer.length())) { + fCurrent.fRedoModificationStamp= beforeChangeModificationStamp; + if (fCurrent.attemptCommit()) + fCurrent.fUndoModificationStamp= beforeChangeModificationStamp; + + fInserting= true; + } + if (fCurrent.fStart < 0) + fCurrent.fStart= fCurrent.fEnd= modelStart; + if (length > 0) + fTextBuffer.append(insertedText); + } else if (length > 0) { + // by pasting or model manipulation + fCurrent.fRedoModificationStamp= beforeChangeModificationStamp; + if (fCurrent.attemptCommit()) + fCurrent.fUndoModificationStamp= beforeChangeModificationStamp; + + fCurrent.fStart= fCurrent.fEnd= modelStart; + fTextBuffer.append(insertedText); + fCurrent.fRedoModificationStamp= afterChangeModificationStamp; + if (fCurrent.attemptCommit()) + fCurrent.fUndoModificationStamp= afterChangeModificationStamp; + + } + } else { + if (length is 0) { + // text will be deleted by backspace or DEL key or empty + // clipboard + length= replacedText.length; + String[] delimiters= fDocument.getLegalLineDelimiters(); + + if ((length is 1) + || TextUtilities.equals(delimiters, replacedText) > -1) { + + // whereby selection is empty + + if (fPreviousDelete.fStart is modelStart + && fPreviousDelete.fEnd is modelEnd) { + // repeated DEL + + // correct wrong settings of fCurrent + if (fCurrent.fStart is modelEnd + && fCurrent.fEnd is modelStart) { + fCurrent.fStart= modelStart; + fCurrent.fEnd= modelEnd; + } + // append to buffer && extend edit range + fPreservedTextBuffer.append(replacedText); + ++fCurrent.fEnd; + + } else if (fPreviousDelete.fStart is modelEnd) { + // repeated backspace + + // insert in buffer and extend edit range + fPreservedTextBuffer.select(0,0); + fPreservedTextBuffer.replace(replacedText); + fCurrent.fStart= modelStart; + + } else { + // either DEL or backspace for the first time + + fCurrent.fRedoModificationStamp= beforeChangeModificationStamp; + if (fCurrent.attemptCommit()) + fCurrent.fUndoModificationStamp= beforeChangeModificationStamp; + + // as we can not decide whether it was DEL or backspace + // we initialize for backspace + fPreservedTextBuffer.append(replacedText); + fCurrent.fStart= modelStart; + fCurrent.fEnd= modelEnd; + } + + fPreviousDelete.set(modelStart, modelEnd); + + } else if (length > 0) { + // whereby selection is not empty + fCurrent.fRedoModificationStamp= beforeChangeModificationStamp; + if (fCurrent.attemptCommit()) + fCurrent.fUndoModificationStamp= beforeChangeModificationStamp; + + fCurrent.fStart= modelStart; + fCurrent.fEnd= modelEnd; + fPreservedTextBuffer.append(replacedText); + } + } else { + // text will be replaced + + if (length is 1) { + length= replacedText.length; + String[] delimiters= fDocument.getLegalLineDelimiters(); + + if ((length is 1) + || TextUtilities.equals(delimiters, replacedText) > -1) { + // because of overwrite mode or model manipulation + if (!fOverwriting + || (modelStart !is fCurrent.fStart + + fTextBuffer.length())) { + fCurrent.fRedoModificationStamp= beforeChangeModificationStamp; + if (fCurrent.attemptCommit()) + fCurrent.fUndoModificationStamp= beforeChangeModificationStamp; + + fOverwriting= true; + } + + if (fCurrent.fStart < 0) + fCurrent.fStart= modelStart; + + fCurrent.fEnd= modelEnd; + fTextBuffer.append(insertedText); + fPreservedTextBuffer.append(replacedText); + fCurrent.fRedoModificationStamp= afterChangeModificationStamp; + return; + } + } + // because of typing or pasting whereby selection is not empty + fCurrent.fRedoModificationStamp= beforeChangeModificationStamp; + if (fCurrent.attemptCommit()) + fCurrent.fUndoModificationStamp= beforeChangeModificationStamp; + + fCurrent.fStart= modelStart; + fCurrent.fEnd= modelEnd; + fTextBuffer.append(insertedText); + fPreservedTextBuffer.append(replacedText); + } + } + // in all cases, the redo modification stamp is updated on the open + // text edit + fCurrent.fRedoModificationStamp= afterChangeModificationStamp; + } + + /** + * Initialize the receiver. + */ + private void initialize() { + initializeUndoHistory(); + + // open up the current text edit + fCurrent= new UndoableTextChange(this); + fPreviousDelete= new UndoableTextChange(this); + fTextBuffer= new StringBuffer(); + fPreservedTextBuffer= new StringBuffer(); + + addListeners(); + } + + /** + * Reset processChange state. + * + * @since 3.2 + */ + private void resetProcessChangeState() { + fInserting= false; + fOverwriting= false; + fPreviousDelete.reinitialize(); + } + + /** + * Shutdown the receiver. + */ + private void shutdown() { + removeListeners(); + + fCurrent= null; + fPreviousDelete= null; + fTextBuffer.clear(); + fPreservedTextBuffer.clear(); + + disposeUndoHistory(); + } + + /** + * Return whether or not any clients are connected to the receiver. + * + * @return true if the receiver is connected to + * clients, false if it is not + */ + bool isConnected() { + if (fConnected is null) + return false; + return !fConnected.isEmpty(); + } + + /* + * @see dwtx.jface.text.IDocumentUndoManager#transferUndoHistory(IDocumentUndoManager) + */ + public void transferUndoHistory(IDocumentUndoManager manager) { + IUndoContext oldUndoContext= manager.getUndoContext(); + // Get the history for the old undo context. + IUndoableOperation [] operations= OperationHistoryFactory.getOperationHistory().getUndoHistory(oldUndoContext); + for (int i= 0; i < operations.length; i++) { + // First replace the undo context + IUndoableOperation op= operations[i]; + if (cast(IContextReplacingOperation)op ) { + (cast(IContextReplacingOperation)op).replaceContext(oldUndoContext, getUndoContext()); + } else { + op.addContext(getUndoContext()); + op.removeContext(oldUndoContext); + } + // Now update the manager that owns the text edit. + if (cast(UndoableTextChange)op ) { + (cast(UndoableTextChange)op).fDocumentUndoManager= this; + } + } + + IUndoableOperation op= OperationHistoryFactory.getOperationHistory().getUndoOperation(getUndoContext()); + if (op !is null && !(cast(UndoableTextChange)op )) + return; + + // Record the transfer itself as an undoable change. + // If the transfer results from some open operation, recording this change will + // cause our undo context to be added to the outer operation. If there is no + // outer operation, there will be a local change to signify the transfer. + // This also serves to synchronize the modification stamps with the documents. + UndoableTextChange cmd= new UndoableTextChange(this); + cmd.fStart= cmd.fEnd= 0; + cmd.fText= cmd.fPreservedText= ""; //$NON-NLS-1$ + if (cast(IDocumentExtension4)fDocument ) { + cmd.fRedoModificationStamp= (cast(IDocumentExtension4)fDocument).getModificationStamp(); + if (op !is null) + cmd.fUndoModificationStamp= (cast(UndoableTextChange)op).fRedoModificationStamp; + } + addToOperationHistory(cmd); + } + + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/undo/DocumentUndoManagerRegistry.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/undo/DocumentUndoManagerRegistry.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,122 @@ +/******************************************************************************* + * 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 + * 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.text.undo.DocumentUndoManagerRegistry; + +import dwtx.text.undo.DocumentUndoManager; // packageimport +import dwtx.text.undo.DocumentUndoEvent; // packageimport +import dwtx.text.undo.IDocumentUndoListener; // packageimport +import dwtx.text.undo.UndoMessages; // packageimport +import dwtx.text.undo.IDocumentUndoManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.dwtxhelper.Collection; + + +import dwtx.core.runtime.Assert; +import dwtx.jface.text.IDocument; + + +/** + * This document undo manager registry provides access to a document's + * undo manager. In order to connect a document a document undo manager + * call connect. After that call has successfully completed + * undo manager can be obtained via getDocumentUndoManager. + * The undo manager is created on the first connect and disposed on the last + * disconnect, i.e. this registry keeps track of how often a undo manager is + * connected and returns the same undo manager to each client as long as the + * document is connected. + *

                        + * The recoding of changes starts with the first {@link #connect(IDocument)}.

                        + * + * @since 3.2 + * @noinstantiate This class is not intended to be instantiated by clients. + */ +public final class DocumentUndoManagerRegistry { + + private static final class Record { + public this(IDocument document) { + count= 0; + undoManager= new DocumentUndoManager(document); + } + private int count; + private IDocumentUndoManager undoManager; + } + + private static Map fgFactory_; + private static Map fgFactory(){ + if( fgFactory_ is null ) fgFactory_ = new HashMap(); + return fgFactory_; + } + + private this() { + // Do not instantiate + } + + + /** + * Connects the file at the given location to this manager. After that call + * successfully completed it is guaranteed that each call to getFileBuffer + * returns the same file buffer until disconnect is called. + *

                        + * The recoding of changes starts with the first {@link #connect(IDocument)}.

                        + * + * @param document the document to be connected + */ + public static synchronized void connect(IDocument document) { + Assert.isNotNull(cast(Object)document); + Record record= cast(Record)fgFactory.get(cast(Object)document); + if (record is null) { + record= new Record(document); + fgFactory.put(cast(Object)document, record); + } + record.count++; + } + + /** + * Disconnects the given document from this registry. + * + * @param document the document to be disconnected + */ + public static synchronized void disconnect(IDocument document) { + Assert.isNotNull(cast(Object)document); + Record record= cast(Record)fgFactory.get(cast(Object)document); + record.count--; + if (record.count is 0) + fgFactory.remove(cast(Object)document); + + } + + /** + * Returns the file buffer managed for the given location or null + * if there is no such file buffer. + *

                        + * The provided location is either a full path of a workspace resource or + * an absolute path in the local file system. The file buffer manager does + * not resolve the location of workspace resources in the case of linked + * resources. + *

                        + * + * @param document the document for which to get its undo manager + * @return the document undo manager or null + */ + public static synchronized IDocumentUndoManager getDocumentUndoManager(IDocument document) { + Assert.isNotNull(cast(Object)document); + Record record= cast(Record)fgFactory.get(cast(Object)document); + if (record is null) + return null; + return record.undoManager; + } + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/undo/IDocumentUndoListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/undo/IDocumentUndoListener.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,45 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.text.undo.IDocumentUndoListener; + +import dwtx.text.undo.DocumentUndoEvent; // packageimport + + +import dwt.dwthelper.utils; + + +/** + * This interface is used to listen to notifications from a DocumentUndoManager. + * The supplied DocumentUndoEvent describes the particular notification. + *

                        + * Document undo listeners must be prepared to receive notifications from a + * background thread. Any UI access occurring inside the implementation must be + * properly synchronized using the techniques specified by the client's widget + * library.

                        + *

                        + * Clients may implement this interface. + *

                        + * + * @since 3.2 + */ +public interface IDocumentUndoListener { + + /** + * The document is involved in an undo-related change. Notify listeners + * with an event describing the change. + * + * @param event the document undo event that describes the particular notification + */ + void documentUndoNotification(DocumentUndoEvent event); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/undo/IDocumentUndoManager.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/undo/IDocumentUndoManager.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,181 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.text.undo.IDocumentUndoManager; + +// import dwtx.text.undo.DocumentUndoManager; // packageimport +// import dwtx.text.undo.DocumentUndoManagerRegistry; // packageimport +import dwtx.text.undo.DocumentUndoEvent; // packageimport +import dwtx.text.undo.IDocumentUndoListener; // packageimport +// import dwtx.text.undo.UndoMessages; // packageimport + + +import dwt.dwthelper.utils; + +import dwtx.core.commands.ExecutionException; +import dwtx.core.commands.operations.IUndoContext; + +/** + * Interface for a document undo manager. Tracks changes in a document and + * builds a history of text commands that describe the undoable changes to the + * document. + *

                        + * Clients must explicitly connect to the undo manager to express their interest + * in the undo history. Clients should disconnect from the undo manager when + * they are no longer interested in tracking the undo history. If there are no + * clients connected to the undo manager, it will not track the document's + * changes and will dispose of any history that was previously kept.

                        + *

                        + * Clients may also listen to the undo manager for notifications before and + * after undo or redo events are performed. Clients must connect to the undo + * manager in addition to registering listeners.

                        + *

                        + * Clients may implement this interface. + *

                        + * + * @see DocumentUndoManagerRegistry + * @see IDocumentUndoListener + * @see dwtx.jface.text.IDocument + * @since 3.2 + */ +public interface IDocumentUndoManager { + + /** + * Adds the specified listener to the list of document undo listeners that + * are notified before and after changes are undone or redone in the + * document. This method has no effect if the instance being added is + * already in the list. + *

                        + * Notifications will not be received if there are no clients connected to + * the receiver. Registering a document undo listener does not implicitly + * connect the listener to the receiver.

                        + *

                        + * Document undo listeners must be prepared to receive notifications from a + * background thread. Any UI access occurring inside the implementation must + * be properly synchronized using the techniques specified by the client's + * widget library.

                        + * + * @param listener the document undo listener to be added as a listener + */ + void addDocumentUndoListener(IDocumentUndoListener listener); + + /** + * Removes the specified listener from the list of document undo listeners. + *

                        + * Removing a listener which is not registered has no effect + *

                        + * + * @param listener the document undo listener to be removed + */ + void removeDocumentUndoListener(IDocumentUndoListener listener); + + /** + * Returns the undo context registered for this document + * + * @return the undo context registered for this document + */ + IUndoContext getUndoContext(); + + /** + * Closes the currently open text edit and open a new one. + */ + void commit(); + + /** + * Connects to the undo manager. Used to signify that a client is monitoring + * the history kept by the undo manager. This message has no effect if the + * client is already connected. + * + * @param client the object connecting to the undo manager + */ + void connect(Object client); + + /** + * Disconnects from the undo manager. Used to signify that a client is no + * longer monitoring the history kept by the undo manager. If all clients + * have disconnected from the undo manager, the undo history will be + * deleted. + * + * @param client the object disconnecting from the undo manager + */ + void disconnect(Object client); + + /** + * Signals the undo manager that all subsequent changes until + * endCompoundChange is called are to be undone in one piece. + */ + void beginCompoundChange(); + + /** + * Signals the undo manager that the sequence of changes which started with + * beginCompoundChange has been finished. All subsequent + * changes are considered to be individually undo-able. + */ + void endCompoundChange(); + + /** + * Sets the limit of the undo history to the specified value. The provided + * limit will supersede any previously set limit. + * + * @param undoLimit the length of this undo manager's history + */ + void setMaximalUndoLevel(int undoLimit); + + /** + * Resets the history of the undo manager. After that call, + * there aren't any undo-able or redo-able text changes. + */ + void reset(); + + /** + * Returns whether at least one text change can be rolled back. + * + * @return true if at least one text change can be rolled back + */ + bool undoable(); + + /** + * Returns whether at least one text change can be repeated. A text change + * can be repeated only if it was executed and rolled back. + * + * @return true if at least on text change can be repeated + */ + bool redoable(); + + /** + * Rolls back the most recently executed text change. + * + * @throws ExecutionException if an exception occurred during undo + */ + void undo() ; + + /** + * Repeats the most recently rolled back text change. + * + * @throws ExecutionException if an exception occurred during redo + */ + void redo() ; + + /** + * Transfers the undo history from the specified document undo manager to + * this undo manager. This message should only be used when it is known + * that the content of the document of the original undo manager when the + * last undo operation was recorded is the same as this undo manager's + * current document content, since the undo history is based on document + * indexes. It is the responsibility of the caller + * to ensure that this call is used correctly. + * + * @param manager the document undo manger whose history is to be transferred to the receiver + */ + public void transferUndoHistory(IDocumentUndoManager manager); + +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/undo/UndoMessages.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/undo/UndoMessages.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,57 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.text.undo.UndoMessages; + +import dwtx.text.undo.DocumentUndoManager; // packageimport +import dwtx.text.undo.DocumentUndoManagerRegistry; // packageimport +import dwtx.text.undo.DocumentUndoEvent; // packageimport +import dwtx.text.undo.IDocumentUndoListener; // packageimport +import dwtx.text.undo.IDocumentUndoManager; // packageimport + + +import dwt.dwthelper.utils; + +import dwt.dwthelper.ResourceBundle; +import dwtx.dwtxhelper.MessageFormat; + +/** + * Helper class to get NLSed messages. + * + * @since 3.2 + */ +final class UndoMessages { + +// private static const String BUNDLE_NAME= "dwtx.text.undo.UndoMessages"; //$NON-NLS-1$ + + private static const ResourceBundle RESOURCE_BUNDLE;//= ResourceBundle.getBundle(BUNDLE_NAME); + + static this() { + RESOURCE_BUNDLE = ResourceBundle.getBundle( + getImportData!("dwtx.text.undo.UndoMessages.properties")); + } + + private this() { + } + + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' ~ key ~ '!'; + } + } + + public static String getFormattedString(String key, Object[] args...) { + return MessageFormat.format(getString(key), args); + } +} diff -r 20cdc983a411 -r 71ec57b4c8f3 dwtx/text/undo/UndoMessages.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/text/undo/UndoMessages.properties Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,12 @@ +############################################################################### +# 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 +############################################################################### + +DocumentUndoManager.operationLabel= Typing diff -r 20cdc983a411 -r 71ec57b4c8f3 fixmodule.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fixmodule.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,87 @@ +module packageimport; + +import tango.io.FilePath; +import tango.io.File; +import tango.io.Buffer; +import tango.io.stream.FileStream; +import tango.io.stream.TextFileStream; +import tango.util.log.Trace; +import tango.text.Regex; +import tango.text.Util; +import tango.text.stream.LineIterator; +import tango.text.convert.Format; + +void processDir( char[] dir ){ + auto pack = dir.dup.replace( '/', '.' ); + auto fp = FilePath(dir); + char[][] mods; + // read all module names + foreach( fileinfo; fp ){ + if( fileinfo.folder ){ + processDir( fileinfo.path ~ fileinfo.name ); + continue; + } + if( fileinfo.name.length > 2 && fileinfo.name[ $-2 .. $ ] == ".d" ){ + mods ~= fileinfo.name.dup; + } + } + // foreach module + foreach( mod; mods ){ + auto filename = Format("{}/{}", dir, mod ); + auto cont = cast(char[])File( filename ).read; + char[][] lines = cont.splitLines(); + int modLine = -1; + foreach( uint idx, char[] line; lines ){ + if( line.length && line.locatePattern( "module dwtx" ) is 0 ){ + //Trace.formatln( "mod: {} {}", idx, line ); + modLine = idx; + break; + } + } + int impLine = -1; + foreach( uint idx, char[] line; lines ){ + if( line.length && line.locatePattern( "import dwtx" ) is 0 ){ + //Trace.formatln( "imp: {} {}", idx, line ); + impLine = idx; + break; + } + } + assert( modLine !is -1 ); + assert( impLine !is -1 ); + if( modLine > impLine ){ + Trace.formatln( "{} {} {} {}", filename, modLine, impLine, lines.length ); + auto moddecl = lines[ modLine .. modLine + 2 ].dup; + for( int i = modLine; i >= impLine+1; i-- ){ + lines[i+1] = lines[i-1]; + } + lines[ impLine .. impLine+2 ] = moddecl; + auto output = new TextFileOutput( filename ); + bool first = true; + foreach( line; lines ){ + if( !first ){ + output.write( \n ); + } + first = false; + output.write( line ); + } + output.flush(); + output.close(); + } + } + // read content into buffer + // search module statement and print to outfile + // write package imports + // write all remaining lines +} + +void main(){ + processDir( "dwtx/text" ); + processDir( "dwtx/jface/text" ); + processDir( "dwtx/jface/internal/text" ); +} + + + + + + diff -r 20cdc983a411 -r 71ec57b4c8f3 packageimport.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/packageimport.d Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,82 @@ +module packageimport; + +import tango.io.FilePath; +import tango.io.File; +import tango.io.Buffer; +import tango.io.stream.FileStream; +import tango.io.stream.TextFileStream; +import tango.util.log.Trace; +import tango.text.Regex; +import tango.text.Util; +import tango.text.stream.LineIterator; +import tango.text.convert.Format; + +void processDir( char[] dir ){ + auto pack = dir.dup.replace( '/', '.' ); + auto fp = FilePath(dir); + char[][] mods; + // read all module names + foreach( fileinfo; fp ){ + if( fileinfo.folder ){ + processDir( fileinfo.path ~ fileinfo.name ); + continue; + } + if( fileinfo.name.length > 2 && fileinfo.name[ $-2 .. $ ] == ".d" ){ + mods ~= fileinfo.name.dup; + } + } + // foreach module + foreach( mod; mods ){ + auto filename = Format("{}/{}", dir, mod ); + Trace.formatln( "{}", filename ); + auto cont = cast(char[])File( filename ).read; + auto output = new TextFileOutput( filename ); + bool firstline = true; + void println( char[] l ){ + if( !firstline ){ + output.newline(); + } + output(l); + firstline = false; + } + bool found = false; + auto it = new LineIterator!(char)( new Buffer( cont )); + foreach( line; it ){ + println(line); + if( line.length && line.locatePattern( "module " ) is 0 ){ + found = true; + break; + } + } + assert( found ); + println( "" ); + foreach( impmod; mods ){ + if( impmod == mod ){ + continue; + } + println( Format( "import {}.{}; // packageimport", pack, impmod[ 0 .. $-2] )); + } + println( "" ); + foreach( line; it ){ + println(line); + } + output.flush(); + output.close(); + } + // read content into buffer + // search module statement and print to outfile + // write package imports + // write all remaining lines +} + +void main(){ + processDir( "dwtx/text" ); + processDir( "dwtx/jface/text" ); + processDir( "dwtx/jface/internal/text" ); +} + + + + + + diff -r 20cdc983a411 -r 71ec57b4c8f3 res/dwtx.jface.internal.text.html.HTMLMessages.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/res/dwtx.jface.internal.text.html.HTMLMessages.properties Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,16 @@ +############################################################################### +# 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 +############################################################################### + + +HTMLTextPresenter.ellipse= ... + +# The following property value must end with a space +HTML2TextReader.listItemPrefix=\t-\ diff -r 20cdc983a411 -r 71ec57b4c8f3 res/dwtx.jface.internal.text.link.contentassist.ContentAssistMessages.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/res/dwtx.jface.internal.text.link.contentassist.ContentAssistMessages.properties Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,20 @@ +############################################################################### +# Copyright (c) 2000, 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 +############################################################################### + + +InfoPopup.info_delay_timer_name=AdditionalInfo Delay + +ContentAssistant.assist_delay_timer_name=AutoAssist Delay + +HTMLTextPresenter.ellipse= ... + +# The following property value must end with a space +HTML2TextReader.listItemPrefix=\t-\ diff -r 20cdc983a411 -r 71ec57b4c8f3 res/dwtx.jface.text.JFaceTextMessages.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/res/dwtx.jface.text.JFaceTextMessages.properties Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,45 @@ +############################################################################### +# 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 +############################################################################### + + +TextViewer.error.bad_location.WidgetCommand.setEvent= TextViewer.WidgetCommand.setEvent: BadLocationException +TextViewer.error.bad_location.findAndSelect= TextViewer.findAndSelect: BadLocationException +TextViewer.error.bad_location.getBottomIndex= TextViewer.getBottomIndex: BadLocationException +TextViewer.error.bad_location.getBottomIndexEndOffset= TextViewer.getBottomIndexEndOffset: BadLocationException +TextViewer.error.bad_location.getFirstCompleteLineOfRegion= TextViewer.getFirstCompleteLineOfRegion: BadLocationException +TextViewer.error.bad_location.getTopIndex= TextViewer.getTopIndex: BadLocationException +TextViewer.error.bad_location.getTopIndexStartOffset= TextViewer.getTopIndexStartOffset: BadLocationException +TextViewer.error.bad_location.selectContentTypePlugin= TextViewer.selectContentTypePlugin: BadLocationException +TextViewer.error.bad_location.setTopIndex_1= TextViewer.setTopIndex: BadLocationException +TextViewer.error.bad_location.setTopIndex_2= TextViewer.setTopIndex: BadLocationException +TextViewer.error.bad_location.shift_1= TextViewer.shift: BadLocationException +TextViewer.error.bad_location.shift_2= TextViewer.shift: BadLocationException +TextViewer.error.bad_location.verifyText= TextViewer.verifyText: BadLocationException +TextViewer.error.invalid_range= Invalid range argument +TextViewer.error.invalid_visible_region_1= Invalid visible region argument +TextViewer.error.invalid_visible_region_2= Invalid visible region argument + +AbstractHoverInformationControlManager.hover.restarter= Hover Restart Delay + +# The first parameter is the annotation type label and the second is the number of annotations +OverviewRulerHeader.toolTipTextEntry= {0}: {1} + +DefaultUndoManager.operationLabel= Typing +DefaultUndoManager.error.undoFailed.title= Undo Failed +DefaultUndoManager.error.redoFailed.title= Redo Failed + +DefaultAnnotationHover.multipleMarkers= Multiple markers at this line +# The parameter is the text of the list item +DefaultAnnotationHover.listItem= - {0} + +# The parameter is the line number +DefaultAnnotationHover.lineNumber=Line: {0} + diff -r 20cdc983a411 -r 71ec57b4c8f3 res/dwtx.jface.text.RegExMessages.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/res/dwtx.jface.text.RegExMessages.properties Mon Sep 08 01:38:10 2008 +0200 @@ -0,0 +1,535 @@ +############################################################################### +# 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 +# Cagatay Calli - [find/replace] retain caps when replacing - https://bugs.eclipse.org/bugs/show_bug.cgi?id=28949 +# Cagatay Calli - [find/replace] define & fix behavior of retain caps with other escapes and text before \C - https://bugs.eclipse.org/bugs/show_bug.cgi?id=217061 +############################################################################### + +## Content Assist for regular expressions ## +# use \\\u0075 for a backslash-u +displayString_bs_bs= \\\\ - Backslash +additionalInfo_bs_bs= Backslash +displayString_bs_0= \\0nnn - Octal character code +additionalInfo_bs_0= Octal character code\n\nExamples:\n\\011 (tabulator)\n\\0112 (character J) +displayString_bs_x= \\xhh - Hex character code +additionalInfo_bs_x= Hexadecimal character code\n\nExamples:\n\\x09 (tabulator)\n\\x4A or \\x4a (character J) +displayString_bs_u= \\\u0075hhhh - Hex code for Unicode character +additionalInfo_bs_u= Hexadecimal code for Unicode character\n\nExamples:\n\\\u0075004A (character J)\n\\\u007503B2 (lowercase Greek letter beta: \u03B2) +displayString_bs_t= \\t - Tab +additionalInfo_bs_t= Tabulator (\\x09, decimal: 9) +displayString_bs_R= \\R - Line delimiter (platform independent) +additionalInfo_bs_R= Line delimiter (platform independent)\n\n\ +This pattern matches any form of line delimiter, i.e.\n\ +- Windows (\\r\\n)\n\ +- Unix (\\n)\n\ +- Mac OS 9 (\\r)\n\n\ +Note that this pattern does not work inside []. +displayString_bs_n= \\n - Newline +additionalInfo_bs_n= Newline (\\x0A, decimal: 10)\n\n\ +WARNING: \\n only finds newline characters. \ +This can lead to unexpected results when the actual document uses different line delimiters.\n\n\ +RECOMMENDATION: use \\R to find a line delimiter. +displayString_bs_r= \\r - CR +additionalInfo_bs_r= Carriage Return (\\x0D, decimal: 13)\n\n\ +WARNING: \\r only finds carriage return characters. \ +This can lead to unexpected results when the actual document uses different line delimiters.\n\n\ +RECOMMENDATION: use \\R to find a line delimiter. +displayString_bs_f= \\f - FF +additionalInfo_bs_f= Form Feed (\\x0C, decimal: 12) +displayString_bs_a= \\a - Beep +additionalInfo_bs_a= Beep, Bell, Alert (\\x07, decimal: 7) +displayString_bs_e= \\e - Esc +additionalInfo_bs_e= Escape (\\x1B, decimal: 27) +displayString_bs_c= \\cC - Control character +additionalInfo_bs_c= Control character for C\n\nExample:\n\\cC (Ctrl+C, \\x03, decimal: 3) + +displayString_dot= . - Any character +additionalInfo_dot= The dot matches any character except line terminators.\n\n\ +To make the dot match line terminators as well, \n\ +start the expression with the embedded flag expression \n\ +"(?s)" (without quotes). +displayString_bs_d= \\d - A digit +additionalInfo_bs_d= A digit: [0-9] +displayString_bs_D= \\D - Not a digit +additionalInfo_bs_D= Not a digit: [^0-9] +displayString_bs_s= \\s - A whitespace +additionalInfo_bs_s= A whitespace: [ \\t\\n\\x0B\\f\\r] +displayString_bs_S= \\S - Not a whitespace +additionalInfo_bs_S= Not a whitespace: [^\\s] +displayString_bs_w= \\w - An alphanumeric (word character) +additionalInfo_bs_w= An alphanumeric (a word character): [a-zA-Z_0-9] +displayString_bs_W= \\W - Not an alphanumeric +additionalInfo_bs_W= Not an alphanumeric (not a word character): [^\\w] + +displayString_start= ^ - Line start +additionalInfo_start= Line start (positional match)\n\nExample:\n\ +The expression "^Eclipse" matches the term "Eclipse"\n\ +only on the second line of text\n\ +"The Eclipse Project\n\ +Eclipse Platform". +displayString_end= $ - Line end +additionalInfo_end= Line end (positional match)\n\nExample:\n\ +The expression "Eclipse$" matches the term "Eclipse"\n\ +only on the second line of text\n\ +"- Install the Eclipse Platform\n\ +- Run Eclipse". +displayString_bs_b= \\b- Word beginning or end +additionalInfo_bs_b= Word beginning or end (positional match)\n\nExample:\n\ +The expression "s\\b" matches only the last "s" of "glasses" in text\n\ +"I lost my glasses." +displayString_bs_B= \\B - Not a word beginning or end +additionalInfo_bs_B= Not a word beginning or end (positional match)\n\nExample:\n\ +The expression "\\BS" matches only "S" of "printString" in text\n\ +"void print(String printString)". +displayString_bs_A= \\A - Start of input +additionalInfo_bs_A= Start of input (positional match)\n\nExample:\n\ +The expression "\\ABC" matches only "BC" of "BCD" in text\n\ +"BCD ABC\n\ +BCDEF". +displayString_bs_G= \\G - Previous match's end +additionalInfo_bs_G= Previous match's end (positional match)\n\nExample:\n\ +The expression "\\Ga" matches the first and then the second "a" in text\n\ +"aardvark" (when starting from the beginning). +displayString_bs_Z= \\Z - End of input, does not consider last line terminator +additionalInfo_bs_Z= End of input, does not consider last line terminator (positional match)\n\n\ +The expression matches at the end of the file, except for when the\n\ +file ends in a line terminator, in which case it matches before that\n\ +line terminator.\n\nExample:\n\ +The expression "ing\\Z" matches "ing" in text\n\ +"testing", as well as in text\n\ +"testing\n\ +", but doesn't match in text\n\ +"testing\n\ +\n\ +" +displayString_bs_z= \\z - End of input +additionalInfo_bs_z= End of input (positional match)\n\nExample:\n\ +The expression "ing\\z" matches "ing" in text\n\ +"testing", but doesn't match in text\n\ +"testing\n\ +" + +### repetition quantifiers ### +displayString_quest= ? - Greedy match 0 or 1 times +additionalInfo_quest= Greedy match 0 or 1 times.\n\n\ +First tries to match the preceding token.\n\ +Falls back to not matching if this choice made a full match impossible.\n\nExample:\n\ +The expression "fo?" matches "f", "fo", and "fo" in text\n\ +"f fo foo". +displayString_star= * - Greedy match 0 or more times +additionalInfo_star= Greedy match 0 or more times.\n\n\ +First tries to match the preceding token as many times as possible.\n\ +Falls back to matching it less often if this choice made a full match impossible.\n\nExamples:\n\ +- The expression "fo*" matches "f", "fo", and "foo" in text\n\ +"f fo foo".\n\ +- The expression "fo*o\\d" matches all three words in text\n\ +"fo1 foo2 fooo3".\n\ +- The expression "<.*>" matches the whole text\n\ +"

                        bold". +displayString_plus= + - Greedy match 1 or more times +additionalInfo_plus= Greedy match 1 or more times\n\n\ +First tries to match the preceding token as many times as possible.\n\ +Falls back to matching it less often if this choice made a full match impossible.\n\nExamples:\n\ +- The expression "fo+" matches "fo" and "foo" in text\n\ +"f fo foo".\n\ +- The expression "fo+o\\d" matches "foo2" and "fooo3" in text\n\ +"fo1 foo2 fooo3".\n\ +- The expression "<.+>" matches the whole text\n\ +"

                        bold", but does not match anywhere in "<>". +displayString_exact= {n} - Greedy match exactly n times +additionalInfo_exact= Greedy match exactly n times.\n\nExamples:\n\ +- The expression "\\\\0[0-3][0-7]{2}" matches all three-digit octal character tokens.\n\ +- The expression "\\b\\w{4}\\b" matches all four-letter-words\n\ +such as "Java", "cool", or "food" (but not "dog"). +displayString_least= {n,} - Greedy match >= n times +additionalInfo_least= Greedy match >= n times.\n\n\ +First tries to match the preceding token as many times as possible.\n\ +Falls back to matching it less often (but at least n times),\n\ +if this choice made a full match impossible.\n\nExamples:\n\ +- The expression "fo{2,}" matches "foo" and "fooo" in text\n\ +"f fo foo fooo".\n\ +- The expression "fo{2,}o\\d" matches "fooo3" and "foooo4" in text\n\ +"fo1 foo2 fooo3 foooo4".\n\ +- The expression "10{3,}[^0]" matches all powers of ten that are larger than one thousand.\n\n\ +Note: The expressions "{0,}" and "*" are equivalent;\n\ +likewise, "{1,}" is equivalent to "+". +displayString_count= {n,m} - Greedy match >= n times but <= m times +additionalInfo_count= Greedy match >= n times but <= m times.\n\n\ +First tries to match the preceding token m times.\n\ +Falls back to matching it less often (but at least n times),\n\ +if this choice made a full match impossible.\n\nExamples:\n\ +- The expression "fo{1,2}" matches "fo", "foo", and "foo" in text\n\ +"f fo foo fooo".\n\ +- The expression "fo{1,2}o\\d" matches "foo2" and "fooo3" in text\n\ +"fo1 foo2 fooo3 foooo4".\n\ +- The expression "^.{70,80}$" matches all the lines that contain\n\ +between 70 and 80 characters (inclusive). + +displayString_questLazy= ?? - Lazy match 0 or 1 times +additionalInfo_questLazy= Lazy match 0 or 1 times.\n\n\ +First tries to not match the preceding token.\n\ +Falls back to matching it if this choice made a full match impossible.\n\nExample:\n\ +The expression "fo??" matches "f", "f", and "f" in text\n\ +"f fo foo". +displayString_starLazy= *? - Lazy match 0 or more times +additionalInfo_starLazy= Lazy match 0 or more times.\n\n\ +First tries to not match the preceding token.\n\ +Falls back to matching it more often if this choice made a full match impossible.\n\nExamples:\n\ +- The expression "fo*?" matches "f", "f", and "f" in text\n\ +"f fo foo".\n\ +- The expression "fo*?o\\d" matches all three words in text\n\ +"fo1 foo2 fooo3".\n\ +- The expression "<.*?>" matches "

                        ", "", and "" in text\n\ +"

                        bold". Note: a more performant expression for finding\n\ +xml tags is "<[^>]*>", which avoids backtracking. +displayString_plusLazy= +? - Lazy match 1 or more times +additionalInfo_plusLazy= Lazy match 1 or more times\n\n\ +First tries to match the preceding token once.\n\ +Falls back to matching it more often if this choice made a full match impossible.\n\nExamples:\n\ +- The expression "fo+?" matches "fo" and "fo" in text\n\ +"f fo foo".\n\ +- The expression "fo+?o\\d" matches "foo2" and "fooo3" in text\n\ +"fo1 foo2 fooo3".\n\ +- The expression "<.+?>" matches "

                        ", "", and "" in text\n\ +"

                        bold". Note: a more performant expression for finding\n\ +xml tags is "<[^>]*>", which avoids backtracking. +displayString_exactLazy= {n}? - Lazy match exactly n times +additionalInfo_exactLazy= Lazy match exactly n times.\n\n\ +This expression is equivalent to the expression\n\ +{n} - Greedy match exactly n times. +displayString_leastLazy= {n,}? - Lazy match >= n times +additionalInfo_leastLazy= Lazy match >= n times.\n\n\ +First tries to match the preceding token n times. Falls back to\n\ +matching it more often, if this choice made a full match impossible.\n\nExamples:\n\ +- The expression "fo{2,}?" matches "foo" and "foo" in text\n\ +"f fo foo fooo".\n\ +- The expression "fo{2,}?o\\d" matches "fooo3" and "foooo4" in text\n\ +"fo1 foo2 fooo3 foooo4".\n\ +- The expression "10{3,}?[^0]" matches all powers of ten that are larger than one thousand.\n\n\ +Note: The expressions "{0,}?" and "*?" are equivalent;\n\ +likewise, "{1,}?" is equivalent to "+?". +displayString_countLazy= {n,m}? - Lazy match >= n times but <= m times +additionalInfo_countLazy= Lazy match >= n times but <= m times.\n\n\ +First tries to match the preceding token n times.\n\ +Falls back to matching it more often (but at most m times),\n\ +if this choice made a full match impossible.\n\nExamples:\n\ +- The expression "fo{1,2}?" matches "fo", "fo", and "fo" in text\n\ +"f fo foo fooo".\n\ +- The expression "fo{1,2}?o\\d" matches "foo2" and "fooo3" in text\n\ +"fo1 foo2 fooo3 foooo4".\n\ + +displayString_questPoss= ?+ - Possessive match 0 or 1 times (no backtracking) +additionalInfo_questPoss= Possessive match 0 or 1 times.\n\n\ +Matches the preceding token if possible. Never backtracks,\n\ +even if this choice renders a full match impossible.\n\nExample:\n\ +The expression "fo?+o\\d" matches the first, but not the second line in text\n\ +"foo1\n\ +fo1". +displayString_starPoss= *+ Possessive match 0 or more times (no backtracking) +additionalInfo_starPoss= Possessive match 0 or more times.\n\n\ +Tries to match the preceding token as many times as possible. Never backtracks,\n\ +even if this choice renders a full match impossible.\n\nExamples:\n\ +- The expression "fo*+" matches "f", "fo" and "foo" in text\n\ +"f fo foo".\n\ +- The expression "fo*+o\\d" matches nowhere in text\n\ +"fo1 foo2 fooo3".\n\ +- The expression "<.*+>" matches nowhere in text\n\ +"

                        bold". +displayString_plusPoss= ++ - Possessive match 1 or more times (no backtracking) +additionalInfo_plusPoss= Possessive match 1 or more times.\n\n\ +Tries to match the preceding token as many times as possible. Never backtracks,\n\ +even if this choice renders a full match impossible.\n\nExamples:\n\ +- The expression "fo++" matches "fo" and "foo" in text\n\ +"f fo foo".\n\ +- The expression "fo++o\\d" matches nowhere in text\n\ +"fo1 foo2 fooo3".\n\ +- The expression "<.++>" matches nowhere in text\n\ +"

                        bold". + +displayString_exactPoss= {n}+ - Possessive match exactly n times (no backtracking) +additionalInfo_exactPoss= Possessive match exactly n times.\n\n\ +This expression is equivalent to the expression\n\ +{n} - Greedy match exactly n times. +displayString_leastPoss= {n,}+ - Possessive match >= n times (no backtracking) +additionalInfo_leastPoss= Possessive match >= n times.\n\n\ +Tries to match the preceding token as many times as possible, but at least n times.\n\ +Never backtracks, even if this choice renders a full match impossible.\n\nExamples:\n\ +- The expression "fo{2,}+" matches "foo" and "fooo" in text\n\ +"f fo foo fooo".\n\ +- The expression "fo{2,}?o\\d" matches nowhere in text\n\ +"fo1 foo2 fooo3 foooo4".\n\ +Note: The expressions "{0,}?" and "*?" are equivalent;\n\ +likewise, "{1,}?" is equivalent to "+?". + +displayString_countPoss= {n,m}+ - Possessive match >= n times but <= m times (no backtracking) +additionalInfo_countPoss= Possessive match >= n times but <= m times.\n\n\ +Tries to match the preceding token as many times as possible, \n\ +at least n times and at most m times.\n\ +Never backtracks, even if this choice renders a full match impossible.\n\nExamples:\n\ +- The expression "fo{1,2}+" matches "fo", "foo", and "foo" in text\n\ +"f fo foo fooo".\n\ +- The expression "fo{1,2}+o\\d" matches only "fooo3" in text\n\ +"fo1 foo2 fooo3 foooo4".\n\ +- The expression "^.{70,80}+$" matches all the lines that contain\n\ +between 70 and 80 characters (inclusive). + +displayString_alt= U|V - Alternation: U or V +additionalInfo_alt= Alternation.\n\n\ +First tries to match subexpression U. Falls back and tries to match V if U didn't match.\n\nExamples:\n\ +- The expression "A|B" applied to text "BA" first matches "B", then "A".\n\ +- The expression "AB|BC|CD" applied to text "ABC BC DAB" matches, in sequence:\n\ +"AB" in the first word, the second word "BC", "AB" at the very end. +displayString_group= (Expr) - Mark Expr as capturing group +additionalInfo_group= Mark Expr as capturing group.\n\n\ +Capturing groups are numbered by counting their opening parentheses from left to right.\n\ +In the expression "((A)(B(C)))", for example, there are four such groups:\n\ +1 ((A)(B(C)))\n\ +2 (A)\n\ +3 (B(C))\n\ +4 (C)\n\ +\n\ +Group zero always stands for the entire expression. During a match,\n\ +each subsequence of the input sequence that matches such a group is saved.\n\ +The captured subsequence i may be used later in the expression, via a back reference "\\i",\n\ +and may also be used in the replace string via "$i".\n\ +\n\ +Note: Groups beginning with (? are pure, non-capturing groups that\n\ +do not capture text and do not count towards the group total. + +displayString_bs_i= \\i - Match of the capturing group i +additionalInfo_bs_i= Match of the capturing group i.\n\n\ +\\i matches the subsequence that has already been saved as capturing group i.\n\ +\\0 is not a valid group number in the regular expression.\n\nExample:\n\ +The expression "(\\d+)\\+\\1" matches "10+10" in text "9+10+10+11".\n\ +\n\ +Note: in the replace string, $i stands for the capturing group i. + +displayString_bs= \\ - Quote next character +additionalInfo_bs= Quote next character\n\nExample:\n\ +The expression "\\{\\n\\}" matches the text "{n}". + +displayString_bs_Q= \\Q - Start quoting +additionalInfo_bs_Q= Start quoting\n\n\ +All characters between \\Q and the next \\E are taken literally and are not interpreted.\n\nExample:\n\ +The expression "\\Qnew int[] {42}\\E;" matches text "new int[] {42}". +displayString_bs_E= \\E - End quoting +additionalInfo_bs_E= End quoting\n\n\ +All characters between \\Q and the next \\E are taken literally and are not interpreted.\n\nExample:\n\ +The expression "\\Qnew int[] {42}\\E;" matches text "new int[] {42}". + +displayString_set= [ecl] - Character set +additionalInfo_set= Character set\n\n\ +Matches a single character out of the set.\n\nExample:\n\ +The expression "[ecl]" matches "c" and "l" in text "cold". +displayString_setExcl= [^ecl] - Excluded character set +additionalInfo_setExcl= Excluded character set\n\n\ +Matches a single character that is not one of the excluded characters.\n\nExamples:\n\ +The expression "[^ecl]" matches "o" and "d" in text "cold".\n\ +The expression "[a-z&&[^ecl]]" matches any character from a to z, excluding e, c, and l. +displayString_setRange= [c-l] - Character range +additionalInfo_setRange= Character range\n\n\ +Matches a single character out of the range from 'c' to 'l'.\n\nExamples:\n\ +The expression "[c-l]" matches "c", "l", and "d" in text "cold".\n\ +The expression "[a-z&&[^ecl]]" matches any character from a to z, excluding e, c, and l. +displayString_setInter= && - Intersection of character sets +additionalInfo_setInter= Intersection of character sets\n\n\ +Matches a character that is in both of the given sets.\n\nExample:\n\ +The expression "[a-z&&[^ecl]]" matches any character from a to z, excluding e, c, and l. + +displayString_posix= \\p{Class} - POSIX or Unicode character class +additionalInfo_posix= POSIX or Unicode character class\n\n\ +Matches a character from the given character class 'Class'.\n\ +Valid classes are:\n\ +\n\ +- POSIX character classes (US-ASCII only):\n\ +\ Lower, Upper, ASCII, Alpha, Digit, Alnum, Punct,\n\ +\ Graph, Print, Blank, Cntrl, XDigit, and Space.\n\ +\n\ +- Unicode blocks (with the prefix 'In'), e.g.:\n\ +\ InBasicLatin\n\ +\ InLatin-1Supplement\n\ +\ InGreek\n\ +\n\ +- Unicode categories, e.g.:\n\ +\ Lu: Uppercase Letter\n\ +\ Ll: Lowercase Letter\n\ +\ L: Letter\n\ +\ N: Number\n\ +\ Z: Separator\n\ +\ LD: Letter or Digit\n\ +\ L1: Latin-1 + +displayString_posixNot= \\P{Class} - Excluded POSIX or Unicode character class +additionalInfo_posixNot= Excluded POSIX or Unicode character class\n\n\ +Negation of character set \\p{Class}. Example:\n\ +\\P{ASCII} is equivalent to [^\\p{ASCII}] and matches all non-ASCII characters.\n\n\ +Valid classes are:\n\ +\n\ +- POSIX character classes (US-ASCII only):\n\ +\ Lower, Upper, ASCII, Alpha, Digit, Alnum, Punct,\n\ +\ Graph, Print, Blank, Cntrl, XDigit, and Space.\n\ +\n\ +- Unicode blocks (with the prefix 'In'), e.g.:\n\ +\ InBasicLatin\n\ +\ InLatin-1Supplement\n\ +\ InGreek\n\ +\n\ +- Unicode categories, e.g.:\n\ +\ Lu: Uppercase Letter\n\ +\ Ll: Lowercase Letter\n\ +\ L: Letter\n\ +\ N: Number\n\ +\ Z: Separator\n\ +\ LD: Letter or Digit\n\ +\ L1: Latin-1 + + +#Flags: +displayString_flag= (?ismd-ismd) - Turn flags on or off +additionalInfo_flag= Turn flags on and off for the rest of the matching process.\n\n\ +Flags before the dash are turned on; those after the dash are turned off.\n\ +The following flags are supported:\n\ +- i: case-insensitive matching\n\ +\n\ +- s: single-line, or dotall matching mode:\n\ +\ The expression . matches any character, including a line terminator.\n\ +\n\ +- m: multiline matching mode:\n\ +\ The expressions ^ and $ match just after or just before,\n\ +\ respectively, a line terminator or the end of the input sequence.\n\ +\ When multiline matching is turned off, these expressions only\n\ +\ match at the beginning and the end of the entire input sequence.\n\ +\ This flag is ON by default.\n\ +\n\ +- d: Unix lines matching mode:\n\ +\ Only the '\\n' line terminator\n\ +\ is recognized in the behavior of ., ^, and $ +# - u: unicode-aware case folding:\n\ +# Case-insensitive matching, when enabled, is done in a manner consistent\n\ +# with the Unicode Standard. By default, case-insensitive matching\n\ +# assumes that only characters in the US-ASCII charset are being matched. +# - c: canonical equivalence\n\ +# Two characters will be considered to match if, and only if, their full\n\ +# canonical decompositions match. The expression "a\\\u0075030A", for example,\n\ +# will match the string "a\u030A" when this flag is specified.\n\ +# By default, matching does not take canonical equivalence into account. +# - x: comments mode\n\ +# Whitespace is ignored, and embedded comments starting with\n\ +# # are ignored until the end of a line.\n\ + +displayString_flagExpr= (?ismd-ismd:Expr) - Turn flags on or off in Expr +additionalInfo_flagExpr= Turn flags on and off in Expr.\n\n\ +Flags before the dash are turned on; those after the dash are turned off.\n\ +The following flags are supported:\n\ +- i: case-insensitive matching\n\ +\n\ +- s: single-line, or dotall matching mode:\n\ +\ The expression . matches any character, including a line terminator.\n\ +\n\ +- m: multiline matching mode:\n\ +\ The expressions ^ and $ match just after or just before,\n\ +\ respectively, a line terminator or the end of the input sequence.\n\ +\ When multiline matching is turned off, these expressions only\n\ +\ match at the beginning and the end of the entire input sequence.\n\ +\ This flag is ON by default.\n\ +\n\ +- d: Unix lines matching mode:\n\ +\ Only the '\\n' line terminator\n\ +\ is recognized in the behavior of ., ^, and $ + + +#Noncapturing groups: +displayString_nonCap= (?:Expr) - Non-capturing group +additionalInfo_nonCap= Non-capturing group of regular expression Expr.\n\n\ +The group is not saved in a back reference.\n\nExample:\n\ +The expression "(?:\\w+) (\\d+)" matches "bug 42" in text "It's bug 42.".\n\ +A back reference "$1" in the replace string will be replaced by "42". + +displayString_atomicCap= (?>Expr) - Non-capturing atomic group +additionalInfo_atomicCap= Non-capturing atomic group of regular expression Expr.\n\n\ +Matches the regular expression Expr once, but does not backtrack into the expression\n\ +again if the first match did not prove to be successful later on.\n\ +The group is not saved in a back reference. + +#Lookaround: +displayString_posLookahead= (?=Expr) - Zero-width positive lookahead +additionalInfo_posLookahead= Expr, via zero-width positive lookahead.\n\n\ +Matches a position (zero-width: does not consume the matched characters),\n\ +where the next characters (-> lookahead)\n\ +do match (-> positive) the embedded expression Expr.\n\nExamples:\n\ +- The expression "var(?==)" matches only the first "var" in text "var=17; other=var;".\n\ +- The expression "\\b(?=\\w{7}\\b)\\w*clip\\w*\\b" matches any\n\ +seven-letter-word that contains "clip". It matches "Eclipse", but not "paperclip". + +displayString_negLookahead= (?!Expr) - Zero-width negative lookahead +additionalInfo_negLookahead= Expr, via zero-width negative lookahead.\n\n\ +Matches a position (zero-width: does not consume the matched characters),\n\ +where the next characters (-> lookahead)\n\ +do not match (-> negative) the embedded expression Expr.\n\nExamples:\n\ +- The expression "var(?!=)" matches only the second "var" in text "var=17; other=var;".\n\ +- The expression "\\b(?!\\w{5,7}\\b)\\w*clip\\w*\\b" matches any\n\ +word that contains "clip" and consists of less than 5 or more than 7 characters.\n\ +It matches "clip" and "paperclip", but not "Eclipse". + +displayString_posLookbehind= (?<=Expr) - Zero-width positive lookbehind +additionalInfo_posLookbehind= Expr, via zero-width positive lookbehind.\n\n\ +Matches a position (zero-width: does not consume the matched characters),\n\ +where the previous characters (-> lookbehind)\n\ +do match (-> positive) the embedded expression Expr.\n\nExample:\n\ +- The expression "\\w{5,}+(?<=as)\\b" matches "alias" and "bananas",\n\ +but does not match "peas", "apples", or "Alaska". + +displayString_negLookbehind= (? lookbehind)\n\ +do not match (-> negative) the embedded expression Expr.\n\nExample:\n\ +- The expression "\\w{5,}+(?

                        + * Clients are allowed to implement subclasses of a multi-text + * edit.Subclasses must implement doCopy() to ensure + * the a copy of the right type is created. Not implementing + * doCopy() in subclasses will result in an assertion + * failure during copying. + * + * @since 3.0 + */ +public class MultiTextEdit : TextEdit { + + private bool fDefined; + + /** + * Creates a new MultiTextEdit. The range + * of the edit is determined by the range of its children. + * + * Adding this edit to a parent edit sets its range to the + * range covered by its children. If the edit doesn't have + * any children its offset is set to the parent's offset + * and its length is set to 0. + */ + public this() { + super(0, Integer.MAX_VALUE); + fDefined= false; + } + + /** + * Creates a new MultiTextEdit for the given + * range. Adding a child to this edit which isn't covered + * by the given range will result in an exception. + * + * @param offset the edit's offset + * @param length the edit's length. + * @see TextEdit#addChild(TextEdit) + * @see TextEdit#addChildren(TextEdit[]) + */ + public this(int offset, int length) { + super(offset, length); + fDefined= true; + } + + /* + * Copy constructor. + */ + protected this(MultiTextEdit other) { + super(other); + } + + /** + * Checks the edit's integrity. + *