Bug 500331 - Contribute https://github.com/sbrosinski/RegexTester/ to e4
Change-Id: Icce0f01f2bc63539d6f8501180ea91ef41bd4eff
Signed-off-by: Lars Vogel <Lars.Vogel@vogella.com>
diff --git a/bundles/org.eclipse.ui.regex/.classpath b/bundles/org.eclipse.ui.regex/.classpath
new file mode 100644
index 0000000..ad32c83
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.ui.regex/.gitignore b/bundles/org.eclipse.ui.regex/.gitignore
new file mode 100644
index 0000000..ce96585
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+bin
+.settings
diff --git a/bundles/org.eclipse.ui.regex/.project b/bundles/org.eclipse.ui.regex/.project
new file mode 100644
index 0000000..1a0f4a6
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.ui.regex</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.ui.regex/LICENSE.md b/bundles/org.eclipse.ui.regex/LICENSE.md
new file mode 100644
index 0000000..f735bee
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/LICENSE.md
@@ -0,0 +1,203 @@
+Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
+LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
+CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and documentation
+ distributed under this Agreement, and
+b) in the case of each subsequent Contributor:
+ i) changes to the Program, and
+ ii) additions to the Program;
+
+ where such changes and/or additions to the Program originate from and are
+ distributed by that particular Contributor. A Contribution 'originates'
+ from a Contributor if it was added to the Program by such Contributor
+ itself or anyone acting on such Contributor's behalf. Contributions do not
+ include additions to the Program which: (i) are separate modules of
+ software distributed in conjunction with the Program under their own
+ license agreement, and (ii) are not derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents" mean patent claims licensable by a Contributor which are
+necessarily infringed by the use or sale of its Contribution alone or when
+combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this
+Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement,
+including all Contributors.
+
+2. GRANT OF RIGHTS
+ a) Subject to the terms of this Agreement, each Contributor hereby grants
+ Recipient a non-exclusive, worldwide, royalty-free copyright license to
+ reproduce, prepare derivative works of, publicly display, publicly
+ perform, distribute and sublicense the Contribution of such Contributor,
+ if any, and such derivative works, in source code and object code form.
+ b) Subject to the terms of this Agreement, each Contributor hereby grants
+ Recipient a non-exclusive, worldwide, royalty-free patent license under
+ Licensed Patents to make, use, sell, offer to sell, import and otherwise
+ transfer the Contribution of such Contributor, if any, in source code and
+ object code form. This patent license shall apply to the combination of
+ the Contribution and the Program if, at the time the Contribution is
+ added by the Contributor, such addition of the Contribution causes such
+ combination to be covered by the Licensed Patents. The patent license
+ shall not apply to any other combinations which include the Contribution.
+ No hardware per se is licensed hereunder.
+ c) Recipient understands that although each Contributor grants the licenses
+ to its Contributions set forth herein, no assurances are provided by any
+ Contributor that the Program does not infringe the patent or other
+ intellectual property rights of any other entity. Each Contributor
+ disclaims any liability to Recipient for claims brought by any other
+ entity based on infringement of intellectual property rights or
+ otherwise. As a condition to exercising the rights and licenses granted
+ hereunder, each Recipient hereby assumes sole responsibility to secure
+ any other intellectual property rights needed, if any. For example, if a
+ third party patent license is required to allow Recipient to distribute
+ the Program, it is Recipient's responsibility to acquire that license
+ before distributing the Program.
+ d) Each Contributor represents that to its knowledge it has sufficient
+ copyright rights in its Contribution, if any, to grant the copyright
+ license set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under
+its own license agreement, provided that:
+
+ a) it complies with the terms and conditions of this Agreement; and
+ b) its license agreement:
+ i) effectively disclaims on behalf of all Contributors all warranties
+ and conditions, express and implied, including warranties or
+ conditions of title and non-infringement, and implied warranties or
+ conditions of merchantability and fitness for a particular purpose;
+ ii) effectively excludes on behalf of all Contributors all liability for
+ damages, including direct, indirect, special, incidental and
+ consequential damages, such as lost profits;
+ iii) states that any provisions which differ from this Agreement are
+ offered by that Contributor alone and not by any other party; and
+ iv) states that source code for the Program is available from such
+ Contributor, and informs licensees how to obtain it in a reasonable
+ manner on or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+ a) it must be made available under this Agreement; and
+ b) a copy of this Agreement must be included with each copy of the Program.
+ Contributors may not remove or alter any copyright notices contained
+ within the Program.
+
+Each Contributor must identify itself as the originator of its Contribution,
+if
+any, in a manner that reasonably allows subsequent Recipients to identify the
+originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with
+respect to end users, business partners and the like. While this license is
+intended to facilitate the commercial use of the Program, the Contributor who
+includes the Program in a commercial product offering should do so in a manner
+which does not create potential liability for other Contributors. Therefore,
+if a Contributor includes the Program in a commercial product offering, such
+Contributor ("Commercial Contributor") hereby agrees to defend and indemnify
+every other Contributor ("Indemnified Contributor") against any losses,
+damages and costs (collectively "Losses") arising from claims, lawsuits and
+other legal actions brought by a third party against the Indemnified
+Contributor to the extent caused by the acts or omissions of such Commercial
+Contributor in connection with its distribution of the Program in a commercial
+product offering. The obligations in this section do not apply to any claims
+or Losses relating to any actual or alleged intellectual property
+infringement. In order to qualify, an Indemnified Contributor must:
+a) promptly notify the Commercial Contributor in writing of such claim, and
+b) allow the Commercial Contributor to control, and cooperate with the
+Commercial Contributor in, the defense and any related settlement
+negotiations. The Indemnified Contributor may participate in any such claim at
+its own expense.
+
+For example, a Contributor might include the Program in a commercial product
+offering, Product X. That Contributor is then a Commercial Contributor. If
+that Commercial Contributor then makes performance claims, or offers
+warranties related to Product X, those performance claims and warranties are
+such Commercial Contributor's responsibility alone. Under this section, the
+Commercial Contributor would have to defend claims against the other
+Contributors related to those performance claims and warranties, and if a
+court requires any other Contributor to pay any damages as a result, the
+Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
+IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each
+Recipient is solely responsible for determining the appropriateness of using
+and distributing the Program and assumes all risks associated with its
+exercise of rights under this Agreement , including but not limited to the
+risks and costs of program errors, compliance with applicable laws, damage to
+or loss of data, programs or equipment, and unavailability or interruption of
+operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
+CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
+LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
+EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
+OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of the
+remainder of the terms of this Agreement, and without further action by the
+parties hereto, such provision shall be reformed to the minimum extent
+necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Program itself
+(excluding combinations of the Program with other software or hardware)
+infringes such Recipient's patent(s), then such Recipient's rights granted
+under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to
+comply with any of the material terms or conditions of this Agreement and does
+not cure such failure in a reasonable period of time after becoming aware of
+such noncompliance. If all Recipient's rights under this Agreement terminate,
+Recipient agrees to cease use and distribution of the Program as soon as
+reasonably practicable. However, Recipient's obligations under this Agreement
+and any licenses granted by Recipient relating to the Program shall continue
+and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in
+order to avoid inconsistency the Agreement is copyrighted and may only be
+modified in the following manner. The Agreement Steward reserves the right to
+publish new versions (including revisions) of this Agreement from time to
+time. No one other than the Agreement Steward has the right to modify this
+Agreement. The Eclipse Foundation is the initial Agreement Steward. The
+Eclipse Foundation may assign the responsibility to serve as the Agreement
+Steward to a suitable separate entity. Each new version of the Agreement will
+be given a distinguishing version number. The Program (including
+Contributions) may always be distributed subject to the version of the
+Agreement under which it was received. In addition, after a new version of the
+Agreement is published, Contributor may elect to distribute the Program
+(including its Contributions) under the new version. Except as expressly
+stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
+licenses to the intellectual property of any Contributor under this Agreement,
+whether expressly, by implication, estoppel or otherwise. All rights in the
+Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the
+intellectual property laws of the United States of America. No party to this
+Agreement will bring a legal action under this Agreement more than one year
+after the cause of action arose. Each party waives its rights to a jury trial in
+any resulting litigation.
diff --git a/bundles/org.eclipse.ui.regex/META-INF/MANIFEST.MF b/bundles/org.eclipse.ui.regex/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..11b7d4d
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: RegExTester
+Bundle-SymbolicName: org.eclipse.ui.regex;singleton:=true
+Bundle-Version: 1.4
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Require-Bundle: org.eclipse.ui;bundle-version="3.103.0",
+ org.eclipse.ui.ide;bundle-version="3.8.1",
+ org.eclipse.core.runtime;bundle-version="3.8.0",
+ org.eclipse.core.resources;bundle-version="3.8.1"
+Bundle-ActivationPolicy: lazy
+Bundle-Activator: org.eclipse.ui.regex.RegExPlugin
+Export-Package: org.eclipse.ui.regex,
+ org.eclipse.ui.regex.event,
+ org.eclipse.ui.regex.view,
+ org.eclipse.ui.regex.view.actions
diff --git a/bundles/org.eclipse.ui.regex/README.md b/bundles/org.eclipse.ui.regex/README.md
new file mode 100644
index 0000000..8d6dae9
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/README.md
@@ -0,0 +1,30 @@
+# RegexTester
+RegexTester is an Eclipse plugin which can be used to easily test regular expressions.
+
+
+
+## Features
+
+* Test and search for regular expression
+* Matches are colorized, for an easy visual clue
+* Support for pattern flags (e.g. Pattern.DOTALL)
+* LiveEval evaluates your regular expression while you are typing it, gives feedback on possible errors and shows any matches automatically
+* LiveEval is supported for changes of the regular expression, the search text and the pattern flags
+* 4 distinct match modes:
+ * Find a sequence of characters
+ * Match a complete text
+ * Split text
+ * Replace every occurence of the regex with a different string. Replacing supports back references ($1,$2,...)
+* LiveEval for match mode changes
+* Context sensitive "Regular Expression Assist"
+* Selective evaluation of expressions
+* Bracket Matching
+* Generation of string literals based on the regexp, e.g. "\(x\)" becomes "\\(x\\)"
+* De-escape patterns in your code, e.g. \\(x\\) becomes \(x\)
+* Improved "Clear Menu", choose which parts of the view you would like to get cleared every time you press the clear button
+* Easy movement through matches: Choose "Previous Match" or "Next Match" and cycle through all matches found.
+* Polished and accessible user interface, everything is reachable via keyboard
+
+## Installation
+
+[Download the plugin jar](https://github.com/sbrosinski/RegexTester/downloads) and put it in your Eclipse plugin folder.
diff --git a/bundles/org.eclipse.ui.regex/build.properties b/bundles/org.eclipse.ui.regex/build.properties
new file mode 100644
index 0000000..588f2c4
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/build.properties
@@ -0,0 +1,13 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ icons/,\
+ lib/,\
+ README.md,\
+ plugin.xml
+src.includes = icons/,\
+ lib/,\
+ src/,\
+ plugin.xml,\
+ build.properties
diff --git a/bundles/org.eclipse.ui.regex/epl-v10.html b/bundles/org.eclipse.ui.regex/epl-v10.html
new file mode 100644
index 0000000..894064c
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/epl-v10.html
@@ -0,0 +1,259 @@
+<!--?xml version="1.0" encoding="ISO-8859-1" ?-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<title>Eclipse Public License - Version 1.0</title>
+<style type="text/css">
+ body {
+ size: 8.5in 11.0in;
+ margin: 0.25in 0.5in 0.25in 0.5in;
+ tab-interval: 0.5in;
+ }
+ p {
+ margin-left: auto;
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+ }
+ p.list {
+ margin-left: 0.5in;
+ margin-top: 0.05em;
+ margin-bottom: 0.05em;
+ }
+ </style>
+
+</head>
+
+<body lang="EN-US">
+
+<h2>Eclipse Public License - v 1.0</h2>
+
+<p>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR
+DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS
+AGREEMENT.</p>
+
+<p><b>1. DEFINITIONS</b></p>
+
+<p>"Contribution" means:</p>
+
+<p class="list">a) in the case of the initial Contributor, the initial
+code and documentation distributed under this Agreement, and</p>
+<p class="list">b) in the case of each subsequent Contributor:</p>
+<p class="list">i) changes to the Program, and</p>
+<p class="list">ii) additions to the Program;</p>
+<p class="list">where such changes and/or additions to the Program
+originate from and are distributed by that particular Contributor. A
+Contribution 'originates' from a Contributor if it was added to the
+Program by such Contributor itself or anyone acting on such
+Contributor's behalf. Contributions do not include additions to the
+Program which: (i) are separate modules of software distributed in
+conjunction with the Program under their own license agreement, and (ii)
+are not derivative works of the Program.</p>
+
+<p>"Contributor" means any person or entity that distributes
+the Program.</p>
+
+<p>"Licensed Patents" mean patent claims licensable by a
+Contributor which are necessarily infringed by the use or sale of its
+Contribution alone or when combined with the Program.</p>
+
+<p>"Program" means the Contributions distributed in accordance
+with this Agreement.</p>
+
+<p>"Recipient" means anyone who receives the Program under
+this Agreement, including all Contributors.</p>
+
+<p><b>2. GRANT OF RIGHTS</b></p>
+
+<p class="list">a) Subject to the terms of this Agreement, each
+Contributor hereby grants Recipient a non-exclusive, worldwide,
+royalty-free copyright license to reproduce, prepare derivative works
+of, publicly display, publicly perform, distribute and sublicense the
+Contribution of such Contributor, if any, and such derivative works, in
+source code and object code form.</p>
+
+<p class="list">b) Subject to the terms of this Agreement, each
+Contributor hereby grants Recipient a non-exclusive, worldwide,
+royalty-free patent license under Licensed Patents to make, use, sell,
+offer to sell, import and otherwise transfer the Contribution of such
+Contributor, if any, in source code and object code form. This patent
+license shall apply to the combination of the Contribution and the
+Program if, at the time the Contribution is added by the Contributor,
+such addition of the Contribution causes such combination to be covered
+by the Licensed Patents. The patent license shall not apply to any other
+combinations which include the Contribution. No hardware per se is
+licensed hereunder.</p>
+
+<p class="list">c) Recipient understands that although each Contributor
+grants the licenses to its Contributions set forth herein, no assurances
+are provided by any Contributor that the Program does not infringe the
+patent or other intellectual property rights of any other entity. Each
+Contributor disclaims any liability to Recipient for claims brought by
+any other entity based on infringement of intellectual property rights
+or otherwise. As a condition to exercising the rights and licenses
+granted hereunder, each Recipient hereby assumes sole responsibility to
+secure any other intellectual property rights needed, if any. For
+example, if a third party patent license is required to allow Recipient
+to distribute the Program, it is Recipient's responsibility to acquire
+that license before distributing the Program.</p>
+
+<p class="list">d) Each Contributor represents that to its knowledge it
+has sufficient copyright rights in its Contribution, if any, to grant
+the copyright license set forth in this Agreement.</p>
+
+<p><b>3. REQUIREMENTS</b></p>
+
+<p>A Contributor may choose to distribute the Program in object code
+form under its own license agreement, provided that:</p>
+
+<p class="list">a) it complies with the terms and conditions of this
+Agreement; and</p>
+
+<p class="list">b) its license agreement:</p>
+
+<p class="list">i) effectively disclaims on behalf of all Contributors
+all warranties and conditions, express and implied, including warranties
+or conditions of title and non-infringement, and implied warranties or
+conditions of merchantability and fitness for a particular purpose;</p>
+
+<p class="list">ii) effectively excludes on behalf of all Contributors
+all liability for damages, including direct, indirect, special,
+incidental and consequential damages, such as lost profits;</p>
+
+<p class="list">iii) states that any provisions which differ from this
+Agreement are offered by that Contributor alone and not by any other
+party; and</p>
+
+<p class="list">iv) states that source code for the Program is available
+from such Contributor, and informs licensees how to obtain it in a
+reasonable manner on or through a medium customarily used for software
+exchange.</p>
+
+<p>When the Program is made available in source code form:</p>
+
+<p class="list">a) it must be made available under this Agreement; and</p>
+
+<p class="list">b) a copy of this Agreement must be included with each
+copy of the Program.</p>
+
+<p>Contributors may not remove or alter any copyright notices contained
+within the Program.</p>
+
+<p>Each Contributor must identify itself as the originator of its
+Contribution, if any, in a manner that reasonably allows subsequent
+Recipients to identify the originator of the Contribution.</p>
+
+<p><b>4. COMMERCIAL DISTRIBUTION</b></p>
+
+<p>Commercial distributors of software may accept certain
+responsibilities with respect to end users, business partners and the
+like. While this license is intended to facilitate the commercial use of
+the Program, the Contributor who includes the Program in a commercial
+product offering should do so in a manner which does not create
+potential liability for other Contributors. Therefore, if a Contributor
+includes the Program in a commercial product offering, such Contributor
+("Commercial Contributor") hereby agrees to defend and
+indemnify every other Contributor ("Indemnified Contributor")
+against any losses, damages and costs (collectively "Losses")
+arising from claims, lawsuits and other legal actions brought by a third
+party against the Indemnified Contributor to the extent caused by the
+acts or omissions of such Commercial Contributor in connection with its
+distribution of the Program in a commercial product offering. The
+obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In
+order to qualify, an Indemnified Contributor must: a) promptly notify
+the Commercial Contributor in writing of such claim, and b) allow the
+Commercial Contributor to control, and cooperate with the Commercial
+Contributor in, the defense and any related settlement negotiations. The
+Indemnified Contributor may participate in any such claim at its own
+expense.</p>
+
+<p>For example, a Contributor might include the Program in a commercial
+product offering, Product X. That Contributor is then a Commercial
+Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance
+claims and warranties are such Commercial Contributor's responsibility
+alone. Under this section, the Commercial Contributor would have to
+defend claims against the other Contributors related to those
+performance claims and warranties, and if a court requires any other
+Contributor to pay any damages as a result, the Commercial Contributor
+must pay those damages.</p>
+
+<p><b>5. NO WARRANTY</b></p>
+
+<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
+PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
+OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION,
+ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
+OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and
+distributing the Program and assumes all risks associated with its
+exercise of rights under this Agreement , including but not limited to
+the risks and costs of program errors, compliance with applicable laws,
+damage to or loss of data, programs or equipment, and unavailability or
+interruption of operations.</p>
+
+<p><b>6. DISCLAIMER OF LIABILITY</b></p>
+
+<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
+NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
+WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
+DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</p>
+
+<p><b>7. GENERAL</b></p>
+
+<p>If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of
+the remainder of the terms of this Agreement, and without further action
+by the parties hereto, such provision shall be reformed to the minimum
+extent necessary to make such provision valid and enforceable.</p>
+
+<p>If Recipient institutes patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that the
+Program itself (excluding combinations of the Program with other
+software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of the
+date such litigation is filed.</p>
+
+<p>All Recipient's rights under this Agreement shall terminate if it
+fails to comply with any of the material terms or conditions of this
+Agreement and does not cure such failure in a reasonable period of time
+after becoming aware of such noncompliance. If all Recipient's rights
+under this Agreement terminate, Recipient agrees to cease use and
+distribution of the Program as soon as reasonably practicable. However,
+Recipient's obligations under this Agreement and any licenses granted by
+Recipient relating to the Program shall continue and survive.</p>
+
+<p>Everyone is permitted to copy and distribute copies of this
+Agreement, but in order to avoid inconsistency the Agreement is
+copyrighted and may only be modified in the following manner. The
+Agreement Steward reserves the right to publish new versions (including
+revisions) of this Agreement from time to time. No one other than the
+Agreement Steward has the right to modify this Agreement. The Eclipse
+Foundation is the initial Agreement Steward. The Eclipse Foundation may
+assign the responsibility to serve as the Agreement Steward to a
+suitable separate entity. Each new version of the Agreement will be
+given a distinguishing version number. The Program (including
+Contributions) may always be distributed subject to the version of the
+Agreement under which it was received. In addition, after a new version
+of the Agreement is published, Contributor may elect to distribute the
+Program (including its Contributions) under the new version. Except as
+expressly stated in Sections 2(a) and 2(b) above, Recipient receives no
+rights or licenses to the intellectual property of any Contributor under
+this Agreement, whether expressly, by implication, estoppel or
+otherwise. All rights in the Program not expressly granted under this
+Agreement are reserved.</p>
+
+<p>This Agreement is governed by the laws of the State of New York and
+the intellectual property laws of the United States of America. No party
+to this Agreement will bring a legal action under this Agreement more
+than one year after the cause of action arose. Each party waives its
+rights to a jury trial in any resulting litigation.</p>
+
+
+
+</body></html>
\ No newline at end of file
diff --git a/bundles/org.eclipse.ui.regex/icons/backward_nav.gif b/bundles/org.eclipse.ui.regex/icons/backward_nav.gif
new file mode 100644
index 0000000..740419b
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/icons/backward_nav.gif
Binary files differ
diff --git a/bundles/org.eclipse.ui.regex/icons/clear_co.gif b/bundles/org.eclipse.ui.regex/icons/clear_co.gif
new file mode 100644
index 0000000..2558326
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/icons/clear_co.gif
Binary files differ
diff --git a/bundles/org.eclipse.ui.regex/icons/e.gif b/bundles/org.eclipse.ui.regex/icons/e.gif
new file mode 100644
index 0000000..7244b85
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/icons/e.gif
Binary files differ
diff --git a/bundles/org.eclipse.ui.regex/icons/forward_nav.gif b/bundles/org.eclipse.ui.regex/icons/forward_nav.gif
new file mode 100644
index 0000000..7a1511d
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/icons/forward_nav.gif
Binary files differ
diff --git a/bundles/org.eclipse.ui.regex/icons/nag.gif b/bundles/org.eclipse.ui.regex/icons/nag.gif
new file mode 100644
index 0000000..afee6cb
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/icons/nag.gif
Binary files differ
diff --git a/bundles/org.eclipse.ui.regex/icons/sample.gif b/bundles/org.eclipse.ui.regex/icons/sample.gif
new file mode 100644
index 0000000..34fb3c9
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/icons/sample.gif
Binary files differ
diff --git a/bundles/org.eclipse.ui.regex/lib/xstream-1.0.2.jar b/bundles/org.eclipse.ui.regex/lib/xstream-1.0.2.jar
new file mode 100644
index 0000000..ca614c8
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/lib/xstream-1.0.2.jar
Binary files differ
diff --git a/bundles/org.eclipse.ui.regex/plugin.xml b/bundles/org.eclipse.ui.regex/plugin.xml
new file mode 100644
index 0000000..9735cbd
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/plugin.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin>
+
+ <extension
+ point="org.eclipse.ui.views">
+ <category
+ name="RegEx Tester"
+ id="org.eclipse.ui.regex.cat">
+ </category>
+ <view
+ name="RegEx Tester"
+ icon="icons/e.gif"
+ category="org.eclipse.ui.regex.cat"
+ class="org.eclipse.ui.regex.view.RegExView"
+ id="org.eclipse.ui.regex.view.RegExView">
+ </view>
+ </extension>
+
+
+
+ <extension
+ point="org.eclipse.ui.preferencePages">
+ <page
+ name="RegEx Tester"
+ class="org.eclipse.ui.regex.view.RegExPreferencePage"
+ id="org.eclipse.ui.regex.view.RegExPreferencePage">
+ </page>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.preferencePages">
+ <page
+ name="Fonts"
+ class="org.eclipse.ui.regex.view.FontPreferencePage"
+ id="org.eclipse.ui.regex.view.FontPreferencePage"
+ category="org.eclipse.ui.regex.view.RegExPreferencePage">
+
+ </page>
+ </extension>
+
+
+</plugin>
diff --git a/bundles/org.eclipse.ui.regex/screenshots/regex2.png b/bundles/org.eclipse.ui.regex/screenshots/regex2.png
new file mode 100644
index 0000000..ebb15e3
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/screenshots/regex2.png
Binary files differ
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/Group.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/Group.java
new file mode 100644
index 0000000..8caf2ec
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/Group.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex;
+
+
+public class Group {
+
+ private int index;
+ private String text;
+
+ public Group(int index, String text) {
+ this.index = index;
+ this.text = text;
+ }
+
+
+
+ /**
+ * @return Returns the index.
+ */
+ public int getIndex() {
+ return index;
+ }
+ /**
+ * @return Returns the text.
+ */
+ public String getText() {
+ return text;
+ }
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/IRegExListener.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/IRegExListener.java
new file mode 100644
index 0000000..2a7dbec
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/IRegExListener.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex;
+
+import org.eclipse.ui.regex.event.IListener;
+
+
+public interface IRegExListener extends IListener {
+
+ public void foundMatches(Matches matches);
+ public void foundNoMatches();
+ public void expressionError(String errMsg);
+ public void doneWithReplace(ReplaceResult result);
+ public void doneWithSplit(String[] result);
+ public void updateRequested();
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/Match.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/Match.java
new file mode 100644
index 0000000..8fca7b6
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/Match.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Defines a single match with was found.
+ * @author sbrosinski
+ * @version $$Id: Match.java,v 1.4 2004/06/15 11:49:17 sbrosin Exp $$
+ */
+
+public class Match {
+ /** the match's start index within the search text */
+ private int start_;
+ /** the match's end index within the search text */
+ private int end_;
+
+ /** contains the match text actually found */
+ private String text_;
+
+ private ArrayList groups_;
+
+ /**
+ * Construct a Match.
+ * @param id an id, identifying the match uniquely
+ * @param start the match's start index within the search text
+ * @param end the match's end index within the search text
+ * @param text contains the match text actually found
+ */
+ public Match(int start, int end, String text) {
+ start_ = start;
+ end_ = end;
+ text_ = text;
+ groups_ = new ArrayList();
+ }
+
+ public void addGroup(Group group) {
+ groups_.add(group);
+ }
+
+ public int getGroupCount() {
+ return groups_.size();
+ }
+
+ public List getGroups() {
+ return groups_;
+ }
+
+ /**
+ * Gets the end index of found match.
+ * @return end index of found match
+ */
+ public int getEnd() {
+ return end_;
+ }
+
+
+ /**
+ * Gets the start index of found match.
+ * @return start index of found match
+ */
+ public int getStart() {
+ return start_;
+ }
+
+
+ /**
+ * Gets the match text.
+ * @return the match text
+ */
+ public String getText() {
+ return text_;
+ }
+
+
+
+ /**
+ * Sets the end end index of found match.
+ * @param end end index of found match
+ */
+ public void setEnd(int end) {
+ end_ = end;
+ }
+
+
+ /**
+ * Sets the start end index of found match.
+ * @param start start index of found match
+ */
+ public void setStart(int start) {
+ start_ = start;
+ }
+
+
+ /**
+ * Sets the match text.
+ * @param text the match text
+ */
+ public void setText(String text) {
+ text_ = text;
+ }
+
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/Matches.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/Matches.java
new file mode 100644
index 0000000..a2a3a15
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/Matches.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+
+/**
+ * Encapsulates all matches found during a single matching session.
+ * @author sbrosinski
+ * @version $$Id: Matches.java,v 1.6 2004/09/06 10:35:16 sbrosin Exp $$
+ */
+public class Matches {
+
+ /** a list containing all matches. */
+ private ArrayList matchList_;
+
+ /** virtual marker, can be set to a certain position within the matches
+ * list. Is used to provide previousMatch/nextMatch result scrolling.
+ * */
+ private int posMarker_;
+
+
+ /**
+ * Constructs a new Matches object.
+ */
+ public Matches() {
+ matchList_ = new ArrayList();
+ // set position marker "in front" of list
+ posMarker_ = -1;
+ }
+
+ public Iterator iterator() {
+ return matchList_.iterator();
+ }
+
+
+ /**
+ * Gets the number of matches found.
+ * @return number of matches.
+ */
+ public int getMatchCount() {
+ return matchList_.size();
+ }
+
+
+ /**
+ * Gets the postion of the internal list marker.
+ * @return position, 0 to numberOfMatches-1
+ */
+ public int getMatchPos() {
+ return posMarker_;
+ }
+
+
+ /**
+ * Returns the match found for a certain range withing the
+ * search text.
+ * @param start the range's start index
+ * @param end the range's end index
+ * @return one Match or null, if no match was found
+ */
+ public Match getMatchByRange(int start, int end) {
+ for (int i = 0; i < matchList_.size(); i++) {
+ Match match = (Match) matchList_.get(i);
+ if (start >= match.getStart() && end <= match.getEnd())
+ return match;
+ }
+ return null;
+ }
+
+
+ public void addMatch(Match match) {
+ matchList_.add(match);
+ }
+
+
+ public Match nextMatch() {
+ if (matchList_ == null)
+ return null;
+
+ if (!(posMarker_ + 1 > matchList_.size() - 1)) {
+ posMarker_++;
+ Match match = (Match) matchList_.get(posMarker_);
+ return match;
+ }
+
+ return null;
+ }
+
+
+ public Match prevMatch() {
+ if (matchList_ == null)
+ return null;
+
+ if (!(posMarker_ - 1 < 0)) {
+ posMarker_--;
+ Match match = (Match) matchList_.get(posMarker_);
+ return match;
+ }
+
+ return null;
+ }
+
+
+ public void resetMatchPos() {
+ posMarker_ = -1;
+ }
+
+
+ public void setMatchPos(int pos) {
+ posMarker_ = pos;
+ }
+
+
+ public void reset() {
+ matchList_ = new ArrayList();
+ }
+
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/RegExListenerManager.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/RegExListenerManager.java
new file mode 100644
index 0000000..678eb6e
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/RegExListenerManager.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.ui.regex;
+
+import java.util.Iterator;
+
+import org.eclipse.ui.regex.event.ListenerManager;
+
+public class RegExListenerManager extends ListenerManager {
+
+ public void publishExpressionError(String errMsg) {
+ for (Iterator i = getListeners().iterator(); i.hasNext();) {
+ IRegExListener listener = (IRegExListener) i.next();
+ listener.expressionError(errMsg);
+ }
+ }
+
+ public void publishFoundMatches(Matches foundMatches) {
+ for (Iterator i = getListeners().iterator(); i.hasNext(); ) {
+ IRegExListener listener = (IRegExListener) i.next();
+ listener.foundMatches(foundMatches);
+ }
+ }
+
+ public void publishFoundNoMatches() {
+ for (Iterator i = getListeners().iterator(); i.hasNext(); ) {
+ IRegExListener listener = (IRegExListener) i.next();
+ listener.foundNoMatches();
+ }
+ }
+
+ public void publishDoneWithReplace(ReplaceResult result) {
+ for (Iterator i = getListeners().iterator(); i.hasNext(); ) {
+ IRegExListener listener = (IRegExListener) i.next();
+ listener.doneWithReplace(result);
+ }
+ }
+
+ public void publishDoneWithSplit(String[] result) {
+ for (Iterator i = getListeners().iterator(); i.hasNext(); ) {
+ IRegExListener listener = (IRegExListener) i.next();
+ listener.doneWithSplit(result);
+ }
+ }
+
+ public void updateRequested() {
+ for (Iterator i = getListeners().iterator(); i.hasNext(); ) {
+ IRegExListener listener = (IRegExListener) i.next();
+ listener.updateRequested();
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/RegExModel.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/RegExModel.java
new file mode 100644
index 0000000..6410420
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/RegExModel.java
@@ -0,0 +1,287 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+public class RegExModel {
+
+ private static RegExModel _instance;
+
+ public final static int MODE_FIND = 0;
+
+ public final static int MODE_MATCH = 1;
+
+ public final static int MODE_SPLIT = 2;
+
+ public final static int MODE_REPLACE = 3;
+
+ private int patternFlags;
+
+ private Matches matches;
+
+ private boolean foundMatches;
+
+ private int matchMode;
+
+ private String replace;
+
+ private String _regExp;
+
+ private String _searchText;
+
+ private RegExListenerManager regExListenerManager;
+
+ private String description;
+
+ private RegExModel() {
+ matches = new Matches();
+ matchMode = MODE_FIND;
+ patternFlags = 0;
+ foundMatches = false;
+ regExListenerManager = new RegExListenerManager();
+ }
+
+ public static RegExModel getInstance() {
+ if (_instance == null) {
+ _instance = new RegExModel();
+ }
+ return _instance;
+ }
+
+ public int getMatchMode() {
+ return matchMode;
+ }
+
+ public void requestUpdate() {
+ regExListenerManager.updateRequested();
+ }
+
+ public void addRegExListener(IRegExListener listener) {
+ regExListenerManager.addListener(listener);
+ }
+
+ public void removeRegExListener(IRegExListener listener) {
+ regExListenerManager.removeListener(listener);
+ }
+
+ public void process() {
+ foundMatches = false;
+ matches = new Matches();
+ if (_regExp.equals("") || _searchText.equals("")) {
+ regExListenerManager.publishFoundNoMatches();
+ return;
+ }
+ try {
+ Pattern pattern = Pattern.compile(_regExp, getPatternFlags());
+ Matcher match = pattern.matcher(_searchText);
+ switch (matchMode) {
+ case MODE_FIND: {
+ find(match);
+ break;
+ }
+ case MODE_MATCH: {
+ match(match);
+ break;
+ }
+ case MODE_REPLACE: {
+ replace(match);
+ break;
+ }
+ case MODE_SPLIT: {
+ split(match, pattern);
+ break;
+ }
+ }
+ } catch (PatternSyntaxException patternSyntaxException) {
+ regExListenerManager.publishExpressionError(patternSyntaxException.getMessage());
+ }
+ }
+
+ private void find(Matcher match) {
+ if (processMatches(match)) {
+ regExListenerManager.publishFoundMatches(matches);
+ } else {
+ regExListenerManager.publishFoundNoMatches();
+ }
+ }
+
+ private void match(Matcher match) {
+
+ if (match.matches()) {
+ foundMatches = true;
+ matches.addMatch(new Match(match.start(), match.end(), match
+ .group(0)));
+ regExListenerManager.publishFoundMatches(matches);
+ } else {
+ regExListenerManager.publishFoundNoMatches();
+ }
+
+ }
+
+ private boolean processMatches(Matcher match) {
+ while (match.find()) {
+ foundMatches = true;
+
+ Match aMatch = new Match(match.start(), match.end(), match.group(0));
+ for (int i = 0; i < match.groupCount() + 1; i++) {
+ aMatch.addGroup(new Group(i, match.group(i)));
+ }
+ matches.addMatch(aMatch);
+ }
+ return foundMatches;
+ }
+
+ private void replace(Matcher match) {
+ if (replace != null) {
+ if (processMatches(match)) {
+ String resultText = match.replaceAll(replace);
+ regExListenerManager.publishDoneWithReplace(new ReplaceResult(resultText, matches));
+ } else {
+ regExListenerManager.publishFoundNoMatches();
+ }
+ }
+ }
+
+
+ private void split(Matcher match, Pattern pattern) {
+ if (processMatches(match)) {
+ regExListenerManager.publishFoundMatches(matches);
+ regExListenerManager.publishDoneWithSplit(pattern.split(_searchText));
+ } else {
+ regExListenerManager.publishFoundNoMatches();
+ }
+ }
+
+
+ public void setMatchMode(int mode) {
+ matchMode = mode;
+ }
+
+ public void setReplace(String theReplace) {
+ replace = theReplace;
+ }
+
+ public String getReplace() {
+ return replace;
+ }
+
+ public void reset() {
+ foundMatches = false;
+ matches = new Matches();
+ _regExp = "";
+ _searchText = "";
+ }
+
+ public boolean foundMatches() {
+ return foundMatches;
+ }
+
+ public Matches getMatches() {
+ return matches;
+ }
+
+ public void addPatternFlag(int flag) {
+ patternFlags += flag;
+ }
+
+ public void removePatternFlag(int flag) {
+ patternFlags -= flag;
+ }
+
+ public void resetPatternFlag() {
+ patternFlags = 0;
+ }
+
+ public int getPatternFlags() {
+ return patternFlags;
+ }
+
+ public String getPatternFlagsAsString() {
+ if (patternFlags == 0)
+ return "";
+ StringBuffer out = new StringBuffer();
+ if ((patternFlags & Pattern.CANON_EQ) != 0)
+ out.append("Pattern.CANON_EQ+");
+ if ((patternFlags & Pattern.CASE_INSENSITIVE) != 0)
+ out.append("Pattern.CASE_INSENSITIVE+");
+ if ((patternFlags & Pattern.COMMENTS) != 0)
+ out.append("Pattern.COMMENTS+");
+ if ((patternFlags & Pattern.DOTALL) != 0)
+ out.append("Pattern.DOTALL+");
+ if ((patternFlags & Pattern.MULTILINE) != 0)
+ out.append("Pattern.MULTILINE+");
+ if ((patternFlags & Pattern.UNICODE_CASE) != 0)
+ out.append("Pattern.UNICODE_CASE+");
+ if ((patternFlags & Pattern.UNIX_LINES) != 0)
+ out.append("Pattern.UNIX_LINES+");
+ String outStr = out.toString();
+ return outStr.substring(0, outStr.length() - 1);
+ }
+
+ public String getRegExAsLiteral() {
+ StringBuffer out = new StringBuffer();
+ char[] chars = getRegExp().toCharArray();
+ for (int i = 0; i < chars.length; i++) {
+ if (chars[i] == '\\') {
+ out.append("\\\\");
+ } else if (chars[i] == '"') {
+ out.append("\\\"");
+ } else {
+ out.append(chars[i]);
+ }
+ }
+ return out.toString();
+ }
+
+ /**
+ * @return Returns the _regExp.
+ */
+ public String getRegExp() {
+ return _regExp;
+ }
+
+ /**
+ * @param exp The _regExp to set.
+ */
+ public void setRegExp(String exp) {
+ _regExp = exp;
+ }
+
+ /**
+ * @return Returns the _searchText.
+ */
+ public String getSearchText() {
+ return _searchText;
+ }
+
+ /**
+ * @param text The _searchText to set.
+ */
+ public void setSearchText(String text) {
+ _searchText = text;
+ }
+
+ /**
+ * @param descr
+ */
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/RegExPlugin.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/RegExPlugin.java
new file mode 100644
index 0000000..c4cbf7e
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/RegExPlugin.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+
+public class RegExPlugin extends AbstractUIPlugin {
+
+ private static RegExPlugin plugin;
+
+ //Resource bundle.
+ private ResourceBundle resourceBundle;
+
+ /**
+ * The constructor.
+ */
+ public RegExPlugin() {
+ }
+
+ /**
+ * This method is called upon plug-in activation
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ try {
+ resourceBundle = ResourceBundle.getBundle("org.eclipse.ui.regex.PluginResources");
+ } catch (MissingResourceException x) {
+ resourceBundle = null;
+ }
+ }
+
+ /**
+ * This method is called when the plug-in is stopped
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ resourceBundle = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance.
+ */
+ public static RegExPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Returns the string from the plugin's resource bundle,
+ * or 'key' if not found.
+ */
+ public static String getResourceString(String key) {
+ ResourceBundle bundle = RegExPlugin.getDefault().getResourceBundle();
+ try {
+ return (bundle != null) ? bundle.getString(key) : key;
+ } catch (MissingResourceException e) {
+ return key;
+ }
+ }
+
+ /**
+ * Returns the plugin's resource bundle,
+ */
+ public ResourceBundle getResourceBundle() {
+ return resourceBundle;
+ }
+
+
+
+ protected void initializeDefaultPluginPreferences() {
+ getPreferenceStore().setDefault("Pattern.CANON_EQ",false);
+ getPreferenceStore().setDefault("Pattern.CASE_INSENSITIVE",false);
+ getPreferenceStore().setDefault("Pattern.COMMENTS",false);
+ getPreferenceStore().setDefault("Pattern.DOTALL",false);
+ getPreferenceStore().setDefault("Pattern.MULTILINE",false);
+ getPreferenceStore().setDefault("Pattern.UNICODE_CASE",false);
+ getPreferenceStore().setDefault("Pattern.UNIX_LINES",false);
+ getPreferenceStore().setDefault("EvalRegEx",false);
+ getPreferenceStore().setDefault("EvalSearch",false);
+ getPreferenceStore().setDefault("EvalBoth",true);
+ getPreferenceStore().setDefault("EvalSwitch",false);
+
+ FontData systemFont = Display.getCurrent().getSystemFont().getFontData()[0];
+
+ getPreferenceStore().setDefault("font.regex.name", systemFont.getName());
+ getPreferenceStore().setDefault("font.regex.height", systemFont.getHeight());
+ getPreferenceStore().setDefault("font.regex.style", systemFont.getStyle());
+ getPreferenceStore().setDefault("font.searchtext.name", systemFont.getName());
+ getPreferenceStore().setDefault("font.searchtext.height", systemFont.getHeight());
+ getPreferenceStore().setDefault("font.searchtext.style", systemFont.getStyle());
+ getPreferenceStore().setDefault("font.result.name", systemFont.getName());
+ getPreferenceStore().setDefault("font.result.height", systemFont.getHeight());
+ getPreferenceStore().setDefault("font.result.style", systemFont.getStyle());
+ }
+
+
+ public ImageDescriptor getImageDescriptor(String imageName) {
+ return imageDescriptorFromPlugin("org.eclipse.ui.regex", "icons/" + imageName);
+ }
+
+
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/ReplaceResult.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/ReplaceResult.java
new file mode 100644
index 0000000..20fb1dc
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/ReplaceResult.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex;
+
+
+public class ReplaceResult {
+
+ private Matches matches;
+ private String resultText;
+
+ public ReplaceResult(String resultText, Matches matches) {
+ this.resultText = resultText;
+ this.matches = matches;
+
+ }
+
+ /**
+ * @return Returns the afterReplace.
+ */
+ public String getResultText() {
+ return resultText;
+ }
+
+ /**
+ * @return Returns the matches.
+ */
+ public Matches getMatches() {
+ return matches;
+ }
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/event/IListener.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/event/IListener.java
new file mode 100644
index 0000000..7e22589
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/event/IListener.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.ui.regex.event;
+
+public interface IListener {
+
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/event/ListenerManager.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/event/ListenerManager.java
new file mode 100644
index 0000000..5a17976
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/event/ListenerManager.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.ui.regex.event;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public abstract class ListenerManager {
+
+ private List listeners = new ArrayList();
+
+ public void addListener(IListener listener) {
+ listeners.add(listener);
+ }
+
+ public void removeListener(IListener listener) {
+ listeners.remove(listener);
+ }
+
+ protected List getListeners() {
+ return listeners;
+ }
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/AssistKeyAdapter.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/AssistKeyAdapter.java
new file mode 100644
index 0000000..475654c
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/AssistKeyAdapter.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex.view;
+
+import java.util.ArrayList;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+
+
+public class AssistKeyAdapter extends KeyAdapter {
+
+ private StyledText textField;
+
+ public void keyPressed(KeyEvent e) {
+ textField = (StyledText) e.widget;
+ int caretOffset = textField.getCaretOffset();
+
+ if (textField.getText().equals("") || caretOffset == 0) return;
+
+ String textSoFar = textField.getText(0, caretOffset - 1);
+
+ ArrayList proposals = Assistant.getAssistItems(textSoFar);
+
+ if (proposals.size() != 0 && e.stateMask == SWT.CONTROL && e.keyCode == 32) {
+ Proposal proposal = showProposals(proposals);
+
+ if (proposal != null) {
+
+ textField.replaceTextRange(caretOffset
+ - proposal.getReplaceCount(), proposal
+ .getReplaceCount(), proposal
+ .getSubstitute());
+ textField.setCaretOffset(caretOffset
+ + proposal.getSubstitute().length() - proposal.getReplaceCount());
+ } else {
+ textField.setCaretOffset(caretOffset);
+ }
+
+
+ }
+ }
+
+ protected Proposal showProposals(ArrayList proposals) {
+ AssistPopup assist = new AssistPopup(textField.getShell());
+ assist.setProposals(proposals);
+ Point pos = textField.toDisplay(textField.getCaret()
+ .getLocation());
+ return assist.open(new Rectangle(
+ pos.x + 10, pos.y - 90, 140, 120));
+
+ }
+
+
+
+
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/AssistPopup.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/AssistPopup.java
new file mode 100644
index 0000000..82bec58
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/AssistPopup.java
@@ -0,0 +1,182 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex.view;
+
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+
+
+public class AssistPopup {
+ private Shell shell;
+ private List list;
+ private int minimumWidth;
+ private ArrayList proposals;
+ private static final Color bgColor = new Color(Display.getCurrent(), 254, 241, 233);
+
+public AssistPopup(Shell parent) {
+ this(parent, 0);
+}
+
+
+public AssistPopup(Shell parent, int style) {
+ shell = new Shell(parent, checkStyle(style));
+
+ list = new List(shell, SWT.SINGLE | SWT.V_SCROLL);
+ list.setBackground(bgColor);
+
+ // close dialog if user selects outside of the shell
+ shell.addListener(SWT.Deactivate, new Listener() {
+ public void handleEvent(Event e){
+ shell.setVisible (false);
+ }
+ });
+
+ // resize shell when list resizes
+ shell.addControlListener(new ControlListener() {
+ public void controlMoved(ControlEvent e){}
+ public void controlResized(ControlEvent e){
+ Rectangle shellSize = shell.getClientArea();
+ list.setSize(shellSize.width, shellSize.height);
+ }
+ });
+
+ // return list selection on Mouse Up or Carriage Return
+ list.addMouseListener(new MouseListener() {
+ public void mouseDoubleClick(MouseEvent e){}
+ public void mouseDown(MouseEvent e){}
+ public void mouseUp(MouseEvent e){
+ shell.setVisible (false);
+ }
+ });
+ list.addKeyListener(new KeyListener() {
+ public void keyReleased(KeyEvent e){}
+ public void keyPressed(KeyEvent e){
+ if (e.character == '\r'){
+ shell.setVisible (false);
+ }
+ }
+ });
+
+}
+private static int checkStyle (int style) {
+ int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+ return style & mask;
+}
+
+
+public Proposal open (Rectangle rect) {
+
+ Point listSize = list.computeSize (rect.width, SWT.DEFAULT);
+ Rectangle screenSize = shell.getDisplay().getBounds();
+
+ // Position the dialog so that it does not run off the screen and the largest number of items are visible
+ int spaceBelow = screenSize.height - (rect.y + rect.height) - 30;
+ int spaceAbove = rect.y - 30;
+
+ int y = 0;
+ if (spaceAbove > spaceBelow && listSize.y > spaceBelow) {
+ // place popup list above table cell
+ if (listSize.y > spaceAbove){
+ listSize.y = spaceAbove;
+ } else {
+ listSize.y += 2;
+ }
+ y = rect.y - listSize.y;
+
+ } else {
+ // place popup list below table cell
+ if (listSize.y > spaceBelow){
+ listSize.y = spaceBelow;
+ } else {
+ listSize.y += 2;
+ }
+ y = rect.y + rect.height;
+ }
+
+ // Make dialog as wide as the cell
+ listSize.x = rect.width;
+ // dialog width should not be les than minimumwidth
+ if (listSize.x < minimumWidth)
+ listSize.x = minimumWidth;
+
+ // Align right side of dialog with right side of cell
+ int x = rect.x + rect.width - listSize.x;
+
+ shell.setBounds(x, y, listSize.x, listSize.y);
+
+ shell.open();
+ list.setFocus();
+
+ Display display = shell.getDisplay();
+ while (!shell.isDisposed () && shell.isVisible ()) {
+ if (!display.readAndDispatch()) display.sleep();
+ }
+
+ Proposal result = null;
+ if (!shell.isDisposed ()) {
+ if (list.getSelectionIndex() != -1) {
+ result = (Proposal) proposals.get(list.getSelectionIndex());
+ }
+ shell.dispose();
+ }
+ return result;
+}
+
+
+public void select(String string) {
+ String[] items = list.getItems();
+
+ // find the first entry in the list that starts with the
+ // specified string
+ if (string != null){
+ for (int i = 0; i < items.length; i++) {
+ if (items[i].startsWith(string)){
+ int index = list.indexOf(items[i]);
+ list.select(index);
+ break;
+ }
+ }
+ }
+}
+
+public void setProposals(ArrayList proposals) {
+ this.proposals = proposals;
+ int c = 0;
+ String[] items = new String[proposals.size()];
+ for (Iterator i = proposals.iterator(); i.hasNext(); ) {
+ Proposal proposal = (Proposal) i.next();
+ items[c++] = proposal.getDescription();
+ }
+ list.setItems(items);
+}
+
+
+}
+
+
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/Assistant.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/Assistant.java
new file mode 100644
index 0000000..05c556c
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/Assistant.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex.view;
+
+import java.util.ArrayList;
+
+
+public class Assistant {
+
+
+ public static ArrayList getAssistItems(String textLeftOfCursor) {
+ ArrayList proposals = new ArrayList();
+ if (textLeftOfCursor.endsWith("\\")) {
+ proposals.add(new Proposal("\\A", "Beginning input \\A", 1));
+ proposals.add(new Proposal("\\b", "Word boundary \\b", 1));
+ proposals.add(new Proposal("\\B", "Non-word boundary \\B", 1));
+ proposals.add(new Proposal("\\d", "Digit \\d", 1));
+ proposals.add(new Proposal("\\D", "Non-digit \\D", 1));
+ proposals
+ .add(new Proposal("\\G", "End of previous match \\G", 1));
+ proposals.add(new Proposal("\\n", "Newline \\n", 1));
+ proposals.add(new Proposal("\\r", "Carriage-return \\r", 1));
+ proposals.add(new Proposal("\\s", "Whitespace \\s", 1));
+ proposals.add(new Proposal("\\S", "Non-whitespace \\S", 1));
+ proposals.add(new Proposal("\\t", "Tab \\t", 1));
+ proposals.add(new Proposal("\\w", "Word \\w", 1));
+ proposals.add(new Proposal("\\W", "Non-word \\W", 1));
+ proposals.add(new Proposal("\\z", "End of input \\z", 1));
+
+ }
+
+ if (textLeftOfCursor.endsWith("(?")) {
+ proposals.add(new Proposal("(?:", "Non-capturing group (?:", 2));
+ proposals.add(new Proposal("(?=", "Positive lookahead (?=", 2));
+ proposals.add(new Proposal("(?!", "Negative lookahead (?!", 2));
+ proposals
+ .add(new Proposal("(?<=", "Positive lookbehind (?<=", 2));
+ proposals
+ .add(new Proposal("(?<!", "Negative lookbehind (?<!", 2));
+
+ }
+
+ if (textLeftOfCursor.endsWith("[")) {
+ proposals.add(new Proposal("[0-9]", "[0-9]", 1));
+ proposals.add(new Proposal("[a-z]", "[a-z]", 1));
+ proposals.add(new Proposal("[A-Z]", "[A-Z]", 1));
+ proposals.add(new Proposal("[a-zA-Z]", "[a-zA-Z]", 1));
+ proposals.add(new Proposal("[a-zA-Z0-9]", "[a-zA-Z0-9]", 1));
+ }
+
+ return proposals;
+ }
+
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/BracketMatchingKeyAdapter.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/BracketMatchingKeyAdapter.java
new file mode 100644
index 0000000..b7e24aa
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/BracketMatchingKeyAdapter.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex.view;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.widgets.Display;
+
+public class BracketMatchingKeyAdapter extends KeyAdapter {
+
+ public void keyPressed(KeyEvent e) {
+ StyledText txt_RegExp = (StyledText) e.widget;
+ txt_RegExp.setStyleRange(null);
+
+ if (matchableBracket(e.character)) {
+
+ markMatchingBracket(txt_RegExp, e.character);
+
+ } else {
+
+ final int KEY_LEFT_ARROW = 16777219;
+ final int KEY_RIGHT_ARROW = 16777220;
+
+ if (e.keyCode == KEY_LEFT_ARROW || e.keyCode == KEY_RIGHT_ARROW) {
+
+ int caretOffset = txt_RegExp.getCaretOffset();
+ String lastText = " ";
+ if (caretOffset - 1 >= 0) {
+ lastText = txt_RegExp.getText(caretOffset - 1, caretOffset - 1);
+ }
+
+ if (matchableBracket(lastText.charAt(0))) {
+ markMatchingBracket(txt_RegExp, lastText.charAt(0));
+ }
+
+ }
+
+ }
+
+ }
+
+ protected void markMatchingBracket(StyledText txt_RegExp, char bracket) {
+ int caretOffset = txt_RegExp.getCaretOffset();
+ int brakePos = -1;
+ int ignoreInnerBracket = 0;
+
+ if (isClosingBracket(bracket)) {
+ String text = txt_RegExp.getText(0, caretOffset - 1);
+ for (int i = text.length() - 2; i >= 0; i--) {
+ if (text.charAt(i) == bracket) {
+ ignoreInnerBracket++;
+ }
+ if (text.charAt(i) == getMatchingBracket(bracket)) {
+ if (ignoreInnerBracket == 0) {
+ brakePos = i;
+ break;
+ } else {
+ ignoreInnerBracket--;
+ }
+ }
+ }
+ }
+
+ if (isOpeningBracket(bracket)) {
+ if (caretOffset != txt_RegExp.getText().length()) {
+ String text = txt_RegExp.getText(caretOffset, txt_RegExp.getText().length() - 1);
+ for (int i = 0; i < text.length(); i++) {
+ if (text.charAt(i) == bracket) {
+ ignoreInnerBracket++;
+ }
+ if (text.charAt(i) == getMatchingBracket(bracket)) {
+ if (ignoreInnerBracket == 0) {
+ brakePos = caretOffset + i;
+ break;
+ } else {
+ ignoreInnerBracket--;
+ }
+ }
+ }
+ }
+ }
+
+ if (brakePos != -1) {
+ StyleRange styleRange1 = new StyleRange(brakePos, 1, Display
+ .getCurrent().getSystemColor(SWT.COLOR_RED), Display
+ .getCurrent().getSystemColor(SWT.COLOR_WHITE), SWT.BOLD);
+ StyleRange styleRange2 = new StyleRange(caretOffset - 1, 1, Display
+ .getCurrent().getSystemColor(SWT.COLOR_RED), Display
+ .getCurrent().getSystemColor(SWT.COLOR_WHITE), SWT.BOLD);
+
+ if (isOpeningBracket(bracket)) {
+ txt_RegExp
+ .setStyleRanges(new StyleRange[]{styleRange2, styleRange1});
+ }
+ if (isClosingBracket(bracket)) {
+ txt_RegExp
+ .setStyleRanges(new StyleRange[]{styleRange1, styleRange2});
+ }
+ }
+ }
+
+ protected boolean matchableBracket(char bracket) {
+ if (bracket == ')' || bracket == ']' || bracket == '(' || bracket == '[' || bracket == '}' || bracket == '{') {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ protected char getMatchingBracket(char bracket) {
+ if (bracket == ')') return '(';
+ if (bracket == '(') return ')';
+ if (bracket == ']') return '[';
+ if (bracket == '[') return ']';
+ if (bracket == '}') return '{';
+ if (bracket == '{') return '}';
+ return ' ';
+ }
+
+ protected boolean isOpeningBracket(char bracket) {
+ if (bracket == '(') return true;
+ if (bracket == '[') return true;
+ if (bracket == '{') return true;
+ return false;
+ }
+
+ protected boolean isClosingBracket(char bracket) {
+ if (bracket == ')') return true;
+ if (bracket == ']') return true;
+ if (bracket == '}') return true;
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/CopyDeclarationAdapter.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/CopyDeclarationAdapter.java
new file mode 100644
index 0000000..46697ca
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/CopyDeclarationAdapter.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex.view;
+
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.ui.regex.RegExModel;
+
+
+public class CopyDeclarationAdapter extends SelectionAdapter {
+
+ public void widgetSelected(SelectionEvent e) {
+ String text = "Pattern.compile(\"" + RegExModel.getInstance().getRegExAsLiteral();
+ if (RegExModel.getInstance().getPatternFlags() == 0)
+ text += "\");";
+ else
+ text += "\"," + RegExModel.getInstance().getPatternFlagsAsString() + ");";
+ Clipboard clipboard = new Clipboard(e.display);
+ TextTransfer textTransfer = TextTransfer.getInstance();
+ clipboard.setContents(new Object[]{text},
+ new Transfer[]{textTransfer});
+ clipboard.dispose();
+
+ }
+
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/Expression.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/Expression.java
new file mode 100644
index 0000000..171ecc6
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/Expression.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex.view;
+
+
+public class Expression {
+
+ private String regex = "";
+
+ private String searchText = "";
+
+ private String name = "";
+
+ private int matchMode = 0;
+
+ private int patternFlag = 0;
+
+
+ public Expression(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @param name The name to set.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ int hash = 7;
+ hash = 31 * hash + (null == name ? 0 : name.hashCode());
+ return hash;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object o) {
+ if (o == this) return true;
+ if (o == null) return false;
+ if (! (o instanceof Expression)) return false;
+ Expression state = (Expression) o;
+ if (name.equals(state.getName())) {
+ return true;
+ }
+ return false;
+ }
+
+ public String toString() {
+ return name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getMatchMode() {
+ return matchMode;
+ }
+
+ public void setMatchMode(int matchMode) {
+ this.matchMode = matchMode;
+ }
+
+ public int getPatternFlag() {
+ return patternFlag;
+ }
+
+ public void setPatternFlag(int patternFlag) {
+ this.patternFlag = patternFlag;
+ }
+
+ public String getRegex() {
+ return regex;
+ }
+
+ public void setRegex(String regex) {
+ this.regex = regex;
+ }
+
+ public String getSearchText() {
+ return searchText;
+ }
+
+ public void setSearchText(String searchText) {
+ this.searchText = searchText;
+ }
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/ExpressionLoader.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/ExpressionLoader.java
new file mode 100644
index 0000000..22e4f74
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/ExpressionLoader.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex.view;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class ExpressionLoader {
+
+ private List listener = new ArrayList();
+
+ private static ExpressionLoader instance;
+
+ public static ExpressionLoader getInstance() {
+ if (instance == null) {
+ instance = new ExpressionLoader();
+ }
+ return instance;
+ }
+
+ private ExpressionLoader() {}
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.regex.view.IExpressionLoader#addExpressionLoaderListener(org.eclipse.ui.regex.view.IExpressionLoaderListener)
+ */
+ public void addExpressionLoaderListener(IExpressionLoaderListener loaderListener) {
+ listener.add(loaderListener);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.regex.view.IExpressionLoader#removeExpressionLoaderListener(org.eclipse.ui.regex.view.IExpressionLoaderListener)
+ */
+ public void removeExpressionLoaderListener(IExpressionLoaderListener loaderListener) {
+ listener.remove(loaderListener);
+ }
+
+
+ public void fireLoadExpression(Expression expression) {
+ for (Iterator i = listener.iterator(); i.hasNext();) {
+ IExpressionLoaderListener l = (IExpressionLoaderListener) i.next();
+ l.loadExpression(expression);
+ }
+ }
+
+
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/FontPreferencePage.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/FontPreferencePage.java
new file mode 100644
index 0000000..19daffb
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/FontPreferencePage.java
@@ -0,0 +1,227 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex.view;
+
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FontDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.regex.RegExPlugin;
+
+
+public class FontPreferencePage extends PreferencePage implements IWorkbenchPreferencePage, SelectionListener {
+
+ private Button regexFontButton;
+ private Text regexFontText;
+ private FontData regexFontData;
+ private Text searchTextFontText;
+ private Button searchTextFontButton;
+ private Text resultFontText;
+ private Button resultFontButton;
+ private FontData searchTextFontData;
+ private FontData resultFontData;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
+ */
+ protected void performDefaults() {
+ String fontName = getPreferenceStore().getDefaultString("font.regex.name");
+ int fontHeight = getPreferenceStore().getDefaultInt("font.regex.height");
+ int fontStyle = getPreferenceStore().getDefaultInt("font.regex.style");
+ regexFontData = new FontData(fontName, fontHeight, fontStyle);
+ regexFontText.setText(buildDescription(fontName, fontHeight));
+ }
+
+ private void setFontData() {
+ if (regexFontData != null) {
+ getPreferenceStore().setValue("font.regex.name", regexFontData.getName());
+ getPreferenceStore().setValue("font.regex.height", regexFontData.getHeight());
+ getPreferenceStore().setValue("font.regex.style", regexFontData.getStyle());
+ }
+ if (searchTextFontData != null) {
+ getPreferenceStore().setValue("font.searchtext.name", searchTextFontData.getName());
+ getPreferenceStore().setValue("font.searchtext.height", searchTextFontData.getHeight());
+ getPreferenceStore().setValue("font.searchtext.style", searchTextFontData.getStyle());
+ }
+ if (resultFontData != null) {
+ getPreferenceStore().setValue("font.result.name", resultFontData.getName());
+ getPreferenceStore().setValue("font.result.height", resultFontData.getHeight());
+ getPreferenceStore().setValue("font.result.style", resultFontData.getStyle());
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.preference.PreferencePage#performApply()
+ */
+ protected void performApply() {
+ setFontData();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.preference.IPreferencePage#performOk()
+ */
+ public boolean performOk() {
+ setFontData();
+ RegExPlugin.getDefault().savePluginPreferences();
+ return true;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
+ */
+ protected Control createContents(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NONE);
+
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 2;
+ composite.setLayout(gridLayout);
+ composite.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_BOTH));
+
+ Label regexFontLabel = new Label(composite, SWT.NONE);
+ regexFontLabel.setText("Regular Expression Font:");
+ GridData gridData = new GridData();
+ gridData.horizontalSpan = 2;
+ regexFontLabel.setLayoutData(gridData);
+
+ regexFontText = new Text(composite, SWT.BORDER);
+ regexFontText.setText(buildDescription(fontName("regex"), fontHeight("regex")));
+ regexFontText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ regexFontText.setFont(createFont("regex"));
+
+ regexFontButton = new Button(composite, SWT.PUSH);
+ regexFontButton.setText("Change...");
+ regexFontButton.addSelectionListener(this);
+ regexFontButton.setData("regex");
+ regexFontButton.setLayoutData(new GridData());
+
+ Label searchTextFontLabel = new Label(composite, SWT.NONE);
+ searchTextFontLabel.setText("Search Text Font:");
+ gridData = new GridData();
+ gridData.horizontalSpan = 2;
+ searchTextFontLabel.setLayoutData(gridData);
+
+ searchTextFontText = new Text(composite, SWT.BORDER);
+ searchTextFontText.setText(buildDescription(fontName("searchtext"), fontHeight("searchtext")));
+ searchTextFontText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ searchTextFontText.setFont(createFont("searchtext"));
+
+ searchTextFontButton = new Button(composite, SWT.PUSH);
+ searchTextFontButton.setText("Change...");
+ searchTextFontButton.addSelectionListener(this);
+ searchTextFontButton.setData("searchtext");
+ searchTextFontButton.setLayoutData(new GridData());
+
+ Label resultFontLabel = new Label(composite, SWT.NONE);
+ resultFontLabel.setText("Result Font:");
+ gridData = new GridData();
+ gridData.horizontalSpan = 2;
+ resultFontLabel.setLayoutData(gridData);
+
+ resultFontText = new Text(composite, SWT.BORDER);
+ resultFontText.setText(buildDescription(fontName("result"), fontHeight("result")));
+ resultFontText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ resultFontText.setFont(createFont("result"));
+
+ resultFontButton = new Button(composite, SWT.PUSH);
+ resultFontButton.setText("Change...");
+ resultFontButton.addSelectionListener(this);
+ resultFontButton.setData("result");
+ resultFontButton.setLayoutData(new GridData());
+
+ return parent;
+ }
+
+ private String fontName(String type) {
+ return getPreferenceStore().getString("font." + type + ".name");
+ }
+
+ private int fontHeight(String type) {
+ return getPreferenceStore().getInt("font." + type + ".height");
+ }
+
+ private int fontStyle(String type) {
+ return getPreferenceStore().getInt("font." + type + ".style");
+ }
+
+ private FontData fontData(String type) {
+ return new FontData(fontName(type), fontHeight(type), fontStyle(type));
+ }
+
+ private Font createFont(String type) {
+ return new Font(Display.getCurrent(), fontData(type));
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+ */
+ public void init(IWorkbench workbench) {
+ this.setPreferenceStore(RegExPlugin.getDefault().getPreferenceStore());
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ if (e.widget == regexFontButton || e.widget == searchTextFontButton || e.widget == resultFontButton) {
+ FontDialog fontDialog = new FontDialog(getShell());
+ fontDialog.setFontList(new FontData[]{fontData((String) ((Button) e.widget).getData())});
+ FontData fontData = fontDialog.open();
+ if (fontData != null) {
+ if (e.widget == regexFontButton) {
+ regexFontData = fontData;
+ regexFontText.setText(fontData.getName() + ", " + fontData.getHeight());
+ regexFontText.setFont(new Font(Display.getCurrent(), fontData));
+ }
+ if (e.widget == searchTextFontButton) {
+ searchTextFontData = fontData;
+ searchTextFontText.setText(fontData.getName() + ", " + fontData.getHeight());
+ searchTextFontText.setFont(new Font(Display.getCurrent(), fontData));
+ }
+ if (e.widget == resultFontButton) {
+ resultFontData = fontData;
+ resultFontText.setText(fontData.getName() + ", " + fontData.getHeight());
+ resultFontText.setFont(new Font(Display.getCurrent(), fontData));
+ }
+ }
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // TODO Auto-generated method stub
+
+ }
+
+ private String buildDescription(String fontName, int fontHeight) {
+ return fontName + ", " + fontHeight;
+ }
+
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/IExpressionLoaderListener.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/IExpressionLoaderListener.java
new file mode 100644
index 0000000..e7551e2
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/IExpressionLoaderListener.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex.view;
+
+
+public interface IExpressionLoaderListener {
+
+ public void loadExpression(Expression expression);
+
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/ILiveEvalListener.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/ILiveEvalListener.java
new file mode 100644
index 0000000..447d203
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/ILiveEvalListener.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.ui.regex.view;
+
+import org.eclipse.ui.regex.event.IListener;
+
+
+public interface ILiveEvalListener extends IListener {
+
+ public void evalActivated();
+ public void evalDeactivated();
+ public void evalDone();
+ public void doEval();
+
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/LiveEval.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/LiveEval.java
new file mode 100644
index 0000000..dfbbc51
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/LiveEval.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex.view;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.custom.ExtendedModifyEvent;
+import org.eclipse.swt.custom.ExtendedModifyListener;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.ui.regex.RegExPlugin;
+
+public class LiveEval {
+
+ private LiveEvalListenerManager liveEvalListenerManager;
+
+ class LiveEvalListener implements ExtendedModifyListener {
+
+ public void modifyText(ExtendedModifyEvent event) {
+ if (LiveEval.this.isLiveEval()) LiveEval.this.doEval();
+ }
+ }
+
+
+ private boolean isLiveEval;
+
+ private LiveEvalListener liveEvalListener;
+
+ private StyledText regEx, searchText;
+
+ private IPreferenceStore prefs = RegExPlugin.getDefault()
+ .getPreferenceStore();
+
+
+ public LiveEval(StyledText regEx, StyledText searchText) {
+ liveEvalListener = new LiveEvalListener();
+ this.regEx = regEx;
+ this.searchText = searchText;
+ isLiveEval = prefs.getBoolean("EvalSwitch");
+
+ prefs.addPropertyChangeListener(new IPropertyChangeListener() {
+
+ public void propertyChange(PropertyChangeEvent event) {
+ if (LiveEval.this.regEx.isDisposed()
+ || LiveEval.this.searchText.isDisposed()) { return; }
+ String prop = event.getProperty();
+
+ if (prop.equals("EvalSwitch")) {
+ boolean newVal = ((Boolean) event.getNewValue())
+ .booleanValue();
+ if (newVal)
+ LiveEval.this.start();
+ else
+ LiveEval.this.stop();
+ }
+ if (LiveEval.this.isLiveEval()) updateChangeListeners();
+ }
+ });
+ liveEvalListenerManager = new LiveEvalListenerManager();
+ }
+
+ public void addLiveEvalListener(ILiveEvalListener listener) {
+ liveEvalListenerManager.addListener(listener);
+ }
+
+ public void removeLiveEvalListener(ILiveEvalListener listener) {
+ liveEvalListenerManager.removeListener(listener);
+ }
+
+ public boolean isLiveEval() {
+ return this.isLiveEval;
+ }
+
+ public void start() {
+ this.isLiveEval = true;
+ updateChangeListeners();
+ liveEvalListenerManager.publishEvalActivated();
+ }
+
+ public void stop() {
+ this.isLiveEval = false;
+ removeChangeListeners();
+ liveEvalListenerManager.publishEvalDeactivated();
+ }
+
+
+
+ private void doEval() {
+ liveEvalListenerManager.publishDoEval();
+ liveEvalListenerManager.publishEvalDone();
+ }
+
+ private void removeChangeListeners() {
+ regEx.removeExtendedModifyListener(liveEvalListener);
+ searchText.removeExtendedModifyListener(liveEvalListener);
+
+ }
+
+ private void updateChangeListeners() {
+ removeChangeListeners();
+ if (prefs.getBoolean("EvalSearch")) {
+ searchText.addExtendedModifyListener(liveEvalListener);
+ }
+ if (prefs.getBoolean("EvalRegEx")) {
+ regEx.addExtendedModifyListener(liveEvalListener);
+ }
+ if (prefs.getBoolean("EvalBoth")) {
+ searchText.addExtendedModifyListener(liveEvalListener);
+ regEx.addExtendedModifyListener(liveEvalListener);
+ }
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/LiveEvalListenerManager.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/LiveEvalListenerManager.java
new file mode 100644
index 0000000..6c52311
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/LiveEvalListenerManager.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex.view;
+
+import java.util.Iterator;
+
+import org.eclipse.ui.regex.event.ListenerManager;
+
+
+public class LiveEvalListenerManager extends ListenerManager {
+
+ public void publishEvalActivated() {
+ for (Iterator i = getListeners().iterator(); i.hasNext(); ) {
+ ILiveEvalListener listener = (ILiveEvalListener) i.next();
+ listener.evalActivated();
+ }
+ };
+
+ public void publishEvalDeactivated() {
+ for (Iterator i = getListeners().iterator(); i.hasNext(); ) {
+ ILiveEvalListener listener = (ILiveEvalListener) i.next();
+ listener.evalDeactivated();
+ }
+ };
+
+ public void publishEvalDone() {
+ for (Iterator i = getListeners().iterator(); i.hasNext(); ) {
+ ILiveEvalListener listener = (ILiveEvalListener) i.next();
+ listener.evalDone();
+ }
+ };
+
+ public void publishDoEval() {
+ for (Iterator i = getListeners().iterator(); i.hasNext(); ) {
+ ILiveEvalListener listener = (ILiveEvalListener) i.next();
+ listener.doEval();
+ }
+ };
+
+
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/Proposal.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/Proposal.java
new file mode 100644
index 0000000..36a2cc3
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/Proposal.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex.view;
+
+public class Proposal {
+
+ private String substitute;
+ private String description;
+ private int replaceCount;
+
+ /**
+ * @param substitute
+ * @param description
+ */
+ public Proposal(String substitute, String description, int replaceCount) {
+ super();
+ this.substitute = substitute;
+ this.description = description;
+ this.replaceCount = replaceCount;
+ }
+
+
+
+ /**
+ * @return Returns the replaceCount.
+ */
+ public int getReplaceCount() {
+ return replaceCount;
+ }
+ /**
+ * @param replaceCount The replaceCount to set.
+ */
+ public void setReplaceCount(int replaceCount) {
+ this.replaceCount = replaceCount;
+ }
+ /**
+ * @return Returns the description.
+ */
+ public String getDescription() {
+ return description;
+ }
+ /**
+ * @param description The description to set.
+ */
+ public void setDescription(String description) {
+ this.description = description;
+ }
+ /**
+ * @return Returns the substitute.
+ */
+ public String getSubstitute() {
+ return substitute;
+ }
+ /**
+ * @param substitute The substitute to set.
+ */
+ public void setSubstitute(String substitute) {
+ this.substitute = substitute;
+ }
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/RegExPreferencePage.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/RegExPreferencePage.java
new file mode 100644
index 0000000..6f34bc9
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/RegExPreferencePage.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex.view;
+
+import java.util.regex.Pattern;
+
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.regex.RegExPlugin;
+
+
+public class RegExPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+
+ private Button btn_CanonicalEquivalence;
+ private Button btn_CaseInsensitive;
+ private Button btn_Comments;
+ private Button btn_DotallMode;
+ private Button btn_MultilineMode;
+ private Button btn_UnicodeCase;
+ private Button btn_UnixLines;
+ private Button btn_EvalRegEx;
+ private Button btn_EvalSearch;
+ private Button btn_EvalBoth;
+ private Button btn_EvalSwitch;
+
+ public RegExPreferencePage() {
+ }
+
+
+ public void init(IWorkbench workbench) {
+ this.setPreferenceStore(RegExPlugin.getDefault().getPreferenceStore());
+ }
+
+ protected void performDefaults() {
+ btn_CanonicalEquivalence.setSelection(getPreferenceStore().getDefaultBoolean("Pattern.CANON_EQ"));
+ btn_CaseInsensitive.setSelection(getPreferenceStore().getDefaultBoolean("Pattern.CASE_INSENSITIVE"));
+ btn_Comments.setSelection(getPreferenceStore().getDefaultBoolean("Pattern.COMMENTS"));
+ btn_DotallMode.setSelection(getPreferenceStore().getDefaultBoolean("Pattern.DOTALL"));
+ btn_MultilineMode.setSelection(getPreferenceStore().getDefaultBoolean("Pattern.MULTILINE"));
+ btn_UnicodeCase.setSelection(getPreferenceStore().getDefaultBoolean("Pattern.UNICODE_CASE"));
+ btn_UnixLines.setSelection(getPreferenceStore().getDefaultBoolean("Pattern.UNIX_LINES"));
+ btn_EvalRegEx.setSelection(getPreferenceStore().getDefaultBoolean("EvalRegEx"));
+ btn_EvalSearch.setSelection(getPreferenceStore().getDefaultBoolean("EvalSearch"));
+ btn_EvalBoth.setSelection(getPreferenceStore().getDefaultBoolean("EvalBoth"));
+ btn_EvalSwitch.setSelection(getPreferenceStore().getDefaultBoolean("EvalSwitch"));
+ }
+
+ public boolean performOk() {
+ getPreferenceStore().setValue("Pattern.CANON_EQ",btn_CanonicalEquivalence.getSelection());
+ getPreferenceStore().setValue("Pattern.CASE_INSENSITIVE",btn_CaseInsensitive.getSelection());
+ getPreferenceStore().setValue("Pattern.COMMENTS",btn_Comments.getSelection());
+ getPreferenceStore().setValue("Pattern.DOTALL",btn_DotallMode.getSelection());
+ getPreferenceStore().setValue("Pattern.MULTILINE",btn_MultilineMode.getSelection());
+ getPreferenceStore().setValue("Pattern.UNICODE_CASE",btn_UnicodeCase.getSelection());
+ getPreferenceStore().setValue("Pattern.UNIX_LINES",btn_UnixLines.getSelection());
+ getPreferenceStore().setValue("EvalRegEx",btn_EvalRegEx.getSelection());
+ getPreferenceStore().setValue("EvalSearch",btn_EvalSearch.getSelection());
+ getPreferenceStore().setValue("EvalBoth",btn_EvalBoth.getSelection());
+ getPreferenceStore().setValue("EvalSwitch",btn_EvalSwitch.getSelection());
+ RegExPlugin.getDefault().savePluginPreferences();
+ return true;
+ }
+
+ protected Control createContents(Composite parent) {
+
+ Group group=new Group(parent,SWT.SHADOW_ETCHED_IN);
+ group.setText("Default Pattern Flags");
+ GridLayout groupGridLayout=new GridLayout();
+ groupGridLayout.numColumns=2;
+
+ group.setLayout(groupGridLayout);
+ group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));
+
+ btn_CanonicalEquivalence=new Button(group,SWT.CHECK);
+ btn_CanonicalEquivalence.setText("Canonical &Equivalence");
+ btn_CanonicalEquivalence.setData(new Integer(Pattern.CANON_EQ));
+ btn_CanonicalEquivalence.setSelection(getPreferenceStore().getBoolean("Pattern.CANON_EQ"));
+
+ btn_CaseInsensitive=new Button(group,SWT.CHECK);
+ btn_CaseInsensitive.setText("Case &Insensitive");
+ btn_CaseInsensitive.setData(new Integer(Pattern.CASE_INSENSITIVE));
+ btn_CaseInsensitive.setSelection(getPreferenceStore().getBoolean("Pattern.CASE_INSENSITIVE"));
+
+ btn_Comments=new Button(group,SWT.CHECK);
+ btn_Comments.setText("&Comments");
+ btn_Comments.setData(new Integer(Pattern.COMMENTS));
+ btn_Comments.setSelection(getPreferenceStore().getBoolean("Pattern.COMMENTS"));
+
+ btn_DotallMode=new Button(group,SWT.CHECK);
+ btn_DotallMode.setText("&Dotall Mode");
+ btn_DotallMode.setData(new Integer(Pattern.DOTALL));
+ btn_DotallMode.setSelection(getPreferenceStore().getBoolean("Pattern.DOTALL"));
+
+ btn_MultilineMode=new Button(group,SWT.CHECK);
+ btn_MultilineMode.setText("&Multiline Mode");
+ btn_MultilineMode.setData(new Integer(Pattern.MULTILINE));
+ btn_MultilineMode.setSelection(getPreferenceStore().getBoolean("Pattern.MULTILINE"));
+
+ btn_UnicodeCase=new Button(group,SWT.CHECK);
+ btn_UnicodeCase.setText("&Unicode Case");
+ btn_UnicodeCase.setData(new Integer(Pattern.UNICODE_CASE));
+ btn_UnicodeCase.setSelection(getPreferenceStore().getBoolean("Pattern.UNICODE_CASE"));
+
+ btn_UnixLines=new Button(group,SWT.CHECK);
+ btn_UnixLines.setText("Unix &Lines");
+ btn_UnixLines.setData(new Integer(Pattern.UNIX_LINES));
+ btn_UnixLines.setSelection(getPreferenceStore().getBoolean("Pattern.UNIX_LINES"));
+
+ Group evalGroup=new Group(parent,SWT.SHADOW_ETCHED_IN);
+ evalGroup.setText("Live Evaluation");
+ GridLayout evalGridLayout=new GridLayout();
+ evalGridLayout.numColumns=1;
+ evalGroup.setLayout(evalGridLayout);
+ evalGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));
+
+ btn_EvalRegEx=new Button(evalGroup,SWT.RADIO);
+ btn_EvalRegEx.setText("React On &Regular Expression Changes");
+ btn_EvalRegEx.setSelection(getPreferenceStore().getBoolean("EvalRegEx"));
+
+ btn_EvalSearch=new Button(evalGroup,SWT.RADIO);
+ btn_EvalSearch.setText("React On &Search Text Changes");
+ btn_EvalSearch.setSelection(getPreferenceStore().getBoolean("EvalSearch"));
+
+ btn_EvalBoth=new Button(evalGroup,SWT.RADIO);
+ btn_EvalBoth.setText("&React On Everything");
+ btn_EvalBoth.setSelection(getPreferenceStore().getBoolean("EvalBoth"));
+
+ btn_EvalSwitch=new Button(evalGroup,SWT.CHECK);
+ btn_EvalSwitch.setText("Use Live &Evaluation");
+ btn_EvalSwitch.setSelection(getPreferenceStore().getBoolean("EvalSwitch"));
+
+ return null;
+ }
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/RegExView.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/RegExView.java
new file mode 100644
index 0000000..3cb84cd
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/RegExView.java
@@ -0,0 +1,864 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex.view;
+
+import java.util.Iterator;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.custom.VerifyKeyListener;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.MenuEvent;
+import org.eclipse.swt.events.MenuListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.ui.part.ViewPart;
+import org.eclipse.ui.regex.Group;
+import org.eclipse.ui.regex.IRegExListener;
+import org.eclipse.ui.regex.Match;
+import org.eclipse.ui.regex.Matches;
+import org.eclipse.ui.regex.RegExModel;
+import org.eclipse.ui.regex.RegExPlugin;
+import org.eclipse.ui.regex.ReplaceResult;
+import org.eclipse.ui.regex.view.actions.AboutAction;
+import org.eclipse.ui.regex.view.actions.ClearAction;
+import org.eclipse.ui.regex.view.actions.NextMatchAction;
+import org.eclipse.ui.regex.view.actions.PrevMatchAction;
+import org.eclipse.ui.regex.view.actions.StandardTextFieldAction;
+import org.eclipse.ui.regex.view.actions.StyledTextActionHandler;
+
+
+public class RegExView extends ViewPart implements SelectionListener,
+ IRegExListener, ILiveEvalListener, IExpressionLoaderListener, IPropertyChangeListener {
+
+ private StyledText txt_RegExp;
+
+ private StyledText txt_SearchText;
+
+ private StyledText txt_Result;
+
+ private Label lbl_RegExp;
+
+ private Button btn_Find, btn_LiveEval;
+
+ private Composite cmp_ButtonGroup;
+
+ private MenuItem mit_CopyLiteral, mit_mReplace, mit_mFind, mit_mMatch,
+ mit_PasteLiteral, mit_mSplit, mit_EvalSelection;
+
+ private int currentCarresPos = 0;
+
+ private final RegExModel regex;
+
+ private LiveEval liveEval;
+
+ private IAction prevMatchAction;
+
+ private IAction nextMatchAction;
+
+ private IAction clearAction;
+
+ private IPreferenceStore prefs;
+
+ private Menu men_PatternFlags;
+
+ private String[] modeLabels = new String[] { "Find", "Match", "Split", "Replace"};
+
+ private static final Color COLOR_WHITE = Display.getCurrent()
+ .getSystemColor(SWT.COLOR_WHITE);
+
+ private static final Color COLOR_RED = Display.getCurrent().getSystemColor(
+ SWT.COLOR_RED);
+
+ private Menu men_MatchMode;
+
+ private MenuItem mit_MatchMode;
+
+ private AboutAction aboutAction;
+
+
+ public RegExView() {
+
+ regex = RegExModel.getInstance();
+ prefs = RegExPlugin.getDefault().getPreferenceStore();
+ prefs.addPropertyChangeListener(this);
+ regex.addRegExListener(this);
+
+ ExpressionLoader.getInstance().addExpressionLoaderListener(this);
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IWorkbenchPart#dispose()
+ */
+ public void dispose() {
+ regex.removeRegExListener(this);
+ prefs.removePropertyChangeListener(this);
+ ExpressionLoader.getInstance().removeExpressionLoaderListener(this);
+ }
+
+
+ public void createPartControl(final Composite parent) {
+
+ makeActions();
+
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+
+ parent.setLayout(gridLayout);
+ GridData gridData = new GridData();
+ parent.setLayoutData(gridData);
+
+ lbl_RegExp = new Label(parent, SWT.LEFT);
+ lbl_RegExp.setText("Regular Expression");
+
+ txt_RegExp = new StyledText(parent, SWT.LEFT | SWT.BORDER | SWT.SINGLE);
+
+
+ txt_RegExp.addKeyListener(new BracketMatchingKeyAdapter());
+ txt_RegExp.addKeyListener(new AssistKeyAdapter());
+
+
+ // GRO: Store/Restore last input value from PreferenceStore
+ IPreferenceStore preferenceStore = RegExPlugin.getDefault().getPreferenceStore();
+ String preferenceKey = "txt_RegExp";
+ txt_RegExp.addFocusListener(new SaveLastValueToPreferenceStoreFocusAdapter(preferenceStore, preferenceKey));
+ txt_RegExp.setText(preferenceStore.getString(preferenceKey));
+
+
+ txt_RegExp.addFocusListener(new FocusListener() {
+
+ private int caretOffset;
+
+ public void focusGained(FocusEvent e) {
+ ((StyledText) e.widget).setCaretOffset(caretOffset);
+ }
+
+ public void focusLost(FocusEvent e) {
+ caretOffset = ((StyledText) e.widget).getCaretOffset();
+ }
+ });
+
+ txt_RegExp.setFont(new Font(Display.getCurrent(), new FontData(prefs.getString("font.regex.name"), prefs.getInt("font.regex.height"), prefs.getInt("font.regex.style"))));
+ txt_RegExp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ txt_RegExp.setMenu(new Menu(parent.getShell()));
+ setTextMenuItems(txt_RegExp);
+ new MenuItem(txt_RegExp.getMenu(), SWT.BAR);
+ setPatternFlagMenu(txt_RegExp.getMenu());
+
+ txt_RegExp.getMenu().addMenuListener(new MenuListener() {
+
+
+ public void menuHidden(MenuEvent e) {
+
+ }
+
+ public void menuShown(MenuEvent e) {
+ if (txt_RegExp.getSelectionCount() > 0) {
+ mit_EvalSelection.setEnabled(true);
+ } else {
+ mit_EvalSelection.setEnabled(false);
+ }
+
+ }
+ });
+
+ // RegEx Menu: Match Mode
+
+ men_MatchMode = new Menu(txt_RegExp.getMenu());
+ mit_MatchMode = new MenuItem(txt_RegExp.getMenu(),
+ SWT.CASCADE);
+ mit_MatchMode.setText("Match mode");
+ mit_MatchMode.setMenu(men_MatchMode);
+
+ mit_mFind = new MenuItem(men_MatchMode, SWT.RADIO);
+ mit_mFind.setText("Find sequence");
+ mit_mFind.setData(new Integer(RegExModel.MODE_FIND));
+ mit_mFind.setSelection(true);
+ mit_mFind.addSelectionListener(this);
+
+ mit_mMatch = new MenuItem(men_MatchMode, SWT.RADIO);
+ mit_mMatch.setText("Match complete text");
+ mit_mMatch.setData(new Integer(RegExModel.MODE_MATCH));
+ mit_mMatch.addSelectionListener(this);
+
+ mit_mSplit = new MenuItem(men_MatchMode, SWT.RADIO);
+ mit_mSplit.setText("Split");
+ mit_mSplit.setData(new Integer(RegExModel.MODE_SPLIT));
+ mit_mSplit.addSelectionListener(this);
+
+ mit_mReplace = new MenuItem(men_MatchMode, SWT.RADIO);
+ mit_mReplace.setText("Replace...");
+ mit_mReplace.setData(new Integer(RegExModel.MODE_REPLACE));
+ mit_mReplace.addSelectionListener(this);
+
+
+
+ // RegEx Menu Item: Copy As String Literal
+ mit_CopyLiteral = new MenuItem(txt_RegExp.getMenu(), SWT.NONE);
+ mit_CopyLiteral.setText("Copy As String &Literal");
+ mit_CopyLiteral.addSelectionListener(this);
+
+ mit_PasteLiteral = new MenuItem(txt_RegExp.getMenu(), SWT.NONE);
+ mit_PasteLiteral.setText("&Paste String Literal");
+ mit_PasteLiteral.addSelectionListener(this);
+
+
+ new MenuItem(txt_RegExp.getMenu(), SWT.BAR);
+ mit_EvalSelection = new MenuItem(txt_RegExp.getMenu(), SWT.NONE);
+ mit_EvalSelection.setText("Eval Selection Only");
+ mit_EvalSelection.addSelectionListener(new SelectionListener() {
+
+ public void widgetSelected(SelectionEvent e) {
+ regex.setRegExp(txt_RegExp.getSelectionText());
+ regex.setSearchText(txt_SearchText.getText());
+ regex.process();
+
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // TODO Auto-generated method stub
+
+ }});
+
+
+
+ SashForm sashForm = new SashForm(parent, SWT.VERTICAL);
+ sashForm.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ txt_SearchText = new StyledText(sashForm, SWT.LEFT | SWT.MULTI
+ | SWT.V_SCROLL | SWT.BORDER);
+ txt_SearchText.setFont(new Font(Display.getCurrent(), new FontData(prefs.getString("font.searchtext.name"), prefs.getInt("font.searchtext.height"), prefs.getInt("font.searchtext.style"))));
+ txt_SearchText.setWordWrap(true);
+ txt_SearchText.setLayoutData(new GridData(GridData.FILL_BOTH));
+ txt_SearchText.addVerifyKeyListener(new VerifyKeyListener() {
+
+ public void verifyKey(VerifyEvent event) {
+ if (event.keyCode == SWT.TAB) {
+ txt_RegExp.setCaretOffset(currentCarresPos);
+ currentCarresPos = txt_SearchText.getCaretOffset();
+ txt_RegExp.setFocus();
+ event.doit = false;
+ }
+ }
+ });
+
+ txt_SearchText.setMenu(new Menu(parent.getShell()));
+ setTextMenuItems(txt_SearchText);
+
+
+ // GRO: Store/Restore last input value from PreferenceStore
+ preferenceKey = "txt_SearchText";
+ txt_SearchText.addFocusListener(new SaveLastValueToPreferenceStoreFocusAdapter(preferenceStore, preferenceKey));
+ txt_SearchText.setText(preferenceStore.getString(preferenceKey));
+
+
+
+ txt_Result = new StyledText(sashForm, SWT.LEFT | SWT.MULTI
+ | SWT.V_SCROLL | SWT.BORDER | SWT.READ_ONLY);
+
+ txt_Result.setFont(new Font(Display.getCurrent(), new FontData(prefs.getString("font.result.name"), prefs.getInt("font.result.height"), prefs.getInt("font.result.style"))));
+ txt_Result.setWordWrap(true);
+ txt_Result.setLayoutData(new GridData(GridData.FILL_BOTH));
+ txt_Result.setBackground(Display.getCurrent().getSystemColor(
+ SWT.COLOR_WIDGET_BACKGROUND));
+ txt_Result.setMenu(new Menu(parent.getShell()));
+ setTextMenuItems(txt_Result);
+
+ cmp_ButtonGroup = new Composite(parent, 0);
+ RowLayout buttonRow = new RowLayout();
+ buttonRow.pack = false;
+ buttonRow.marginLeft = 0;
+ buttonRow.spacing = 20;
+ cmp_ButtonGroup.setLayout(buttonRow);
+
+ btn_Find = new Button(cmp_ButtonGroup, SWT.CENTER | SWT.FLAT);
+ btn_Find.setText("&Find");
+ btn_Find.addSelectionListener(this);
+
+ liveEval = new LiveEval(txt_RegExp, txt_SearchText);
+ liveEval.addLiveEvalListener(this);
+
+ btn_LiveEval = new Button(cmp_ButtonGroup, SWT.CHECK | SWT.FLAT);
+ btn_LiveEval.setText("&Live Evaluation");
+ if (prefs.getBoolean("EvalSwitch")) {
+ btn_LiveEval.setSelection(true);
+ liveEval.start();
+ }
+
+ btn_LiveEval.addSelectionListener(new SelectionAdapter() {
+
+ public void widgetSelected(SelectionEvent e) {
+ Button check = (Button) e.widget;
+ if (check.getSelection()) {
+ liveEval.start();
+ } else {
+ liveEval.stop();
+ }
+ }
+ });
+
+ StyledTextActionHandler styledTextActionHandler = new StyledTextActionHandler(
+ this.getViewSite().getActionBars());
+ styledTextActionHandler.addStyledText(txt_RegExp);
+ styledTextActionHandler.addStyledText(txt_SearchText);
+ styledTextActionHandler.addStyledText(txt_Result);
+
+ if (liveEval.isLiveEval()) {
+ processRegEx();
+ updateFoundStatus();
+ }
+
+ }
+
+ public void updateFoundStatus() {
+ if (regex.foundMatches()) {
+ if (regex.getMatches().getMatchPos() > 0)
+ prevMatchAction.setEnabled(true);
+ else
+ prevMatchAction.setEnabled(false);
+
+ if (regex.getMatches().getMatchPos() < regex.getMatches()
+ .getMatchCount() - 1)
+ nextMatchAction.setEnabled(true);
+ else
+ nextMatchAction.setEnabled(false);
+ } else {
+ prevMatchAction.setEnabled(false);
+ nextMatchAction.setEnabled(false);
+ }
+ }
+
+ private void makeActions() {
+ nextMatchAction = new NextMatchAction(this);
+ prevMatchAction = new PrevMatchAction(this);
+ clearAction = new ClearAction(this);
+
+
+ aboutAction = new AboutAction(this);
+
+ getViewSite().getActionBars().getToolBarManager().add(clearAction);
+ getViewSite().getActionBars().getToolBarManager().add(new Separator());
+ getViewSite().getActionBars().getToolBarManager().add(prevMatchAction);
+ getViewSite().getActionBars().getToolBarManager().add(nextMatchAction);
+ //getViewSite().getActionBars().getMenuManager().add(registerAction);
+ getViewSite().getActionBars().getMenuManager().add(aboutAction);
+ }
+
+ public void selectNextMatch() {
+ Match match = regex.getMatches().nextMatch();
+ if (match != null) {
+ StyledText searchText = txt_SearchText;
+ StyledText resultText = txt_Result;
+ searchText.setSelection(match.getStart(), match.getEnd());
+
+ String resultStr = resultText.getText();
+ Pattern patt = Pattern.compile("start=" + match.getStart()
+ + ", end=" + match.getEnd());
+ Matcher matcher = patt.matcher(resultStr);
+ if (matcher.find()) {
+ resultText.setSelection(matcher.start(), matcher.end());
+ }
+ }
+ }
+
+ public void selectPreviousMatch() {
+ Match match = regex.getMatches().prevMatch();
+
+ if (match != null) {
+ StyledText searchText = txt_SearchText;
+ StyledText resultText = txt_Result;
+ searchText.setSelection(match.getStart(), match.getEnd());
+ String resultStr = resultText.getText();
+
+ Pattern patt = Pattern.compile("start=" + match.getStart()
+ + ", end=" + match.getEnd());
+ Matcher matcher = patt.matcher(resultStr);
+ if (matcher.find()) {
+ resultText.setSelection(matcher.start(), matcher.end());
+ }
+ }
+
+ }
+
+ public void clear(int mode) {
+
+ if (mode == ClearAction.MODE_REGEX || mode == ClearAction.MODE_ALL) {
+ txt_RegExp.setText("");
+ }
+ if (mode == ClearAction.MODE_SEARCH || mode == ClearAction.MODE_ALL) {
+ txt_SearchText.setText("");
+ }
+ if (mode == ClearAction.MODE_RESULT || mode == ClearAction.MODE_ALL) {
+ txt_Result.setText("");
+ }
+
+ regex.reset();
+
+ }
+
+ private void setPatternFlagMenu(Menu menu) {
+ class FlagStatusAdapter extends SelectionAdapter {
+
+ public void widgetSelected(SelectionEvent e) {
+ MenuItem menItem = (MenuItem) e.widget;
+ Integer flag = (Integer) menItem.getData();
+ if (menItem.getSelection()) {
+ regex.addPatternFlag(flag.intValue());
+ } else {
+ regex.removePatternFlag(flag.intValue());
+ }
+ if (liveEval.isLiveEval()) {
+ processRegEx();
+ updateFoundStatus();
+ }
+ txt_RegExp.setToolTipText(regex.getPatternFlagsAsString());
+ }
+ }
+ FlagStatusAdapter flagStatusAdapter = new FlagStatusAdapter();
+
+ men_PatternFlags = new Menu(menu);
+ MenuItem mit_PatternFlags = new MenuItem(menu, SWT.CASCADE);
+ mit_PatternFlags.setText("Pattern &Flags");
+ mit_PatternFlags.setMenu(men_PatternFlags);
+
+ MenuItem mit_Flags_CanonEq = new MenuItem(men_PatternFlags, SWT.CHECK);
+ mit_Flags_CanonEq.setText("Canonical &Equivalence");
+ mit_Flags_CanonEq.setData(new Integer(Pattern.CANON_EQ));
+ mit_Flags_CanonEq.setSelection(prefs.getBoolean("Pattern.CANON_EQ"));
+ mit_Flags_CanonEq.addSelectionListener(flagStatusAdapter);
+
+ MenuItem mit_Flags_CaseIns = new MenuItem(men_PatternFlags, SWT.CHECK);
+ mit_Flags_CaseIns.setText("Case &Insensitive");
+ mit_Flags_CaseIns.setData(new Integer(Pattern.CASE_INSENSITIVE));
+ mit_Flags_CaseIns.setSelection(prefs
+ .getBoolean("Pattern.CASE_INSENSITIVE"));
+ mit_Flags_CaseIns.addSelectionListener(flagStatusAdapter);
+
+ MenuItem mit_Flags_Comments = new MenuItem(men_PatternFlags, SWT.CHECK);
+ mit_Flags_Comments.setText("&Comments");
+ mit_Flags_Comments.setData(new Integer(Pattern.COMMENTS));
+ mit_Flags_Comments.setSelection(prefs.getBoolean("Pattern.COMMENTS"));
+ mit_Flags_Comments.addSelectionListener(flagStatusAdapter);
+
+ MenuItem mit_Flags_Dotall = new MenuItem(men_PatternFlags, SWT.CHECK);
+ mit_Flags_Dotall.setText("&Dotall Mode");
+ mit_Flags_Dotall.setData(new Integer(Pattern.DOTALL));
+ mit_Flags_Dotall.setSelection(prefs.getBoolean("Pattern.DOTALL"));
+ mit_Flags_Dotall.addSelectionListener(flagStatusAdapter);
+
+ MenuItem mit_Flags_Multiline = new MenuItem(men_PatternFlags, SWT.CHECK);
+ mit_Flags_Multiline.setText("&Multiline Mode");
+ mit_Flags_Multiline.setData(new Integer(Pattern.MULTILINE));
+ mit_Flags_Multiline.setSelection(prefs.getBoolean("Pattern.MULTILINE"));
+ mit_Flags_Multiline.addSelectionListener(flagStatusAdapter);
+
+ MenuItem mit_Flags_unicodeCase = new MenuItem(men_PatternFlags,
+ SWT.CHECK);
+ mit_Flags_unicodeCase.setText("&Unicode Case");
+ mit_Flags_unicodeCase.setData(new Integer(Pattern.UNICODE_CASE));
+ mit_Flags_unicodeCase.setSelection(prefs
+ .getBoolean("Pattern.UNICODE_CASE"));
+ mit_Flags_unicodeCase.addSelectionListener(flagStatusAdapter);
+
+ MenuItem mit_Flags_unixLines = new MenuItem(men_PatternFlags, SWT.CHECK);
+ mit_Flags_unixLines.setText("Unix &Lines");
+ mit_Flags_unixLines.setData(new Integer(Pattern.UNIX_LINES));
+ mit_Flags_unixLines
+ .setSelection(prefs.getBoolean("Pattern.UNIX_LINES"));
+ mit_Flags_unixLines.addSelectionListener(flagStatusAdapter);
+
+ new MenuItem(men_PatternFlags, SWT.BAR);
+ MenuItem mit_Flags_deactivateAll = new MenuItem(men_PatternFlags,
+ SWT.NONE);
+ mit_Flags_deactivateAll.setText("Deactivate &All");
+ mit_Flags_deactivateAll.addSelectionListener(new SelectionAdapter() {
+
+ public void widgetSelected(SelectionEvent e) {
+ MenuItem menItem = (MenuItem) e.widget;
+ Menu menu = menItem.getParent();
+ MenuItem[] menItems = menu.getItems();
+ for (int i = 0; i < menItems.length; i++) {
+ menItems[i].setSelection(false);
+ }
+ regex.resetPatternFlag();
+ }
+ });
+
+ }
+
+ public void setFocus() {
+ txt_RegExp.setFocus();
+ }
+
+ private void setTextMenuItems(StyledText text) {
+ MenuItem mitCut = new MenuItem(text.getMenu(), SWT.NONE);
+ mitCut.setText("Cu&t");
+ mitCut.setData(new StandardTextFieldAction(text,
+ StandardTextFieldAction.CUT));
+ mitCut.addSelectionListener(this);
+
+ MenuItem mitCopy = new MenuItem(text.getMenu(), SWT.NONE);
+ mitCopy.setText("&Copy");
+ mitCopy.setData(new StandardTextFieldAction(text,
+ StandardTextFieldAction.COPY));
+ mitCopy.addSelectionListener(this);
+
+ MenuItem mitPaste = new MenuItem(text.getMenu(), SWT.NONE);
+ mitPaste.setText("&Paste");
+ mitPaste.setData(new StandardTextFieldAction(text,
+ StandardTextFieldAction.PASTE));
+ mitPaste.addSelectionListener(this);
+
+ MenuItem mitSelectAll = new MenuItem(text.getMenu(), SWT.NONE);
+ mitSelectAll.setText("Select &All");
+ mitSelectAll.setData(new StandardTextFieldAction(text,
+ StandardTextFieldAction.SELECT_ALL));
+ mitSelectAll.addSelectionListener(this);
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ Widget widget = e.widget;
+ Object data = widget.getData();
+
+ // selected one of the standard text field menu commands
+ // Cut, Copy, Paste, Select All
+ if (data instanceof StandardTextFieldAction) {
+ ((StandardTextFieldAction) data).perform();
+ }
+
+ // Selected MenuItem "Copy As String Literal"
+ if (widget == mit_CopyLiteral) {
+ Clipboard clipboard = new Clipboard(e.display);
+ TextTransfer textTransfer = TextTransfer.getInstance();
+ clipboard.setContents(new Object[] { regex.getRegExAsLiteral() },
+ new Transfer[] { textTransfer });
+ clipboard.dispose();
+ }
+
+ if (widget == mit_mFind || widget == mit_mMatch
+ || widget == mit_mReplace || widget == mit_mSplit) {
+ MenuItem menuItem = (MenuItem) widget;
+ if (menuItem.getSelection()) {
+ int mode = ((Integer) data).intValue();
+ setMatchMode(mode);
+ if (liveEval.isLiveEval()) {
+ processRegEx();
+ updateFoundStatus();
+ }
+ }
+ }
+
+ if (widget == mit_PasteLiteral) {
+ pasteLiteral(e.display);
+ }
+
+ // Selected MenuItem "Replace ..."
+ if (widget == mit_mReplace) {
+ MenuItem menuItem = (MenuItem) widget;
+ if (menuItem.getSelection())
+ activateReplaceMode();
+ }
+
+ if (widget == btn_Find) {
+ processRegEx();
+ updateFoundStatus();
+ }
+
+ }
+
+ private void setMatchMode(int mode) {
+ regex.setMatchMode(mode);
+ btn_Find.setText(modeLabels[mode]);
+ MenuItem[] modeItems = men_MatchMode.getItems();
+ if (!modeItems[mode].getSelection()) {
+ for (int i = 0; i < modeItems.length; i++) {
+ modeItems[i].setSelection(false);
+ }
+ modeItems[mode].setSelection(true);
+ }
+ }
+
+ private void pasteLiteral(Display display) {
+ Clipboard clipboard = new Clipboard(display);
+ TextTransfer textTransfer = TextTransfer.getInstance();
+ String clipboardText = (String) clipboard.getContents(textTransfer);
+ clipboard.dispose();
+
+ if (clipboardText != null) {
+ StringBuffer out = new StringBuffer();
+ char[] chars = clipboardText.toCharArray();
+ boolean lastWasBackslash = false;
+ for (int i = 0; i < chars.length; i++) {
+ if (chars[i] == '\\') {
+ if (lastWasBackslash) {
+ out.append(chars[i]);
+ lastWasBackslash = false;
+ } else {
+ lastWasBackslash = true;
+ }
+ } else {
+ out.append(chars[i]);
+ }
+
+ }
+
+ txt_RegExp.insert(out.toString());
+ }
+ }
+
+ private void activateReplaceMode() {
+ InputDialog inputDialog = new InputDialog(
+ getViewSite().getShell(),
+ "Replace Match by ...",
+ "Enter a value which should be used to replace every instance of a found match:",
+ regex.getReplace(), new IInputValidator() {
+
+ public String isValid(String newText) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ });
+ int retCode = inputDialog.open();
+
+ if (retCode == Window.OK) {
+ String replace = inputDialog.getValue();
+
+ regex.setMatchMode(RegExModel.MODE_REPLACE);
+ regex.setReplace(replace);
+
+ btn_Find.setText(modeLabels[RegExModel.MODE_REPLACE]);
+
+ if (liveEval.isLiveEval()) {
+ processRegEx();
+ updateFoundStatus();
+ }
+ }
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // do nothing
+ }
+
+ private void processRegEx() {
+ updateModel();
+ regex.process();
+ }
+
+ public void updateModel() {
+ regex.setRegExp(txt_RegExp.getText());
+ regex.setSearchText(txt_SearchText.getText());
+ }
+
+ public void updateView(Expression state) {
+ updateView(state.getName(), state.getRegex(), state.getSearchText(), state.getMatchMode(), state.getPatternFlag());
+ updateModel();
+ }
+
+ public void updateView(String descr, String regEx, String search, int matchMode, int patternFlags) {
+ txt_RegExp.setText(regEx);
+ txt_SearchText.setText(search);
+ setMatchMode(matchMode);
+ setPatternFlags(patternFlags);
+ setRegExDecription(descr);
+ }
+
+
+
+ private void setRegExDecription(String descr) {
+
+ regex.setDescription(descr);
+ }
+
+ private void setPatternFlags(int patternFlags) {
+ MenuItem[] flagItems = men_PatternFlags.getItems();
+ for (int i = 0; i < flagItems.length; i++) {
+ if (flagItems[i].getData() == null)
+ continue;
+ if ((patternFlags & ((Integer) flagItems[i].getData()).intValue()) != 0) {
+ flagItems[i].setSelection(true);
+ } else {
+ flagItems[i].setSelection(false);
+ }
+ }
+
+ }
+
+ private void displayReplace(ReplaceResult replaceResult) {
+ StringBuffer out = new StringBuffer("Replaced "
+ + replaceResult.getMatches().getMatchCount()
+ + " match(es):\n\n");
+ out.append(replaceResult.getResultText());
+ txt_Result.setText(out.toString());
+ }
+
+ private void displaySplit(String[] splitResult) {
+ StringBuffer out = new StringBuffer("Split text into "
+ + splitResult.length + " parts:\n\n");
+ for (int i = 0; i < splitResult.length; i++) {
+ out.append("part ");
+ out.append(i);
+ out.append(" = ");
+ out.append(splitResult[i]);
+ out.append("\n\n");
+ }
+ out.append(txt_Result.getText());
+ txt_Result.setText(out.toString());
+ }
+
+ private void displayMatches(Matches matches) {
+ StringBuffer out = new StringBuffer("Found " + matches.getMatchCount()
+ + " match(es):\n\n");
+ txt_SearchText.setStyleRange(null);
+
+ StyleRange[] styleRanges = new StyleRange[matches.getMatchCount()];
+ int c = 0;
+
+ for (Iterator i = matches.iterator(); i.hasNext();) {
+ Match match = (Match) i.next();
+
+ styleRanges[c++] = new StyleRange(match.getStart(), match.getEnd()
+ - match.getStart(), COLOR_RED, COLOR_WHITE);
+
+ out.append("start=");
+ out.append(match.getStart());
+ out.append(", end=");
+ out.append(match.getEnd());
+ out.append("\n");
+ for (Iterator groups = match.getGroups().iterator(); groups
+ .hasNext();) {
+ Group group = (Group) groups.next();
+ out.append("Group(");
+ out.append(group.getIndex());
+ out.append(") = ");
+ out.append(group.getText());
+ out.append("\n");
+ }
+
+ out.append("\n");
+
+ }
+ txt_SearchText.setStyleRanges(styleRanges);
+ txt_Result.setText(out.toString());
+ }
+
+
+ public void foundMatches(Matches matches) {
+ displayMatches(matches);
+ }
+
+
+ public void foundNoMatches() {
+ txt_SearchText.setStyleRange(null);
+ txt_Result.setText("No matches found!");
+ }
+
+
+ public void expressionError(String errMsg) {
+ txt_Result.setText("A Syntax Error occured: \\n" + errMsg);
+ }
+
+ public void doneWithReplace(ReplaceResult result) {
+ displayReplace(result);
+ }
+
+ public void doneWithSplit(String[] result) {
+ displaySplit(result);
+ }
+
+
+ public void evalActivated() {
+ btn_LiveEval.setSelection(true);
+ processRegEx();
+ updateFoundStatus();
+ }
+
+
+ public void evalDeactivated() {
+ btn_LiveEval.setSelection(false);
+ }
+
+
+ public void evalDone() {
+ updateFoundStatus();
+ }
+
+
+ public void doEval() {
+ processRegEx();
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.regex.IRegExListener#updateRequested()
+ */
+ public void updateRequested() {
+ updateModel();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.regex.view.IExpressionLoaderListener#loadExpression(org.eclipse.ui.regex.view.Expression)
+ */
+ public void loadExpression(Expression expression) {
+ updateView(expression);
+ }
+
+ protected void setRegExFont(FontData fontData) {
+ txt_RegExp.setFont(new Font(Display.getCurrent(), fontData));
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
+ */
+ public void propertyChange(PropertyChangeEvent event) {
+ if (event.getProperty().startsWith("font.")) {
+ txt_RegExp.setFont(new Font(Display.getCurrent(), new FontData(prefs.getString("font.regex.name"), prefs.getInt("font.regex.height"), prefs.getInt("font.regex.style"))));
+ txt_SearchText.setFont(new Font(Display.getCurrent(), new FontData(prefs.getString("font.searchtext.name"), prefs.getInt("font.searchtext.height"), prefs.getInt("font.searchtext.style"))));
+ txt_Result.setFont(new Font(Display.getCurrent(), new FontData(prefs.getString("font.result.name"), prefs.getInt("font.result.height"), prefs.getInt("font.result.style"))));
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/SaveLastValueToPreferenceStoreFocusAdapter.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/SaveLastValueToPreferenceStoreFocusAdapter.java
new file mode 100644
index 0000000..ca0860c
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/SaveLastValueToPreferenceStoreFocusAdapter.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Andreas Groll
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andreas Groll - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex.view;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.FocusAdapter;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Saves the last text value from a widget when focus is lost to {@link IPreferenceStore}.
+ * PreferenceStore will be automatically saved by
+ * {@link org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)}.
+ * <p>
+ * The current version support only {@link StyledText}, but it can be easily extended, if
+ * needed.
+ * @author Andreas Groll
+ */
+public class SaveLastValueToPreferenceStoreFocusAdapter extends FocusAdapter {
+
+ private final IPreferenceStore preferenceStore;
+ private final String preferenceKey;
+
+ /**
+ * Constructor.
+ * @param preferenceStore PreferenceStore to store value.
+ * @param preferenceKey Name of the key to store value.
+ */
+ public SaveLastValueToPreferenceStoreFocusAdapter(final IPreferenceStore preferenceStore,
+ final String preferenceKey) {
+
+ this.preferenceStore = preferenceStore;
+ this.preferenceKey = preferenceKey;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void focusLost(final FocusEvent e) {
+
+ // Init
+ String value = null;
+
+ // Current version supports only StyledText and Text, but can be extended, if needed
+ if (e.widget instanceof StyledText) {
+ StyledText styledText = (StyledText)e.widget;
+ value = styledText.getText();
+ } else if (e.widget instanceof Text) {
+ Text text = (Text)e.widget;
+ value = text.getText();
+ } else {
+ // Unusupported widget type
+ return;
+ }
+
+ // Put to preference store
+ preferenceStore.setValue(preferenceKey, value == null ? "" : value);
+ }
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/AboutAction.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/AboutAction.java
new file mode 100644
index 0000000..59e96fb
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/AboutAction.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex.view.actions;
+
+import java.util.Dictionary;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.ui.regex.RegExPlugin;
+import org.eclipse.ui.regex.view.RegExView;
+
+
+public class AboutAction extends Action {
+
+ private RegExView view;
+
+ public AboutAction(RegExView view) {
+ setText("About");
+ this.view = view;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ Dictionary d = RegExPlugin.getDefault().getBundle().getHeaders();
+ String version = (String) d.get(org.osgi.framework.Constants.BUNDLE_VERSION);
+
+ String msg = "Regular Expression Tester " + version + "\n";
+ msg += "(C) 2006-2012 by Stephan Brosinski <sbrosinski@gmail.com>\n\n";
+ msg += "https://github.com/sbrosinski/RegexTester \n";
+
+
+ MessageDialog.openInformation(view.getSite().getShell(), "About RegexTester", msg);
+
+
+ }
+
+
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/ClearAction.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/ClearAction.java
new file mode 100644
index 0000000..2254ebd
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/ClearAction.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex.view.actions;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.regex.RegExPlugin;
+import org.eclipse.ui.regex.view.RegExView;
+
+public class ClearAction extends Action {
+ public static final int MODE_REGEX = 0;
+ public static final int MODE_SEARCH = 1;
+ public static final int MODE_RESULT = 2;
+ public static final int MODE_ALL = 3;
+
+ private static ImageDescriptor image = RegExPlugin.getDefault().getImageDescriptor("clear_co.gif");
+ private int mode = MODE_ALL;
+ private RegExView view;
+
+
+ public ClearAction(RegExView regExView) {
+ super("ClearAction", image);
+ view = regExView;
+ setToolTipText("Clear...");
+ setMenuCreator(new ClearActionMenuCreator(this));
+ }
+
+ public void setMode(int aMode) {
+ mode =aMode;
+ }
+
+ public void run() {
+ view.clear(mode);
+ view.updateFoundStatus();
+ }
+
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/ClearActionMenuCreator.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/ClearActionMenuCreator.java
new file mode 100644
index 0000000..68d1fea
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/ClearActionMenuCreator.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex.view.actions;
+
+import org.eclipse.jface.action.IMenuCreator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+
+
+public class ClearActionMenuCreator implements IMenuCreator {
+
+ Menu menu;
+ ClearAction clearAction;
+ ClearSelection clearSelection = new ClearSelection();
+
+ class ClearSelection extends SelectionAdapter {
+ public void widgetSelected(SelectionEvent e) {
+ MenuItem menuItem = (MenuItem) e.widget;
+ boolean selected = menuItem.getSelection();
+ int mode=((Integer)menuItem.getData()).intValue();
+
+ if (selected) {
+ clearAction.setMode(mode);
+ }
+ }
+ }
+
+ public ClearActionMenuCreator(ClearAction action) {
+ clearAction = action;
+ }
+
+ public void dispose() {
+ if (menu != null) {
+ menu.dispose();
+ }
+ }
+
+
+ public Menu getMenu(Control parent) {
+ if (menu != null) {
+ return menu;
+ }
+
+ menu = new Menu(parent);
+
+ MenuItem mitClearBoth= new MenuItem(menu,SWT.RADIO);
+ mitClearBoth.setData(new Integer(ClearAction.MODE_ALL));
+ mitClearBoth.setText("Everything");
+ mitClearBoth.addSelectionListener(clearSelection);
+ mitClearBoth.setSelection(true);
+
+ MenuItem mitClearRegEx = new MenuItem(menu, SWT.RADIO);
+ mitClearRegEx.setText("Regular Expression");
+ mitClearRegEx.setData(new Integer(ClearAction.MODE_REGEX));
+ mitClearRegEx.addSelectionListener(clearSelection);
+
+ MenuItem mitClearSearch= new MenuItem(menu,SWT.RADIO);
+ mitClearSearch.setData(new Integer(ClearAction.MODE_SEARCH));
+ mitClearSearch.setText("Search Text");
+ mitClearSearch.addSelectionListener(clearSelection);
+
+ MenuItem mitClearResult= new MenuItem(menu,SWT.RADIO);
+ mitClearResult.setData(new Integer(ClearAction.MODE_RESULT));
+ mitClearResult.setText("Result");
+ mitClearResult.addSelectionListener(clearSelection);
+
+
+ return menu;
+ }
+
+
+ public Menu getMenu(Menu parent) {
+ return null;
+ }
+
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/NextMatchAction.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/NextMatchAction.java
new file mode 100644
index 0000000..878cc62
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/NextMatchAction.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.ui.regex.view.actions;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.regex.RegExPlugin;
+import org.eclipse.ui.regex.view.RegExView;
+
+public class NextMatchAction extends Action {
+ private static ImageDescriptor image = RegExPlugin.getDefault().getImageDescriptor("forward_nav.gif");
+ private RegExView view;
+
+ public NextMatchAction(RegExView regExView) {
+ super("NextMatchAction", image);
+ view = regExView;
+ setEnabled(false);
+ setToolTipText("Show Next Match");
+ }
+
+ public void run() {
+ view.selectNextMatch();
+ view.updateFoundStatus();
+ }
+
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/PrevMatchAction.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/PrevMatchAction.java
new file mode 100644
index 0000000..ff49112
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/PrevMatchAction.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.ui.regex.view.actions;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.regex.RegExPlugin;
+import org.eclipse.ui.regex.view.RegExView;
+
+public class PrevMatchAction extends Action {
+ private static ImageDescriptor image = RegExPlugin.getDefault().getImageDescriptor("backward_nav.gif");
+ private RegExView view;
+
+ public PrevMatchAction(RegExView regExView) {
+ super("PrevMatchAction", image);
+ view = regExView;
+ setEnabled(false);
+ setToolTipText("Show Previous Match");
+ }
+
+ public void run() {
+ view.selectPreviousMatch();
+ view.updateFoundStatus();
+ }
+
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/StandardTextFieldAction.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/StandardTextFieldAction.java
new file mode 100644
index 0000000..3173827
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/StandardTextFieldAction.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stephan Brosinski
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Brosinski - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ui.regex.view.actions;
+
+import org.eclipse.swt.custom.StyledText;
+
+
+public class StandardTextFieldAction {
+
+ private StyledText styledText;
+ private int type;
+
+ public static final int COPY = 1;
+ public static final int CUT = 2;
+ public static final int PASTE = 3;
+ public static final int SELECT_ALL = 4;
+
+ public StandardTextFieldAction(StyledText styledText,int type) {
+ this.styledText = styledText;
+ this.type = type;
+ }
+
+ public void perform() {
+ if (type == COPY) styledText.copy();
+ if (type == CUT) styledText.cut();
+ if (type == PASTE) styledText.paste();
+ if (type == SELECT_ALL) styledText.selectAll();
+ }
+
+}
diff --git a/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/StyledTextActionHandler.java b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/StyledTextActionHandler.java
new file mode 100644
index 0000000..6b7638d
--- /dev/null
+++ b/bundles/org.eclipse.ui.regex/src/org/eclipse/ui/regex/view/actions/StyledTextActionHandler.java
@@ -0,0 +1,460 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * This class is based on IBM's TextActionHandler. It has been altered
+ * so it works with StyledText widgets instead
+ *
+ */
+
+package org.eclipse.ui.regex.view.actions;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.actions.ActionFactory;
+
+
+/**
+ * Handles the redirection of the global Cut, Copy, Paste, and
+ * Select All actions to either the current inline text control
+ * or the part's supplied action handler.
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p><p>
+ * Example usage:
+ * <pre>
+ * textActionHandler = new TextActionHandler(this.getViewSite().getActionBars());
+ * textActionHandler.addText((Text)textCellEditor1.getControl());
+ * textActionHandler.addText((Text)textCellEditor2.getControl());
+ * textActionHandler.setSelectAllAction(selectAllAction);
+ * </pre>
+ * </p>
+ */
+public class StyledTextActionHandler {
+ private DeleteActionHandler textDeleteAction = new DeleteActionHandler();
+ private CutActionHandler textCutAction = new CutActionHandler();
+ private CopyActionHandler textCopyAction = new CopyActionHandler();
+ private PasteActionHandler textPasteAction = new PasteActionHandler();
+ private SelectAllActionHandler textSelectAllAction = new SelectAllActionHandler();
+
+ private IAction deleteAction;
+ private IAction cutAction;
+ private IAction copyAction;
+ private IAction pasteAction;
+ private IAction selectAllAction;
+
+ private IPropertyChangeListener deleteActionListener = new PropertyChangeListener(textDeleteAction);
+ private IPropertyChangeListener cutActionListener = new PropertyChangeListener(textCutAction);
+ private IPropertyChangeListener copyActionListener = new PropertyChangeListener(textCopyAction);
+ private IPropertyChangeListener pasteActionListener = new PropertyChangeListener(textPasteAction);
+ private IPropertyChangeListener selectAllActionListener = new PropertyChangeListener(textSelectAllAction);
+
+ private Listener textControlListener = new TextControlListener();
+ private StyledText activeTextControl;
+
+ private MouseAdapter mouseAdapter = new MouseAdapter() {
+ public void mouseUp(MouseEvent e) {
+ updateActionsEnableState();
+ }
+ };
+ private KeyAdapter keyAdapter = new KeyAdapter() {
+ public void keyReleased(KeyEvent e) {
+ updateActionsEnableState();
+ }
+ };
+
+ private class TextControlListener implements Listener {
+ public void handleEvent(Event event) {
+ switch (event.type) {
+ case SWT.Activate:
+ activeTextControl = (StyledText) event.widget;
+ updateActionsEnableState();
+ break;
+ case SWT.Deactivate:
+ // added so only one of the styled text fields can
+ // have a selection, which I believe should be the default
+ // behaviour
+ activeTextControl.setSelection(0,0);
+ activeTextControl = null;
+ updateActionsEnableState();
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private class PropertyChangeListener implements IPropertyChangeListener {
+ private IAction actionHandler;
+ protected PropertyChangeListener(IAction actionHandler) {
+ super();
+ this.actionHandler = actionHandler;
+ }
+ public void propertyChange(PropertyChangeEvent event) {
+ if (activeTextControl != null)
+ return;
+ if (event.getProperty().equals(IAction.ENABLED)) {
+ Boolean bool = (Boolean) event.getNewValue();
+ actionHandler.setEnabled(bool.booleanValue());
+ }
+ }
+ };
+
+ private class DeleteActionHandler extends Action {
+ protected DeleteActionHandler() {
+ super("Delete"); //$NON-NLS-1$
+ setId("TextDeleteActionHandler");//$NON-NLS-1$
+ setEnabled(false);
+ }
+ public void runWithEvent(Event event) {
+ if (activeTextControl != null && !activeTextControl.isDisposed()) {
+ //this method doesn't exits in StyledText ??
+ //activeTextControl.clearSelection();
+ activeTextControl.setSelection(0,0);
+ return;
+ }
+ if (deleteAction != null) {
+ deleteAction.runWithEvent(event);
+ return;
+ }
+ }
+ public void updateEnabledState() {
+ if (activeTextControl != null && !activeTextControl.isDisposed()) {
+ //if condition also had: activeTextControl.getCaretPosition() < activeTextControl.getCharCount() removed
+ // because method doesn't exist in StyledText
+ setEnabled(activeTextControl.getSelectionCount() > 0);
+ return;
+ }
+ if (deleteAction != null) {
+ setEnabled(deleteAction.isEnabled());
+ return;
+ }
+ setEnabled(false);
+ }
+ }
+
+ private class CutActionHandler extends Action {
+ protected CutActionHandler() {
+ super("Cut"); //$NON-NLS-1$
+ setId("TextCutActionHandler");//$NON-NLS-1$
+ setEnabled(false);
+ }
+ public void runWithEvent(Event event) {
+ if (activeTextControl != null && !activeTextControl.isDisposed()) {
+ activeTextControl.cut();
+ return;
+ }
+ if (cutAction != null) {
+ cutAction.runWithEvent(event);
+ return;
+ }
+ }
+ public void updateEnabledState() {
+ if (activeTextControl != null && !activeTextControl.isDisposed()) {
+ setEnabled(activeTextControl.getSelectionCount() > 0);
+ return;
+ }
+ if (cutAction != null) {
+ setEnabled(cutAction.isEnabled());
+ return;
+ }
+ setEnabled(false);
+ }
+ }
+
+ private class CopyActionHandler extends Action {
+ protected CopyActionHandler() {
+ super("Copy"); //$NON-NLS-1$
+ setId("TextCopyActionHandler");//$NON-NLS-1$
+ setEnabled(false);
+ }
+ public void runWithEvent(Event event) {
+ if (activeTextControl != null && !activeTextControl.isDisposed()) {
+ activeTextControl.copy();
+ return;
+ }
+ if (copyAction != null) {
+ copyAction.runWithEvent(event);
+ return;
+ }
+ }
+ public void updateEnabledState() {
+ if (activeTextControl != null && !activeTextControl.isDisposed()) {
+ setEnabled(activeTextControl.getSelectionCount() > 0);
+ return;
+ }
+ if (copyAction != null) {
+ setEnabled(copyAction.isEnabled());
+ return;
+ }
+ setEnabled(false);
+ }
+ }
+
+ private class PasteActionHandler extends Action {
+ protected PasteActionHandler() {
+ super("Paste"); //$NON-NLS-1$
+ setId("TextPasteActionHandler");//$NON-NLS-1$
+ setEnabled(false);
+ }
+ public void runWithEvent(Event event) {
+ if (activeTextControl != null && !activeTextControl.isDisposed()) {
+ activeTextControl.paste();
+ return;
+ }
+ if (pasteAction != null) {
+ pasteAction.runWithEvent(event);
+ return;
+ }
+ }
+ public void updateEnabledState() {
+ if (activeTextControl != null && !activeTextControl.isDisposed()) {
+ setEnabled(true);
+ return;
+ }
+ if (pasteAction != null) {
+ setEnabled(pasteAction.isEnabled());
+ return;
+ }
+ setEnabled(false);
+ }
+ }
+
+ private class SelectAllActionHandler extends Action {
+ protected SelectAllActionHandler() {
+ super("TextAction.selectAll"); //$NON-NLS-1$
+ setId("TextSelectAllActionHandler");//$NON-NLS-1$
+ setEnabled(false);
+ }
+ public void runWithEvent(Event event) {
+ if (activeTextControl != null && !activeTextControl.isDisposed()) {
+ activeTextControl.selectAll();
+ return;
+ }
+ if (selectAllAction != null) {
+ selectAllAction.runWithEvent(event);
+ return;
+ }
+ }
+ public void updateEnabledState() {
+ if (activeTextControl != null && !activeTextControl.isDisposed()) {
+ setEnabled(true);
+ return;
+ }
+ if (selectAllAction != null) {
+ setEnabled(selectAllAction.isEnabled());
+ return;
+ }
+ setEnabled(false);
+ }
+ }
+/**
+ * Creates a <code>Text</code> control action handler
+ * for the global Cut, Copy, Paste, Delete, and Select All
+ * of the action bar.
+ *
+ * @param actionBar the action bar to register global
+ * action handlers for Cut, Copy, Paste, Delete,
+ * and Select All
+ */
+public StyledTextActionHandler(IActionBars actionBar) {
+ super();
+ actionBar.setGlobalActionHandler(ActionFactory.CUT.getId(), textCutAction);
+ actionBar.setGlobalActionHandler(ActionFactory.COPY.getId(), textCopyAction);
+ actionBar.setGlobalActionHandler(ActionFactory.PASTE.getId(), textPasteAction);
+ actionBar.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), textSelectAllAction);
+ actionBar.setGlobalActionHandler(ActionFactory.DELETE.getId(), textDeleteAction);
+}
+/**
+ * Add a <code>Text</code> control to the handler
+ * so that the Cut, Copy, Paste, Delete, and Select All
+ * actions are redirected to it when active.
+ *
+ * @param textControl the inline <code>Text</code> control
+ */
+public void addStyledText(StyledText textControl) {
+ if (textControl == null)
+ return;
+
+ activeTextControl = textControl;
+ textControl.addListener(SWT.Activate, textControlListener);
+ textControl.addListener(SWT.Deactivate, textControlListener);
+
+ // We really want a selection listener but it is not supported so we
+ // use a key listener and a mouse listener to know when selection changes
+ // may have occured
+ textControl.addKeyListener(keyAdapter);
+ textControl.addMouseListener(mouseAdapter);
+
+}
+/**
+ * Dispose of this action handler
+ */
+public void dispose() {
+ setCutAction(null);
+ setCopyAction(null);
+ setPasteAction(null);
+ setSelectAllAction(null);
+ setDeleteAction(null);
+}
+/**
+ * Removes a <code>Text</code> control from the handler
+ * so that the Cut, Copy, Paste, Delete, and Select All
+ * actions are no longer redirected to it when active.
+ *
+ * @param textControl the inline <code>Text</code> control
+ */
+public void removeStyledText(StyledText textControl) {
+ if (textControl == null)
+ return;
+
+ textControl.removeListener(SWT.Activate, textControlListener);
+ textControl.removeListener(SWT.Deactivate, textControlListener);
+
+ textControl.removeMouseListener(mouseAdapter);
+ textControl.removeKeyListener(keyAdapter);
+
+ activeTextControl = null;
+ updateActionsEnableState();
+}
+/**
+ * Set the default <code>IAction</code> handler for the Copy
+ * action. This <code>IAction</code> is run only if no active
+ * inline text control.
+ *
+ * @param action the <code>IAction</code> to run for the
+ * Copy action, or <code>null</null> if not interested.
+ */
+public void setCopyAction(IAction action) {
+ if (copyAction == action)
+ return;
+
+ if (copyAction != null)
+ copyAction.removePropertyChangeListener(copyActionListener);
+
+ copyAction = action;
+
+ if (copyAction != null)
+ copyAction.addPropertyChangeListener(copyActionListener);
+
+ textCopyAction.updateEnabledState();
+}
+/**
+ * Set the default <code>IAction</code> handler for the Cut
+ * action. This <code>IAction</code> is run only if no active
+ * inline text control.
+ *
+ * @param action the <code>IAction</code> to run for the
+ * Cut action, or <code>null</null> if not interested.
+ */
+public void setCutAction(IAction action) {
+ if (cutAction == action)
+ return;
+
+ if (cutAction != null)
+ cutAction.removePropertyChangeListener(cutActionListener);
+
+ cutAction = action;
+
+ if (cutAction != null)
+ cutAction.addPropertyChangeListener(cutActionListener);
+
+ textCutAction.updateEnabledState();
+}
+/**
+ * Set the default <code>IAction</code> handler for the Paste
+ * action. This <code>IAction</code> is run only if no active
+ * inline text control.
+ *
+ * @param action the <code>IAction</code> to run for the
+ * Paste action, or <code>null</null> if not interested.
+ */
+public void setPasteAction(IAction action) {
+ if (pasteAction == action)
+ return;
+
+ if (pasteAction != null)
+ pasteAction.removePropertyChangeListener(pasteActionListener);
+
+ pasteAction = action;
+
+ if (pasteAction != null)
+ pasteAction.addPropertyChangeListener(pasteActionListener);
+
+ textPasteAction.updateEnabledState();
+}
+/**
+ * Set the default <code>IAction</code> handler for the Select All
+ * action. This <code>IAction</code> is run only if no active
+ * inline text control.
+ *
+ * @param action the <code>IAction</code> to run for the
+ * Select All action, or <code>null</null> if not interested.
+ */
+public void setSelectAllAction(IAction action) {
+ if (selectAllAction == action)
+ return;
+
+ if (selectAllAction != null)
+ selectAllAction.removePropertyChangeListener(selectAllActionListener);
+
+ selectAllAction = action;
+
+ if (selectAllAction != null)
+ selectAllAction.addPropertyChangeListener(selectAllActionListener);
+
+ textSelectAllAction.updateEnabledState();
+}
+/**
+ * Set the default <code>IAction</code> handler for the Delete
+ * action. This <code>IAction</code> is run only if no active
+ * inline text control.
+ *
+ * @param action the <code>IAction</code> to run for the
+ * Delete action, or <code>null</null> if not interested.
+ */
+public void setDeleteAction(IAction action) {
+ if (deleteAction == action)
+ return;
+
+ if (deleteAction != null)
+ deleteAction.removePropertyChangeListener(deleteActionListener);
+
+ deleteAction = action;
+
+ if (deleteAction != null)
+ deleteAction.addPropertyChangeListener(deleteActionListener);
+
+ textDeleteAction.updateEnabledState();
+}
+/**
+ * Update the enable state of the Cut, Copy,
+ * Paste, Delete, and Select All action handlers
+ */
+private void updateActionsEnableState() {
+ textCutAction.updateEnabledState();
+ textCopyAction.updateEnabledState();
+ textPasteAction.updateEnabledState();
+ textSelectAllAction.updateEnabledState();
+ textDeleteAction.updateEnabledState();
+}
+}