*** empty log message ***
authorjsurfer <jsurfer>
Thu, 2 Sep 2004 18:28:05 +0000 (18:28 +0000)
committerjsurfer <jsurfer>
Thu, 2 Sep 2004 18:28:05 +0000 (18:28 +0000)
56 files changed:
net.sourceforge.phpeclipse.xml.ui/.classpath [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/.cvsignore [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/.project [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/build.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/icons/basic/obj16/htmledit.gif [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/icons/basic/obj16/xml.png [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/icons/element_obj.gif [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/plugin.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/plugin.xml [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/XMLPlugin.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/XMLPluginResources.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/DTDMergeViewer.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/DTDMergeViewerCreator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/XMLMergeViewer.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/XMLMergeViewerCreator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/DTDEditor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLDocumentProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLDocumentSetupParticipant.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditor.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditorMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditorMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlineContentProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlineLabelProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlinePage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/XMLPreferenceInitializer.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/XMLSyntaxPreferencePage.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/preview.xml [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AbstractDocumentProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AnnotationAdapter.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AttValueDoubleClickStrategy.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DTDConfiguration.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DTDDocumentProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DeclScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/EntityRule.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/NameDetector.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/NmtokenDetector.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/SimpleDoubleClickStrategy.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/SingleTokenScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/TagDoubleClickStrategy.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/TextScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/WhitespaceDetector.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotation.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotationHover.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotationIterator.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLCDATAScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLConfiguration.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLPartitionScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLReconcileStep.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLReconcilingStrategy.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTagRule.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTagScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTextHover.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLWordFinder.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/text/DTDTextTools.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/text/IXMLSyntaxConstants.java [new file with mode: 0644]
net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/text/XMLTextTools.java [new file with mode: 0644]

diff --git a/net.sourceforge.phpeclipse.xml.ui/.classpath b/net.sourceforge.phpeclipse.xml.ui/.classpath
new file mode 100644 (file)
index 0000000..275b34c
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" path="src/"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/net.sourceforge.phpeclipse.xml.ui/.cvsignore b/net.sourceforge.phpeclipse.xml.ui/.cvsignore
new file mode 100644 (file)
index 0000000..b0f6f7c
--- /dev/null
@@ -0,0 +1,5 @@
+bin
+build.xml
+xmlui.jar
+xmluisrc.zip
+net.sf.solareclipse.*
diff --git a/net.sourceforge.phpeclipse.xml.ui/.project b/net.sourceforge.phpeclipse.xml.ui/.project
new file mode 100644 (file)
index 0000000..5351da1
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>net.sourceforge.phpeclipse.xml.ui</name>
+       <comment></comment>
+       <projects>
+               <project>net.sf.wdte.core</project>
+               <project>net.sf.wdte.ui</project>
+               <project>net.sf.wdte.xml.core</project>
+       </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.jdt.core.javanature</nature>
+               <nature>org.eclipse.pde.PluginNature</nature>
+       </natures>
+</projectDescription>
diff --git a/net.sourceforge.phpeclipse.xml.ui/build.properties b/net.sourceforge.phpeclipse.xml.ui/build.properties
new file mode 100644 (file)
index 0000000..6a9fa87
--- /dev/null
@@ -0,0 +1,2 @@
+bin.includes = plugin.xml, icons/
+source.xmlui.jar = src/
diff --git a/net.sourceforge.phpeclipse.xml.ui/icons/basic/obj16/htmledit.gif b/net.sourceforge.phpeclipse.xml.ui/icons/basic/obj16/htmledit.gif
new file mode 100644 (file)
index 0000000..5dae869
Binary files /dev/null and b/net.sourceforge.phpeclipse.xml.ui/icons/basic/obj16/htmledit.gif differ
diff --git a/net.sourceforge.phpeclipse.xml.ui/icons/basic/obj16/xml.png b/net.sourceforge.phpeclipse.xml.ui/icons/basic/obj16/xml.png
new file mode 100644 (file)
index 0000000..ec16b48
Binary files /dev/null and b/net.sourceforge.phpeclipse.xml.ui/icons/basic/obj16/xml.png differ
diff --git a/net.sourceforge.phpeclipse.xml.ui/icons/element_obj.gif b/net.sourceforge.phpeclipse.xml.ui/icons/element_obj.gif
new file mode 100644 (file)
index 0000000..dcf0083
Binary files /dev/null and b/net.sourceforge.phpeclipse.xml.ui/icons/element_obj.gif differ
diff --git a/net.sourceforge.phpeclipse.xml.ui/plugin.properties b/net.sourceforge.phpeclipse.xml.ui/plugin.properties
new file mode 100644 (file)
index 0000000..26ec48e
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2004 Christopher Lenz 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:
+#     Christopher Lenz - initial english resources
+# 
+# $Id: plugin.properties,v 1.1 2004-09-02 18:28:04 jsurfer Exp $
+#
+
+pluginName = Web Development Tools XML UI
+providerName= WDTE Project
+
+xmlEditorName = XML Editor
+dtdEditorName = DTD Editor
+
+xmlEditorPreferencePageName = HTML/XML Editor
+
+templates.xml.contextType.name = XML Context
+templates.html.contextType.name = HTML Context
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.xml.ui/plugin.xml b/net.sourceforge.phpeclipse.xml.ui/plugin.xml
new file mode 100644 (file)
index 0000000..2e8c52e
--- /dev/null
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin
+   id="net.sourceforge.phpeclipse.xml.ui"
+   name="%pluginName"
+   version="0.0.1"
+   provider-name="%providerName"
+   class="net.sourceforge.phpeclipse.xml.ui.XMLPlugin">
+
+   <runtime>
+      <library name="xmlui.jar">
+         <export name="*"/>
+      </library>
+   </runtime>
+   <requires>
+      <import plugin="net.sourceforge.phpeclipse.core"/>
+      <import plugin="net.sourceforge.phpeclipse.xml.core"/>
+      <import plugin="net.sourceforge.phpeclipse.ui"/>
+      <import plugin="org.eclipse.compare"/>
+      <import plugin="org.eclipse.core.filebuffers"/>
+      <import plugin="org.eclipse.core.resources"/>
+      <import plugin="org.eclipse.core.runtime"/>
+      <import plugin="org.eclipse.jface.text"/>
+      <import plugin="org.eclipse.osgi"/>
+      <import plugin="org.eclipse.ui"/>
+      <import plugin="org.eclipse.ui.editors"/>
+      <import plugin="org.eclipse.ui.ide"/>
+      <import plugin="org.eclipse.ui.views"/>
+      <import plugin="org.eclipse.ui.workbench.texteditor"/>
+   </requires>
+
+
+   <extension
+         point="org.eclipse.core.runtime.preferences">
+      <initializer class="net.sourceforge.phpeclipse.xml.ui.internal.preferences.XMLPreferenceInitializer"/>
+   </extension>
+   <extension
+         point="org.eclipse.ui.preferencePages">
+      <page
+            name="%xmlEditorPreferencePageName"
+            category="net.sourceforge.phpeclipse.ui.preferencePage"
+            class="net.sourceforge.phpeclipse.xml.ui.internal.preferences.XMLSyntaxPreferencePage"
+            id="net.sourceforge.phpeclipse.xml.ui.preferences.XMLSyntaxPreferencePage">
+      </page>
+   </extension>
+   <extension
+         point="org.eclipse.core.filebuffers.documentSetup">
+      <participant
+            extensions="xml,xsd"
+            class="net.sourceforge.phpeclipse.xml.ui.internal.editor.XMLDocumentSetupParticipant">
+      </participant>
+   </extension>
+   <extension
+         point="org.eclipse.ui.editors.documentProviders">
+      <provider
+            extensions="dtd"
+            class="net.sourceforge.phpeclipse.xml.ui.internal.text.DTDDocumentProvider"
+            id="net.sourceforge.phpeclipse.xml.ui.internal.text.DTDDocumentProvider">
+      </provider>
+      <provider
+            extensions="xml,xsd"
+            class="net.sourceforge.phpeclipse.xml.ui.internal.editor.XMLDocumentProvider"
+            id="net.sourceforge.phpeclipse.xml.ui.internal.editor.XMLDocumentProvider">
+      </provider>
+   </extension>
+   <extension
+         point="org.eclipse.ui.editors">
+      <editor
+            name="%dtdEditorName"
+            icon="icons/basic/obj16/xml.png"
+            extensions="dtd"
+            contributorClass="org.eclipse.ui.editors.text.TextEditorActionContributor"
+            class="net.sourceforge.phpeclipse.xml.ui.internal.editor.DTDEditor"
+            id="net.sourceforge.phpeclipse.xml.ui.internal.editor.DTDEditor">
+      </editor>
+      <editor
+            name="%xmlEditorName"
+            icon="icons/basic/obj16/xml.png"
+            extensions="xml,xsd"
+            contributorClass="org.eclipse.ui.editors.text.TextEditorActionContributor"
+            class="net.sourceforge.phpeclipse.xml.ui.internal.editor.XMLEditor"
+            id="net.sourceforge.phpeclipse.xml.ui.internal.editor.XMLEditor">
+      </editor>
+   </extension>
+   <extension
+         point="org.eclipse.compare.contentMergeViewers">
+      <viewer
+            extensions="dtd"
+            class="net.sourceforge.phpeclipse.xml.ui.internal.compare.DTDMergeViewerCreator"
+            id="net.sourceforge.phpeclipse.xml.ui.internal.compare.DTDMergeViewerCreator">
+      </viewer>
+      <viewer
+            extensions="xml,xsd"
+            class="net.sourceforge.phpeclipse.xml.ui.internal.compare.XMLMergeViewerCreator"
+            id="net.sourceforge.phpeclipse.xml.ui.internal.compare.XMLMergeViewerCreator">
+      </viewer>
+   </extension>
+   <extension
+         point="org.eclipse.team.core.fileTypes">
+      <fileTypes
+            type="text"
+            extension="dtd">
+      </fileTypes>
+      <fileTypes
+            type="text"
+            extension="xml">
+      </fileTypes>
+      <fileTypes
+            type="text"
+            extension="xsd">
+      </fileTypes>
+   </extension>
+
+</plugin>
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/XMLPlugin.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/XMLPlugin.java
new file mode 100644 (file)
index 0000000..bbbf329
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLPlugin.java,v 1.1 2004-09-02 18:28:04 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui;
+
+import java.net.URL;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import net.sourceforge.phpeclipse.xml.ui.text.DTDTextTools;
+import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+public class XMLPlugin extends AbstractUIPlugin {
+       public static final String ICON_ELEMENT = "element_obj.gif"; //$NON-NLS-1$
+       
+       // The shared instance.
+       private static XMLPlugin plugin;
+
+       // Resource bundle.
+       private ResourceBundle resources;
+
+       private XMLTextTools xmlTextTools;
+       private DTDTextTools dtdTextTools;
+
+       /**
+        * The constructor.
+        */
+       public XMLPlugin() {
+               plugin = this;
+
+               try {
+                       resources = ResourceBundle.getBundle(
+                               "net.sourceforge.phpeclipse.xml.ui.XMLPluginResources"); //$NON-NLS-1$
+               } catch (MissingResourceException x) {
+               }
+       }
+
+       /*
+        * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+        */
+       public void stop(BundleContext context) throws Exception {
+               try {
+                       if (xmlTextTools != null) {
+                               xmlTextTools.dispose();
+                               xmlTextTools = null;
+                       }
+
+                       if (dtdTextTools != null) {
+                               dtdTextTools.dispose();
+                               dtdTextTools = null;
+                       }
+               } finally {
+                       super.stop(context);
+               }
+       }
+
+       /**
+        * Returns the shared instance.
+        */
+       public static XMLPlugin 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 = XMLPlugin.getDefault().getResourceBundle();
+               try {
+                       return bundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return key;
+               }
+       }
+
+       /**
+        * Returns the plugin's resource bundle.
+        */
+       public ResourceBundle getResourceBundle() {
+               return resources;
+       }
+
+       /**
+        * Returns instance of text tools for XML.
+        */
+       public XMLTextTools getXMLTextTools() {
+               if (xmlTextTools == null) {
+                       xmlTextTools = new XMLTextTools(getPreferenceStore());
+               }
+               return xmlTextTools;
+       }
+
+       /**
+        * Returns instance of text tools for DTD.
+        */
+       public DTDTextTools getDTDTextTools() {
+               if (dtdTextTools == null) {
+                       dtdTextTools = new DTDTextTools(getPreferenceStore());
+               }
+               return dtdTextTools;
+       }
+
+       /*
+        * @see AbstractUIPlugin#initializeImageRegistry(ImageRegistry)
+        */
+       protected void initializeImageRegistry(ImageRegistry reg) {
+               reg.put(ICON_ELEMENT, getImageDescriptor(ICON_ELEMENT));
+       }
+
+       /**
+        * Returns an image descriptor for the image corresponding to the specified
+        * key (which is the name of the image file).
+        * 
+        * @param key The key of the image
+        * @return The descriptor for the requested image, or <code>null</code> if 
+        *         the image could not be found
+        */
+       private ImageDescriptor getImageDescriptor(String key) {
+               try {
+                       URL url = getBundle().getEntry("/icons/" + key); //$NON-NLS-1$
+                       return ImageDescriptor.createFromURL(url);
+               } catch (IllegalStateException e) {
+                       return null;
+               }
+       }
+       
+       
+
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/XMLPluginResources.properties b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/XMLPluginResources.properties
new file mode 100644 (file)
index 0000000..3b08588
--- /dev/null
@@ -0,0 +1,54 @@
+#
+# Copyright (c) 2003 Christopher Lenz 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:
+#     Igor Malinin - initial english resources
+# 
+# $Id: XMLPluginResources.properties,v 1.1 2004-09-02 18:28:04 jsurfer Exp $
+#
+
+####
+# XML Syntax Highlighting Preferences
+####
+
+XmlSyntaxPreferencePage.others=Others
+XmlSyntaxPreferencePage.PI=Precessing Instruction
+XmlSyntaxPreferencePage.Declaration=Declaration
+XmlSyntaxPreferencePage.Comment=Comment
+XmlSyntaxPreferencePage.Tag=Tag Name
+XmlSyntaxPreferencePage.AttName=Attribute Name
+XmlSyntaxPreferencePage.AttValue=Attribute Value
+XmlSyntaxPreferencePage.Entity=XML Entity
+XmlSyntaxPreferencePage.CDATA=CDATA Section
+XmlSyntaxPreferencePage.SmartyTag=Smarty Tag Name
+XmlSyntaxPreferencePage.Conditional=Conditional Section
+
+
+XmlSyntaxPreferencePage.description=XML Syntax Colors
+XmlSyntaxPreferencePage.backgroundColor=Background Color
+XmlSyntaxPreferencePage.systemDefault=System Default
+XmlSyntaxPreferencePage.custom=Custom
+XmlSyntaxPreferencePage.foreground=Foreground
+XmlSyntaxPreferencePage.color=Color
+XmlSyntaxPreferencePage.bold=Bold
+XmlSyntaxPreferencePage.italic=Italic
+XmlSyntaxPreferencePage.preview=Preview
+
+DTDMergeViewer.title=DTD Source Compare
+XMLMergeViewer.title=XML Source Compare
+
+## Actions ##
+
+ContentAssistProposal.label=Content Assist@Ctrl+SPACE
+ContentAssistProposal.tooltip=Content Assist
+ContentAssistProposal.image=
+ContentAssistProposal.description=Content Assist
+
+CompletionProcessor.ContextInfo.display.pattern=proposal {0} at position {1}
+CompletionProcessor.ContextInfo.value.pattern=proposal {0} valid from {1} to {2}
+CompletionProcessor.Proposal.ContextInfo.pattern={0} valid 5 characters around insertion point
+CompletionProcessor.Proposal.hoverinfo.pattern=Java keyword: {0}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/DTDMergeViewer.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/DTDMergeViewer.java
new file mode 100644 (file)
index 0000000..d20f85a
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: DTDMergeViewer.java,v 1.1 2004-09-02 18:28:05 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.compare;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.contentmergeviewer.TextMergeViewer;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.TextViewer;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.texteditor.AbstractTextEditor;
+
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.DTDConfiguration;
+import net.sourceforge.phpeclipse.xml.ui.text.DTDTextTools;
+
+/**
+ * @author Igor Malinin
+ */
+public class DTDMergeViewer extends TextMergeViewer {
+
+       /**
+        * The preference store.
+        */
+       private IPreferenceStore preferenceStore;
+
+       /**
+        * The listener for changes to the preference store. 
+        */
+       private IPropertyChangeListener propertyChangeListener;
+
+       /**
+        * The DTD text tools.
+        */
+       private DTDTextTools textTools;
+
+       /*
+        * @see TextMergeViewer#TextMergeViewer(Composite, int, CompareConfiguration)
+        */
+       public DTDMergeViewer(
+               Composite parent, int style, CompareConfiguration configuration
+       ) {
+               super(parent, style, configuration);
+       }
+
+       // TextMergeViewer Implementation ------------------------------------------
+
+       /*
+        * @see TextMergeViewer#configureTextViewer()
+        */
+       protected void configureTextViewer(TextViewer textViewer) {
+               XMLPlugin plugin = XMLPlugin.getDefault();
+
+               preferenceStore = plugin.getPreferenceStore();
+               if (preferenceStore != null) {
+                       propertyChangeListener = new IPropertyChangeListener() {
+                               public void propertyChange(PropertyChangeEvent event) {
+                                       handlePreferenceStoreChanged(event);
+                               }
+                       };
+                       preferenceStore.addPropertyChangeListener(propertyChangeListener);
+               }
+
+               textTools = plugin.getDTDTextTools();
+
+               if (textViewer instanceof SourceViewer) {
+                       SourceViewer sourceViewer = (SourceViewer) textViewer;
+                       sourceViewer.configure(new DTDConfiguration(textTools));
+               }
+
+               updateBackgroundColor();
+       }
+
+       /*
+        * @see TextMergeViewer#getDocumentPartitioner()
+        */
+       protected IDocumentPartitioner getDocumentPartitioner() {
+               return textTools.createDTDPartitioner();
+       }
+
+       /*
+        * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#getTitle()
+        */
+       public String getTitle() {
+               return XMLPlugin.getResourceString("DTDMergeViewer.title"); //$NON-NLS-1$
+       }
+
+       /*
+        * @see org.eclipse.jface.viewers.ContentViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
+        */
+       protected void handleDispose(DisposeEvent event) {
+               if (propertyChangeListener != null) {
+                       if (preferenceStore != null) {
+                               preferenceStore
+                                       .removePropertyChangeListener(propertyChangeListener);
+                       }
+
+                       propertyChangeListener = null;
+               }
+
+               super.handleDispose(event);
+       }
+
+       protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
+               String p = event.getProperty();
+
+               if (p.equals(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND) ||
+                       p.equals(AbstractTextEditor
+                               .PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)
+               ) {
+                       updateBackgroundColor();
+               } else if (textTools.affectsBehavior(event)) {
+                       invalidateTextPresentation();
+               }
+       }
+
+       private void updateBackgroundColor() {
+               boolean defaultBackgroundColor = preferenceStore.getBoolean(
+                       AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT);
+
+               if (defaultBackgroundColor) {
+                       setBackgroundColor(null);
+               } else {
+                       RGB backgroundColor = PreferenceConverter
+                               .getColor(preferenceStore,
+                                       AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND);
+                       setBackgroundColor(backgroundColor);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/DTDMergeViewerCreator.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/DTDMergeViewerCreator.java
new file mode 100644 (file)
index 0000000..6eeb9fc
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: DTDMergeViewerCreator.java,v 1.1 2004-09-02 18:28:05 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.compare;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.IViewerCreator;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * @author Igor Malinin
+ */
+public class DTDMergeViewerCreator implements IViewerCreator {
+
+       /*
+        * @see IViewerCreator#createViewer(Composite, CompareConfiguration)
+        */
+       public Viewer createViewer(Composite parent, CompareConfiguration config) {
+               return new DTDMergeViewer(parent, SWT.NULL, config);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/XMLMergeViewer.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/XMLMergeViewer.java
new file mode 100644 (file)
index 0000000..6d817c3
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLMergeViewer.java,v 1.1 2004-09-02 18:28:05 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.compare;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.contentmergeviewer.TextMergeViewer;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.TextViewer;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.texteditor.AbstractTextEditor;
+
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLConfiguration;
+import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools;
+
+/**
+ * @author Igor Malinin
+ */
+public class XMLMergeViewer extends TextMergeViewer {
+
+       /**
+        * The preference store.
+        */
+       private IPreferenceStore preferenceStore;
+
+       /**
+        * The listener for changes to the preference store.
+        */
+       private IPropertyChangeListener propertyChangeListener;
+
+       /**
+        * The XML text tools.
+        */
+       private XMLTextTools textTools;
+
+       /*
+        * @see TextMergeViewer#TextMergeViewer(Composite, int,
+        *      CompareConfiguration)
+        */
+       public XMLMergeViewer(Composite parent, int style,
+                       CompareConfiguration configuration) {
+               super(parent, style, configuration);
+       }
+
+       // TextMergeViewer Implementation
+       // ------------------------------------------
+
+       /*
+        * @see TextMergeViewer#configureTextViewer()
+        */
+       protected void configureTextViewer(TextViewer textViewer) {
+               XMLPlugin plugin = XMLPlugin.getDefault();
+
+               preferenceStore = plugin.getPreferenceStore();
+               if (preferenceStore != null) {
+                       propertyChangeListener = new IPropertyChangeListener() {
+                               public void propertyChange(PropertyChangeEvent event) {
+                                       handlePreferenceStoreChanged(event);
+                               }
+                       };
+                       preferenceStore.addPropertyChangeListener(propertyChangeListener);
+               }
+
+               textTools = plugin.getXMLTextTools();
+
+               if (textViewer instanceof SourceViewer) {
+                       SourceViewer sourceViewer = (SourceViewer) textViewer;
+                       sourceViewer.configure(new XMLConfiguration(textTools));
+               }
+
+               updateBackgroundColor();
+       }
+
+       /*
+        * @see TextMergeViewer#getDocumentPartitioner()
+        */
+       protected IDocumentPartitioner getDocumentPartitioner() {
+               return textTools.createXMLPartitioner();
+       }
+
+       /*
+        * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#getTitle()
+        */
+       public String getTitle() {
+               return XMLPlugin.getResourceString("XMLMergeViewer.title"); //$NON-NLS-1$
+       }
+
+       /*
+        * @see org.eclipse.jface.viewers.ContentViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
+        */
+       protected void handleDispose(DisposeEvent event) {
+               if (propertyChangeListener != null) {
+                       if (preferenceStore != null) {
+                               preferenceStore.removePropertyChangeListener(
+                                               propertyChangeListener);
+                       }
+
+                       propertyChangeListener = null;
+               }
+
+               super.handleDispose(event);
+       }
+
+       protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
+               String p = event.getProperty();
+
+               if (p.equals(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND)
+                || p.equals(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) {
+                       updateBackgroundColor();
+               } else if (textTools.affectsBehavior(event)) {
+                       invalidateTextPresentation();
+               }
+       }
+
+       private void updateBackgroundColor() {
+               boolean defaultBackgroundColor = preferenceStore.getBoolean(
+                               AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT);
+
+               if (defaultBackgroundColor) {
+                       setBackgroundColor(null);
+               } else {
+                       RGB backgroundColor = PreferenceConverter.getColor(preferenceStore,
+                                       AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND);
+                       setBackgroundColor(backgroundColor);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/XMLMergeViewerCreator.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/XMLMergeViewerCreator.java
new file mode 100644 (file)
index 0000000..60f84c0
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLMergeViewerCreator.java,v 1.1 2004-09-02 18:28:05 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.compare;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.IViewerCreator;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * @author Igor Malinin
+ */
+public class XMLMergeViewerCreator implements IViewerCreator {
+
+       /*
+        * @see IViewerCreator#createViewer(Composite, CompareConfiguration)
+        */
+       public Viewer createViewer(Composite parent, CompareConfiguration config) {
+               return new XMLMergeViewer(parent, SWT.NULL, config);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/DTDEditor.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/DTDEditor.java
new file mode 100644 (file)
index 0000000..e5de102
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: DTDEditor.java,v 1.1 2004-09-02 18:28:04 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.editor;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.ui.editors.text.TextEditor;
+import org.eclipse.ui.texteditor.ContentAssistAction;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.DTDConfiguration;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.DTDDocumentProvider;
+import net.sourceforge.phpeclipse.xml.ui.text.DTDTextTools;
+
+
+/**
+ * DTD Editor.
+ * 
+ * @author Igor Malinin
+ */
+public class DTDEditor extends TextEditor {
+
+       public DTDEditor() {
+               setPreferenceStore(XMLPlugin.getDefault().getPreferenceStore());
+       }
+
+       /*
+        * @see org.eclipse.ui.editors.text.TextEditor#initializeEditor()
+        */
+       protected void initializeEditor() {
+               super.initializeEditor();
+
+               DTDTextTools dtdTextTools = XMLPlugin.getDefault().getDTDTextTools();
+
+               setSourceViewerConfiguration(new DTDConfiguration(dtdTextTools));
+
+               setDocumentProvider(new DTDDocumentProvider());
+       }
+
+       protected boolean affectsTextPresentation(PropertyChangeEvent event) {
+               return XMLPlugin.getDefault().getDTDTextTools().affectsBehavior(event);
+       }
+       protected void createActions() {
+               super.createActions();
+
+               IAction action = new ContentAssistAction(XMLEditorMessages.getResourceBundle(),
+               "ContentAssistProposal.", this); //$NON-NLS-1$
+           action
+               .setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+           setAction("ContentAssistProposal", action); //$NON-NLS-1$
+           markAsStateDependentAction("ContentAssistProposal", true); //$NON-NLS-1$
+           
+//             IAction action= new TextOperationAction(
+//                             TemplateMessages.getResourceBundle(),
+//                             "Editor." + TEMPLATE_PROPOSALS + ".", //$NON-NLS-1$ //$NON-NLS-2$
+//                             this,
+//                             ISourceViewer.CONTENTASSIST_PROPOSALS);
+//             action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+//             setAction(TEMPLATE_PROPOSALS, action);
+//             markAsStateDependentAction(TEMPLATE_PROPOSALS, true);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLDocumentProvider.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLDocumentProvider.java
new file mode 100644 (file)
index 0000000..73c9c3f
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz 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:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: XMLDocumentProvider.java,v 1.1 2004-09-02 18:28:04 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.editor;
+
+import java.net.MalformedURLException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.ui.editors.text.TextFileDocumentProvider;
+
+import net.sourceforge.phpeclipse.xml.core.internal.model.XMLDocument;
+import net.sourceforge.phpeclipse.xml.core.model.IXMLDocument;
+
+
+/**
+ * Document provider for XML files.
+ * 
+ * TODO Merge the encoding detection support from I18NDocumentProvider and
+ *      AbstractDocumentProvider into this class
+ * 
+ * TODO This class currently doubles as a model manager which will need to be 
+ *      moved into core at some point, and would make this class pretty much
+ *      useless
+ */
+public class XMLDocumentProvider extends TextFileDocumentProvider {
+
+       // Inner Classes -----------------------------------------------------------
+
+       private class XMLFileInfo extends FileInfo {
+               IXMLDocument xmlDocument;
+       }
+
+       // TestFileDocumentProvider Implementation ---------------------------------
+
+       /*
+        * @see TextFileDocumentProvider#createEmptyFileInfo()
+        */
+       protected FileInfo createEmptyFileInfo() {
+               return new XMLFileInfo();
+       }
+
+       /*
+        * @see TextFileDocumentProvider#createFileInfo(Object)
+        */
+       protected FileInfo createFileInfo(Object element) throws CoreException {
+               FileInfo fileInfo = super.createFileInfo(element);
+               if (!(fileInfo instanceof XMLFileInfo)) {
+                       return null;
+               }
+
+               IDocument document = fileInfo.fTextFileBuffer.getDocument();
+
+               String systemId = null;
+               try {
+                       systemId = getSystemFile(fileInfo).toURL().toString();
+               } catch (MalformedURLException e) {
+               }
+
+               IXMLDocument xmlDocument = createModel(document, systemId);
+               if (xmlDocument instanceof IDocumentListener) {
+                       document.addDocumentListener((IDocumentListener) xmlDocument);
+               }
+
+               XMLFileInfo xmlFileInfo = (XMLFileInfo) fileInfo;
+               xmlFileInfo.xmlDocument = xmlDocument;
+
+               return xmlFileInfo;
+       }
+
+       /*
+        * @see TextFileDocumentProvider#disposeFileInfo(Object, TextFileDocumentProvider.FileInfo)
+        */
+       protected void disposeFileInfo(Object element, FileInfo info) {
+               if (info instanceof XMLFileInfo) {
+                       IDocument document = getDocument(element);
+                       if (document != null) {
+                               IXMLDocument xmlDocument = ((XMLFileInfo) info).xmlDocument;
+                               if (xmlDocument instanceof IDocumentListener) {
+                                       document.removeDocumentListener(
+                                                       (IDocumentListener) xmlDocument);
+                               }
+                       }
+               }
+
+               super.disposeFileInfo(element, info);
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Creates the XML document model object corresponding to the specified 
+        * document.
+        * 
+        * @param document the document to parse
+        * @param systemId the system ID of the document
+        * @return the document model object
+        */
+       public IXMLDocument createModel(IDocument document, String systemId) {
+               return new XMLDocument(document, systemId);
+       }
+
+       /**
+        * Returns the XML document model associated with the specified element.
+        * 
+        * @param element the element
+        * @return the document model associated with the element
+        */
+       public IXMLDocument getModel(Object element) {
+               FileInfo info = getFileInfo(element);
+               if (info instanceof XMLFileInfo) {
+                       XMLFileInfo xmlFileInfo = (XMLFileInfo) info;
+                       return xmlFileInfo.xmlDocument;
+               }
+
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLDocumentSetupParticipant.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLDocumentSetupParticipant.java
new file mode 100644 (file)
index 0000000..c7cac74
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz 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:
+ *     Christopher Lenz - initial implementation
+ * 
+ * $Id: XMLDocumentSetupParticipant.java,v 1.1 2004-09-02 18:28:04 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.editor;
+
+import org.eclipse.core.filebuffers.IDocumentSetupParticipant;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools;
+
+/**
+ * Document setup participant that sets up the CSS specific partitioning.
+ */
+public class XMLDocumentSetupParticipant implements IDocumentSetupParticipant {
+
+       /* 
+        * @see IDocumentSetupParticipant#setup(IDocument)
+        */
+       public void setup(IDocument document) {
+               if (document != null) {
+                       XMLTextTools tools = XMLPlugin.getDefault().getXMLTextTools();
+                       IDocumentPartitioner partitioner = tools.createXMLPartitioner();
+                       partitioner.connect(document);
+                       document.setDocumentPartitioner(partitioner);
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditor.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditor.java
new file mode 100644 (file)
index 0000000..931ea8b
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *     Christopher Lenz - integrated outline page
+ *
+ * $Id: XMLEditor.java,v 1.1 2004-09-02 18:28:04 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.editor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.ui.text.IReconcilingParticipant;
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+import net.sourceforge.phpeclipse.xml.ui.internal.outline.XMLOutlinePage;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLConfiguration;
+import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.editors.text.EditorsUI;
+import org.eclipse.ui.editors.text.TextEditor;
+import org.eclipse.ui.texteditor.ChainedPreferenceStore;
+import org.eclipse.ui.texteditor.ContentAssistAction;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+
+/**
+ * XML Editor.
+ * 
+ * @author Igor Malinin
+ */
+public class XMLEditor extends TextEditor implements IReconcilingParticipant {
+
+    /**
+     * Listens to changes to the selection in the outline page, and changes the
+     * selection and highlight range in the editor accordingly.
+     */
+    private class OutlineSelectionChangedListener
+        implements ISelectionChangedListener {
+
+        /*
+         * @see ISelectionChangedListener#selectionChanged(SelectionChangedEvent)
+         */
+        public void selectionChanged(SelectionChangedEvent event) {
+            IStructuredSelection selection =
+                (IStructuredSelection) event.getSelection();
+            if (selection.isEmpty()) {
+                resetHighlightRange();
+            } else {
+                ISourceReference element = (ISourceReference)
+                                       selection.getFirstElement();
+                highlightElement(element, true);
+            }
+        }
+
+    }
+
+    /**
+     * The associated outline page.
+     */
+       XMLOutlinePage outlinePage;
+
+    /**
+     * Listens to changes in the outline page's selection to update the editor
+     * selection and highlight range.
+     */
+    private ISelectionChangedListener outlineSelectionChangedListener;
+
+    /**
+     * Constructor.
+     */
+       public XMLEditor() {
+               List stores = new ArrayList(3);
+
+               stores.add(XMLPlugin.getDefault().getPreferenceStore());
+               stores.add(EditorsUI.getPreferenceStore());
+
+               setPreferenceStore(
+                       new ChainedPreferenceStore(
+                               (IPreferenceStore[]) stores
+                                       .toArray(new IPreferenceStore[stores.size()])));
+       }
+
+       /*
+        * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+        */
+       public Object getAdapter(Class adapter) {
+               if (adapter.equals(IContentOutlinePage.class)) {
+                       if (outlinePage == null) {
+                               outlinePage = new XMLOutlinePage(this);
+                outlineSelectionChangedListener =
+                    new OutlineSelectionChangedListener();
+                outlinePage.addSelectionChangedListener(
+                outlineSelectionChangedListener);
+                       }
+
+                       return outlinePage;
+               }
+
+               return super.getAdapter(adapter);
+       }
+
+       /* 
+        * @see IReconcilingParticipant#reconciled()
+        */
+       public void reconciled() {
+               Shell shell = getSite().getShell();
+               if ((shell != null) && !shell.isDisposed()) {
+                       shell.getDisplay().asyncExec(new Runnable() {
+                               public void run() {
+                                       if (outlinePage != null) {
+                                               outlinePage.update();
+                                       }
+                               }
+                       });
+               }
+       }
+
+       /*
+        * @see org.eclipse.ui.editors.text.TextEditor#initializeEditor()
+        */
+       protected void initializeEditor() {
+               super.initializeEditor();
+
+               XMLTextTools xmlTextTools = XMLPlugin.getDefault().getXMLTextTools();
+               setSourceViewerConfiguration(new XMLConfiguration(xmlTextTools, this));
+               setDocumentProvider(new XMLDocumentProvider());
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractTextEditor#affectsTextPresentation(PropertyChangeEvent)
+        */
+       protected boolean affectsTextPresentation(PropertyChangeEvent event) {
+               return XMLPlugin.getDefault().getXMLTextTools().affectsBehavior(event);
+       }
+
+    void highlightElement(ISourceReference element,
+               boolean moveCursor) {
+        if (element != null) {
+            IRegion highlightRegion = element.getSourceRegion();
+            setHighlightRange(highlightRegion.getOffset(),
+                highlightRegion.getLength(), moveCursor);
+        } else {
+            resetHighlightRange();
+        }
+    }
+    
+    protected void createActions() {
+               super.createActions();
+
+               IAction action = new ContentAssistAction(XMLEditorMessages.getResourceBundle(),
+               "ContentAssistProposal.", this); //$NON-NLS-1$
+           action
+               .setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+           setAction("ContentAssistProposal", action); //$NON-NLS-1$
+           markAsStateDependentAction("ContentAssistProposal", true); //$NON-NLS-1$
+           
+//             IAction action= new TextOperationAction(
+//                             TemplateMessages.getResourceBundle(),
+//                             "Editor." + TEMPLATE_PROPOSALS + ".", //$NON-NLS-1$ //$NON-NLS-2$
+//                             this,
+//                             ISourceViewer.CONTENTASSIST_PROPOSALS);
+//             action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+//             setAction(TEMPLATE_PROPOSALS, action);
+//             markAsStateDependentAction(TEMPLATE_PROPOSALS, true);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditorMessages.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditorMessages.java
new file mode 100644 (file)
index 0000000..1af6716
--- /dev/null
@@ -0,0 +1,45 @@
+/**********************************************************************
+Copyright (c) 2000, 2002 IBM Corp. 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 implementation
+    Klaus Hartlage - www.eclipseproject.de
+**********************************************************************/
+package net.sourceforge.phpeclipse.xml.ui.internal.editor;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class XMLEditorMessages {
+
+       private static final String RESOURCE_BUNDLE= "net.sourceforge.phpeclipse.xml.ui.internal.editor.XMLEditorMessages";//$NON-NLS-1$
+
+       private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+       private XMLEditorMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+               }
+       }
+       
+       /**
+        * Gets a string from the resource bundle and formats it with arguments
+        */     
+       public static String getFormattedString(String key, Object[] args) {
+               return MessageFormat.format(getString(key), args);
+       }
+       
+       public static ResourceBundle getResourceBundle() {
+               return fgResourceBundle;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditorMessages.properties b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditorMessages.properties
new file mode 100644 (file)
index 0000000..bea66ef
--- /dev/null
@@ -0,0 +1,10 @@
+#############################################################
+#
+# (c) Copyright IBM Corp. 2000, 2001.
+# All Rights Reserved.
+#
+#############################################################
+ContentAssistProposal.label=Content Assist@Ctrl+SPACE
+ContentAssistProposal.tooltip=Content Assist
+ContentAssistProposal.image=
+ContentAssistProposal.description=Content Assist
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlineContentProvider.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlineContentProvider.java
new file mode 100644 (file)
index 0000000..9096ce6
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz 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:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: XMLOutlineContentProvider.java,v 1.1 2004-09-02 18:28:05 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.outline;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+import net.sourceforge.phpeclipse.xml.core.model.IXMLDocument;
+import net.sourceforge.phpeclipse.xml.core.model.IXMLElement;
+
+/**
+ * Content provider for the XML outline page.
+ */
+public class XMLOutlineContentProvider implements ITreeContentProvider {
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The parsed XML document.
+        */
+       private IXMLDocument document;
+
+       // ITreeContentProvider Implementation -------------------------------------
+
+       /*
+        * ITreeContentProvider#getChildren(Object)
+        */
+       public Object[] getChildren(Object parentElement) {
+               if (parentElement instanceof IXMLElement) {
+                       return ((IXMLElement) parentElement).getChildren();
+               }
+               return new Object[0];
+       }
+
+       /*
+        * @see ITreeContentProvider#getParent(Object)
+        */
+       public Object getParent(Object element) {
+               if (element instanceof IXMLElement) {
+                       return ((IXMLElement) element).getParent();
+               }
+               return null;
+       }
+
+       /*
+        * @see ITreeContentProvider#hasChildren(Object)
+        */
+       public boolean hasChildren(Object element) {
+               return getChildren(element).length > 0;
+       }
+
+       /*
+        * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(Object)
+        */
+       public Object[] getElements(Object inputElement) {
+               if ((document != null) && (document.getRoot() != null)) {
+                       return new Object[] { document.getRoot() };
+               }
+               return new Object[0];
+       }
+
+       /*
+        * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+        */
+       public void dispose() {
+               document = null;
+       }
+
+       /*
+        * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(Viewer, Object, Object)
+        */
+       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+               if (oldInput != newInput) {
+                       if (oldInput instanceof IXMLDocument) {
+                               document = null;
+                       }
+                       if (newInput instanceof IXMLDocument) {
+                               document = (IXMLDocument) newInput;
+                       }          
+               }
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlineLabelProvider.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlineLabelProvider.java
new file mode 100644 (file)
index 0000000..29c3d7a
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz 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:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: XMLOutlineLabelProvider.java,v 1.1 2004-09-02 18:28:05 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.outline;
+
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+import net.sourceforge.phpeclipse.xml.core.model.IXMLElement;
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+
+/**
+ * Label provider for the XML outline page.
+ */
+public class XMLOutlineLabelProvider extends LabelProvider {
+
+       // LabelProvider Implementation --------------------------------------------
+
+       /**
+        * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
+        */
+       public Image getImage(Object element) {
+               if (element instanceof IXMLElement) {
+                       return XMLPlugin.getDefault().getImageRegistry().get(
+                               XMLPlugin.ICON_ELEMENT);
+               }
+               return null;
+       }
+
+       /**
+        * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
+        */
+       public String getText(Object element) {
+               if (element instanceof IXMLElement) {
+                       IXMLElement xmlElement = (IXMLElement) element;
+                       StringBuffer buf = new StringBuffer();
+                       if (xmlElement.getPrefix() != null) {
+                               buf.append(xmlElement.getPrefix());
+                               buf.append(':');
+                       }
+                       buf.append(xmlElement.getLocalName());
+                       return buf.toString();
+               }
+               return null;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlinePage.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlinePage.java
new file mode 100644 (file)
index 0000000..a07f25a
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz 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:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: XMLOutlinePage.java,v 1.1 2004-09-02 18:28:05 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.outline;
+
+import java.util.List;
+
+import org.eclipse.jface.viewers.DecoratingLabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.ui.views.outline.ProblemsLabelDecorator;
+import net.sourceforge.phpeclipse.xml.core.model.IXMLDocument;
+import net.sourceforge.phpeclipse.xml.ui.internal.editor.XMLDocumentProvider;
+import net.sourceforge.phpeclipse.xml.ui.internal.editor.XMLEditor;
+
+/**
+ * Implements the outline page associated with the XML editor.
+ */
+public class XMLOutlinePage extends ContentOutlinePage {
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The associated editor.
+        */
+       private XMLEditor editor;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param editor The associated text editor
+        */
+       public XMLOutlinePage(XMLEditor editor) {
+               this.editor = editor;
+       }
+
+       // ContentOutlinePage Implementation ---------------------------------------
+
+       /*
+        * @see org.eclipse.ui.part.IPage#createControl(Composite)
+        */
+       public void createControl(Composite parent) {
+               super.createControl(parent);
+               TreeViewer viewer = getTreeViewer();
+               viewer.setContentProvider(new XMLOutlineContentProvider());
+               viewer.setLabelProvider(new DecoratingLabelProvider(
+                               new XMLOutlineLabelProvider(),
+                               new ProblemsLabelDecorator(editor)));
+               viewer.setInput(getDocument());
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Selects a specific element in the outline page.
+        * 
+        * @param element the element to select
+        */
+       public void select(ISourceReference element) {
+               TreeViewer viewer = getTreeViewer();
+               if (viewer != null) {
+                       ISelection selection = viewer.getSelection();
+                       if (selection instanceof IStructuredSelection) {
+                               IStructuredSelection structuredSelection =
+                                       (IStructuredSelection) selection;
+                               List elements = structuredSelection.toList();
+                               if (!elements.contains(element)) {
+                                       if (element == null) {
+                                               selection = StructuredSelection.EMPTY;
+                                       } else {
+                                               selection = new StructuredSelection(element);
+                                       }
+                                       viewer.setSelection(selection, true);
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Updates the outline page.
+        */
+       public void update() {
+               IXMLDocument document = getDocument();
+               if (document != null) {
+                       TreeViewer viewer = getTreeViewer();
+                       if (viewer != null) {
+                               Control control = viewer.getControl();
+                               if ((control != null) && !control.isDisposed()) {
+                                       control.setRedraw(false);
+                                       viewer.setInput(document);
+                                       viewer.expandAll();
+                                       control.setRedraw(true);
+                               }
+                       }
+               }
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       /**
+        * Returns the parsed model of the XML document that is loaded into the 
+        * associated editor.
+        * 
+        * @return the parsed XML document
+        */
+       private IXMLDocument getDocument() {
+               IDocumentProvider provider = editor.getDocumentProvider();
+               if (provider instanceof XMLDocumentProvider) {
+                       XMLDocumentProvider xmlProvider = (XMLDocumentProvider) provider;
+                       return xmlProvider.getModel(editor.getEditorInput());
+               }
+               return null;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/XMLPreferenceInitializer.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/XMLPreferenceInitializer.java
new file mode 100644 (file)
index 0000000..b1186e7
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2002-2004 Roberto Gonzalez Rocha 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:
+ *     Roberto Gonzalez Rocha - Initial version
+ *     Igor Malinin - refactoring, minor changes
+ *
+ * $Id: XMLPreferenceInitializer.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+package net.sourceforge.phpeclipse.xml.ui.internal.preferences;
+
+import net.sourceforge.phpeclipse.ui.preferences.ITextStylePreferences;
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+import net.sourceforge.phpeclipse.xml.ui.text.IXMLSyntaxConstants;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.texteditor.AbstractTextEditor;
+
+
+/**
+ * @author Igor Malinin
+ */
+public class XMLPreferenceInitializer extends AbstractPreferenceInitializer {
+       /*
+        * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+        */
+       public void initializeDefaultPreferences() {
+               IPreferenceStore store = XMLPlugin.getDefault().getPreferenceStore();
+
+               // TODO: ChainedPreferenceStore does not work for preferences preview
+
+               PreferenceConverter.setDefault(store,
+                       AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND,
+                       Display.getDefault()
+                               .getSystemColor(SWT.COLOR_LIST_FOREGROUND).getRGB());
+
+               store.setDefault(
+                       AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT,
+                       true);
+
+               PreferenceConverter.setDefault(store,
+                       AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND,
+                       Display.getDefault()
+                               .getSystemColor(SWT.COLOR_LIST_BACKGROUND).getRGB());
+
+               store.setDefault(
+                       AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT,
+                       true);
+
+               // end of common preferences
+
+               setDefault(store, IXMLSyntaxConstants.XML_DEFAULT,
+                       "0,0,0", ITextStylePreferences.STYLE_NORMAL);
+
+               setDefault(store, IXMLSyntaxConstants.XML_TAG,
+                       "127,0,127", ITextStylePreferences.STYLE_NORMAL);
+
+               setDefault(store, IXMLSyntaxConstants.XML_ATT_NAME,
+                       "0,127,0", ITextStylePreferences.STYLE_NORMAL);
+
+               setDefault(store, IXMLSyntaxConstants.XML_ATT_VALUE,
+                       "0,0,255", ITextStylePreferences.STYLE_NORMAL);
+
+               setDefault(store, IXMLSyntaxConstants.XML_ENTITY,
+                       "127,127,0", ITextStylePreferences.STYLE_NORMAL);
+
+               setDefault(store, IXMLSyntaxConstants.XML_CDATA,
+                       "127,127,0", ITextStylePreferences.STYLE_NORMAL);
+
+               setDefault(store, IXMLSyntaxConstants.XML_PI,
+                       "127,127,127", ITextStylePreferences.STYLE_BOLD);
+
+               setDefault(store, IXMLSyntaxConstants.XML_COMMENT,
+                       "127,0,0", ITextStylePreferences.STYLE_NORMAL);
+
+               setDefault(store, IXMLSyntaxConstants.XML_DECL,
+                       "127,0,127", ITextStylePreferences.STYLE_BOLD);
+
+               setDefault(store, IXMLSyntaxConstants.XML_SMARTY,
+                       "255,0,127", ITextStylePreferences.STYLE_BOLD); 
+               
+               setDefault(store, IXMLSyntaxConstants.DTD_CONDITIONAL,
+                       "127,127,0", ITextStylePreferences.STYLE_BOLD);
+       }
+
+       private static void setDefault(
+               IPreferenceStore store, String constant, String color, String style
+       ) {
+               store.setDefault(constant + ITextStylePreferences.SUFFIX_FOREGROUND, color);
+               store.setDefault(constant + ITextStylePreferences.SUFFIX_STYLE, style);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/XMLSyntaxPreferencePage.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/XMLSyntaxPreferencePage.java
new file mode 100644 (file)
index 0000000..d55505a
--- /dev/null
@@ -0,0 +1,498 @@
+/*
+ * Copyright (c) 2002-2004 Roberto Gonzalez Rocha 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:
+ *     Roberto Gonzalez Rocha - Initial version
+ *     Igor Malinin - refactoring, minor changes
+ *
+ * $Id: XMLSyntaxPreferencePage.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.preferences;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewer;
+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.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+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.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.texteditor.AbstractTextEditor;
+
+import net.sourceforge.phpeclipse.ui.ColorEditor;
+import net.sourceforge.phpeclipse.ui.preferences.ITextStylePreferences;
+import net.sourceforge.phpeclipse.ui.preferences.OverlayPreferenceStore;
+import net.sourceforge.phpeclipse.ui.preferences.PreferenceDescriptor;
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLConfiguration;
+import net.sourceforge.phpeclipse.xml.ui.text.IXMLSyntaxConstants;
+import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools;
+
+/**
+ * The XMLSyntaxPreferencePage is a preference page that handles setting the colors used by the XML editors.
+ */
+public class XMLSyntaxPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+
+  public final PreferenceDescriptor[] fKeys = new PreferenceDescriptor[] {
+      new PreferenceDescriptor(PreferenceDescriptor.BOOLEAN, AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT),
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND),
+
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_DEFAULT
+          + ITextStylePreferences.SUFFIX_FOREGROUND),
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_DEFAULT + ITextStylePreferences.SUFFIX_STYLE),
+
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_TAG + ITextStylePreferences.SUFFIX_FOREGROUND),
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_TAG + ITextStylePreferences.SUFFIX_STYLE),
+
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_ATT_NAME
+          + ITextStylePreferences.SUFFIX_FOREGROUND),
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_ATT_NAME + ITextStylePreferences.SUFFIX_STYLE),
+
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_ATT_VALUE
+          + ITextStylePreferences.SUFFIX_FOREGROUND),
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_ATT_VALUE + ITextStylePreferences.SUFFIX_STYLE),
+
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_ENTITY
+          + ITextStylePreferences.SUFFIX_FOREGROUND),
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_ENTITY + ITextStylePreferences.SUFFIX_STYLE),
+
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_CDATA + ITextStylePreferences.SUFFIX_FOREGROUND),
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_CDATA + ITextStylePreferences.SUFFIX_STYLE),
+
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_PI + ITextStylePreferences.SUFFIX_FOREGROUND),
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_PI + ITextStylePreferences.SUFFIX_STYLE),
+
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_COMMENT
+          + ITextStylePreferences.SUFFIX_FOREGROUND),
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_COMMENT + ITextStylePreferences.SUFFIX_STYLE),
+
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_DECL + ITextStylePreferences.SUFFIX_FOREGROUND),
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_DECL + ITextStylePreferences.SUFFIX_STYLE),
+
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_SMARTY + ITextStylePreferences.SUFFIX_FOREGROUND),
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.XML_SMARTY + ITextStylePreferences.SUFFIX_STYLE), 
+      
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.DTD_CONDITIONAL
+          + ITextStylePreferences.SUFFIX_FOREGROUND),
+      new PreferenceDescriptor(PreferenceDescriptor.STRING, IXMLSyntaxConstants.DTD_CONDITIONAL
+          + ITextStylePreferences.SUFFIX_STYLE),};
+
+  OverlayPreferenceStore overlay;
+
+  final String[][] fSyntaxColorListModel = new String[][] { { 
+      XMLPlugin.getResourceString("XmlSyntaxPreferencePage.others"), //$NON-NLS-1$
+      IXMLSyntaxConstants.XML_DEFAULT }, { XMLPlugin.getResourceString("XmlSyntaxPreferencePage.Tag"), //$NON-NLS-1$
+      IXMLSyntaxConstants.XML_TAG }, { XMLPlugin.getResourceString("XmlSyntaxPreferencePage.AttName"), //$NON-NLS-1$
+      IXMLSyntaxConstants.XML_ATT_NAME }, { XMLPlugin.getResourceString("XmlSyntaxPreferencePage.AttValue"), //$NON-NLS-1$
+      IXMLSyntaxConstants.XML_ATT_VALUE }, { XMLPlugin.getResourceString("XmlSyntaxPreferencePage.Entity"), //$NON-NLS-1$
+      IXMLSyntaxConstants.XML_ENTITY }, { XMLPlugin.getResourceString("XmlSyntaxPreferencePage.CDATA"), //$NON-NLS-1$
+      IXMLSyntaxConstants.XML_CDATA }, { XMLPlugin.getResourceString("XmlSyntaxPreferencePage.PI"), //$NON-NLS-1$
+      IXMLSyntaxConstants.XML_PI }, { XMLPlugin.getResourceString("XmlSyntaxPreferencePage.Comment"), //$NON-NLS-1$
+      IXMLSyntaxConstants.XML_COMMENT }, { XMLPlugin.getResourceString("XmlSyntaxPreferencePage.Declaration"), //$NON-NLS-1$
+      IXMLSyntaxConstants.XML_DECL }, { XMLPlugin.getResourceString("XmlSyntaxPreferencePage.Conditional"), //$NON-NLS-1$
+      IXMLSyntaxConstants.XML_SMARTY }, { XMLPlugin.getResourceString("XmlSyntaxPreferencePage.SmartyTag"), //$NON-NLS-1$
+      IXMLSyntaxConstants.DTD_CONDITIONAL }, 
+          };
+
+  private XMLTextTools xmlTextTools;
+
+  private Color bgColor;
+
+  Button bgDefault;
+
+  Button bgCustom;
+
+  ColorEditor bgColorEditor;
+
+  List colors;
+
+  ColorEditor fgColorEditor;
+
+  Button fgBold;
+
+  SourceViewer preview;
+
+  /**
+   * Constructor for XMLSyntaxPreferencePage.
+   */
+  public XMLSyntaxPreferencePage() {
+    setDescription(XMLPlugin.getResourceString("XmlSyntaxPreferencePage.description")); //$NON-NLS-1$
+
+    setPreferenceStore(XMLPlugin.getDefault().getPreferenceStore());
+
+    overlay = new OverlayPreferenceStore(getPreferenceStore(), fKeys);
+  }
+
+  protected Control createContents(Composite parent) {
+    overlay.load();
+    overlay.start();
+
+    Composite colorComposite = new Composite(parent, SWT.NULL);
+    colorComposite.setLayout(new GridLayout());
+
+    Group backgroundComposite = new Group(colorComposite, SWT.SHADOW_ETCHED_IN);
+
+    backgroundComposite.setLayout(new RowLayout());
+    backgroundComposite.setText(XMLPlugin.getResourceString("XmlSyntaxPreferencePage.backgroundColor")); //$NON-NLS-1$
+
+    SelectionListener backgroundSelectionListener = new SelectionListener() {
+      public void widgetSelected(SelectionEvent e) {
+        boolean custom = bgCustom.getSelection();
+        bgColorEditor.getButton().setEnabled(custom);
+        overlay.setValue(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT, !custom);
+      }
+
+      public void widgetDefaultSelected(SelectionEvent e) {
+      }
+    };
+
+    bgDefault = new Button(backgroundComposite, SWT.RADIO | SWT.LEFT);
+    bgDefault.setText(XMLPlugin.getResourceString("XmlSyntaxPreferencePage.systemDefault")); //$NON-NLS-1$
+    bgDefault.addSelectionListener(backgroundSelectionListener);
+
+    bgCustom = new Button(backgroundComposite, SWT.RADIO | SWT.LEFT);
+    bgCustom.setText(XMLPlugin.getResourceString("XmlSyntaxPreferencePage.custom")); //$NON-NLS-1$
+    bgCustom.addSelectionListener(backgroundSelectionListener);
+
+    bgColorEditor = new ColorEditor(backgroundComposite);
+
+    Label label = new Label(colorComposite, SWT.LEFT);
+    label.setText(XMLPlugin.getResourceString("XmlSyntaxPreferencePage.foreground")); //$NON-NLS-1$
+    label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+    Composite editorComposite = new Composite(colorComposite, SWT.NONE);
+    GridLayout layout = new GridLayout();
+    layout.numColumns = 2;
+    layout.marginHeight = 0;
+    layout.marginWidth = 0;
+    editorComposite.setLayout(layout);
+    GridData gd = new GridData(GridData.FILL_BOTH);
+    editorComposite.setLayoutData(gd);
+
+    colors = new List(editorComposite, SWT.SINGLE | SWT.V_SCROLL | SWT.BORDER);
+    gd = new GridData(GridData.FILL_BOTH);
+    gd.heightHint = convertHeightInCharsToPixels(5);
+    colors.setLayoutData(gd);
+
+    Composite stylesComposite = new Composite(editorComposite, SWT.NONE);
+    layout = new GridLayout();
+    layout.marginHeight = 0;
+    layout.marginWidth = 0;
+    layout.numColumns = 2;
+    stylesComposite.setLayout(layout);
+    stylesComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+    label = new Label(stylesComposite, SWT.LEFT);
+    label.setText(XMLPlugin.getResourceString("XmlSyntaxPreferencePage.color")); //$NON-NLS-1$
+    gd = new GridData();
+    gd.horizontalAlignment = GridData.BEGINNING;
+    label.setLayoutData(gd);
+
+    fgColorEditor = new ColorEditor(stylesComposite);
+
+    Button fgColorButton = fgColorEditor.getButton();
+    gd = new GridData(GridData.FILL_HORIZONTAL);
+    gd.horizontalAlignment = GridData.BEGINNING;
+    fgColorButton.setLayoutData(gd);
+
+    label = new Label(stylesComposite, SWT.LEFT);
+    label.setText(XMLPlugin.getResourceString("XmlSyntaxPreferencePage.bold")); //$NON-NLS-1$
+    gd = new GridData();
+    gd.horizontalAlignment = GridData.BEGINNING;
+    label.setLayoutData(gd);
+
+    fgBold = new Button(stylesComposite, SWT.CHECK);
+    gd = new GridData(GridData.FILL_HORIZONTAL);
+    gd.horizontalAlignment = GridData.BEGINNING;
+    fgBold.setLayoutData(gd);
+
+    label = new Label(colorComposite, SWT.LEFT);
+    label.setText(XMLPlugin.getResourceString("XmlSyntaxPreferencePage.preview")); //$NON-NLS-1$
+    label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+    Control previewer = createPreviewer(colorComposite);
+    gd = new GridData(GridData.FILL_BOTH);
+    gd.widthHint = convertWidthInCharsToPixels(20);
+    gd.heightHint = convertHeightInCharsToPixels(5);
+    previewer.setLayoutData(gd);
+
+    colors.addSelectionListener(new SelectionListener() {
+
+      public void widgetDefaultSelected(SelectionEvent e) {
+      }
+
+      public void widgetSelected(SelectionEvent e) {
+        handleSyntaxColorListSelection();
+      }
+    });
+
+    bgColorEditor.getButton().addSelectionListener(new SelectionListener() {
+      public void widgetDefaultSelected(SelectionEvent e) {
+      }
+
+      public void widgetSelected(SelectionEvent e) {
+        PreferenceConverter.setValue(overlay, AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND, bgColorEditor.getColorValue());
+      }
+    });
+
+    fgColorButton.addSelectionListener(new SelectionListener() {
+      public void widgetDefaultSelected(SelectionEvent e) {
+      }
+
+      public void widgetSelected(SelectionEvent e) {
+        int i = colors.getSelectionIndex();
+
+        String key = fSyntaxColorListModel[i][1];
+
+        PreferenceConverter.setValue(overlay, key + ITextStylePreferences.SUFFIX_FOREGROUND, fgColorEditor.getColorValue());
+      }
+    });
+
+    fgBold.addSelectionListener(new SelectionListener() {
+      public void widgetDefaultSelected(SelectionEvent e) {
+      }
+
+      public void widgetSelected(SelectionEvent e) {
+        int i = colors.getSelectionIndex();
+
+        String key = fSyntaxColorListModel[i][1];
+
+        String value = (fgBold.getSelection()) ? ITextStylePreferences.STYLE_BOLD : ITextStylePreferences.STYLE_NORMAL;
+
+        overlay.setValue(key + ITextStylePreferences.SUFFIX_STYLE, value);
+      }
+    });
+
+    initialize();
+
+    return colorComposite;
+  }
+
+  private Control createPreviewer(Composite parent) {
+    xmlTextTools = new XMLTextTools(overlay); // REVISIT: DTD
+
+    preview = new SourceViewer(parent, null, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
+
+    preview.configure(new XMLConfiguration(xmlTextTools));
+    preview.getTextWidget().setFont(JFaceResources.getFontRegistry().get(JFaceResources.TEXT_FONT));
+    preview.setEditable(false);
+
+    initializeViewerColors(preview);
+
+    String content = loadPreviewContentFromFile("preview.xml"); //$NON-NLS-1$
+    IDocument document = new Document(content);
+
+    // REVISIT: DTD
+    IDocumentPartitioner partitioner = xmlTextTools.createXMLPartitioner();
+
+    partitioner.connect(document);
+    document.setDocumentPartitioner(partitioner);
+
+    preview.setDocument(document);
+
+    overlay.addPropertyChangeListener(new IPropertyChangeListener() {
+      public void propertyChange(PropertyChangeEvent event) {
+        String p = event.getProperty();
+        if (p.equals(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND)
+            || p.equals(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) {
+          initializeViewerColors(preview);
+        }
+
+        preview.invalidateTextPresentation();
+      }
+    });
+
+    return preview.getControl();
+  }
+
+  /**
+   * Initializes the given viewer's colors.
+   * 
+   * @param viewer
+   *          the viewer to be initialized
+   */
+  void initializeViewerColors(ISourceViewer viewer) {
+    if (overlay != null) {
+      StyledText styledText = viewer.getTextWidget();
+
+      // ---------- background color ----------------------
+      Color color = null;
+      if (!overlay.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) {
+        color = createColor(overlay, AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND, styledText.getDisplay());
+      }
+
+      styledText.setBackground(color);
+
+      if (bgColor != null) {
+        bgColor.dispose();
+      }
+
+      bgColor = color;
+    }
+  }
+
+  /**
+   * Creates a color from the information stored in the given preference store. Returns <code>null</code> if there is no such
+   * information available.
+   */
+  private Color createColor(IPreferenceStore store, String key, Display display) {
+    RGB rgb = null;
+
+    if (store.contains(key)) {
+      if (store.isDefault(key)) {
+        rgb = PreferenceConverter.getDefaultColor(store, key);
+      } else {
+        rgb = PreferenceConverter.getColor(store, key);
+      }
+
+      if (rgb != null) {
+        return new Color(display, rgb);
+      }
+    }
+
+    return null;
+  }
+
+  void handleSyntaxColorListSelection() {
+    int i = colors.getSelectionIndex();
+
+    String key = fSyntaxColorListModel[i][1];
+
+    RGB rgb = PreferenceConverter.getColor(overlay, key + ITextStylePreferences.SUFFIX_FOREGROUND);
+
+    fgColorEditor.setColorValue(rgb);
+
+    // REVISIT
+    fgBold.setSelection(overlay.getString(key + ITextStylePreferences.SUFFIX_STYLE).indexOf(ITextStylePreferences.STYLE_BOLD) >= 0);
+  }
+
+  private String loadPreviewContentFromFile(String filename) {
+    StringBuffer string = new StringBuffer(512);
+
+    try {
+      char[] buf = new char[512];
+      BufferedReader reader = new BufferedReader(new InputStreamReader(XMLSyntaxPreferencePage.class.getResourceAsStream(filename)));
+
+      try {
+        while (true) {
+          int n = reader.read(buf);
+          if (n < 0) {
+            break;
+          }
+
+          string.append(buf, 0, n);
+        }
+      } finally {
+        reader.close();
+      }
+    } catch (IOException e) {
+    }
+
+    return string.toString();
+  }
+
+  /**
+   *  
+   */
+  private void initialize() {
+    initializeFields();
+
+    for (int i = 0; i < fSyntaxColorListModel.length; i++) {
+      colors.add(fSyntaxColorListModel[i][0]);
+    }
+
+    colors.getDisplay().asyncExec(new Runnable() {
+
+      public void run() {
+        colors.select(0);
+        handleSyntaxColorListSelection();
+      }
+    });
+  }
+
+  private void initializeFields() {
+    RGB rgb = PreferenceConverter.getColor(overlay, AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND);
+    bgColorEditor.setColorValue(rgb);
+
+    boolean def = overlay.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT);
+    bgDefault.setSelection(def);
+    bgCustom.setSelection(!def);
+    bgColorEditor.getButton().setEnabled(!def);
+  }
+
+  /*
+   * @see IWorkbenchPreferencePage#init(IWorkbench)
+   */
+  public void init(IWorkbench workbench) {
+  }
+
+  /*
+   * @see PreferencePage#performDefaults()
+   */
+  protected void performDefaults() {
+    overlay.loadDefaults();
+    //initializeFields();
+    handleSyntaxColorListSelection();
+
+    super.performDefaults();
+
+    preview.invalidateTextPresentation();
+  }
+
+  /*
+   * @see org.eclipse.jface.preference.IPreferencePage#performOk()
+   */
+  public boolean performOk() {
+    overlay.propagate();
+    XMLPlugin.getDefault().savePluginPreferences();
+
+    return true;
+  }
+
+  /*
+   * @see org.eclipse.jface.dialogs.IDialogPage#dispose()
+   */
+  public void dispose() {
+    if (xmlTextTools != null) {
+      xmlTextTools.dispose();
+      xmlTextTools = null;
+    }
+
+    if (overlay != null) {
+      overlay.stop();
+      overlay = null;
+    }
+
+    super.dispose();
+  }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/preview.xml b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/preview.xml
new file mode 100644 (file)
index 0000000..2fc0edc
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!DOCTYPE doc SYSTEM "doc.dtd" [
+       <!ELEMENT text (#PCDATA)>
+       <!ATTLIST text
+               xml:space (preserve) #FIXED 'preserve'
+               id        ID         #IMPLIED
+       >
+]>
+
+<!-- comment -->
+
+<doc>
+       <text id="name">
+               &lt;text&gt;
+               <![CDATA[<text>]]>
+       </text>
+</doc>
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AbstractDocumentProvider.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AbstractDocumentProvider.java
new file mode 100644 (file)
index 0000000..1b3a58c
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: AbstractDocumentProvider.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.jface.text.rules.IWhitespaceDetector;
+
+import net.sourceforge.phpeclipse.ui.editor.I18NDocumentProvider;
+
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public abstract class AbstractDocumentProvider extends I18NDocumentProvider {
+       protected IWhitespaceDetector detector = new WhitespaceDetector();
+
+       /*
+        * @see org.eclipse.ui.editors.text.IStorageDocumentProvider#getDefaultEncoding()
+        */
+       public String getDefaultEncoding() {
+               return "UTF-8";
+       }
+
+       public String getDeclaredEncoding( InputStream in ) throws IOException {
+               if ( !in.markSupported() ) {
+                       in = new BufferedInputStream( in, 512 );
+               }
+
+               in.mark( 512 );
+               String encoding = super.getDeclaredEncoding( in );
+               if ( encoding != null ) {
+                       return encoding;
+               }
+
+               in.reset();
+
+               // check Prolog-Start <?xml
+               if ( !skipXMLDecl(in) ) {
+                       return null;
+               }
+
+               // detect 'encoding'
+               skipEncoding( in );
+
+               // read encoding
+               int delimiter;
+
+               while ( true ) {
+                       int ch = in.read();
+                       if ( ch < 0 ) {
+                               return null;
+                       }
+
+                       if ( detector.isWhitespace((char) ch) ) {
+                               continue;
+                       }
+
+                       if ( ch == '"' || ch == '\'' ) {
+                               delimiter = ch;
+                               break;
+                       }
+
+                       return null;
+               }
+
+               StringBuffer buf = new StringBuffer();
+
+               while ( true ) {
+                       int ch = in.read();
+                       if ( ch < 0 ) {
+                               return null;
+                       }
+
+                       if ( ch == delimiter ) {
+                               break;
+                       }
+
+                       buf.append( (char) ch );
+               }
+
+               return buf.toString();
+       }
+
+       private boolean skipXMLDecl( InputStream in ) throws IOException {
+               int ch = in.read();
+               if ( ch != '<' ) {
+                       return false;
+               }
+
+               ch = in.read();
+               if ( ch != '?' ) {
+                       return false;
+               }
+
+               ch = in.read();
+               if ( ch != 'x' ) {
+                       return false;
+               }
+
+               ch = in.read();
+               if ( ch != 'm' ) {
+                       return false;
+               }
+
+               ch = in.read();
+               if ( ch != 'l' ) {
+                       return false;
+               }
+
+               return true;
+       }
+
+       private boolean skipEncoding( InputStream in ) throws IOException {
+               int ch = in.read();
+
+               boolean whitespace = false;
+
+               while ( true ) {
+                       if ( ch < 0 ) {
+                               return false;
+                       }
+
+                       if ( detector.isWhitespace((char) ch) ) {
+                               ch = in.read();
+                               whitespace = true;
+                               continue;
+                       }
+
+                       if ( ch == '?' || ch == '<' ) {
+                               return false;
+                       }
+
+                       if ( ch != 'e' ) {
+                               ch = in.read();
+                               whitespace = false;
+                               continue;
+                       }
+
+                       if ( !whitespace ) {
+                               ch = in.read();
+                               continue;
+                       }
+
+                       if ( (ch = in.read()) == 'n' &&
+                                       (ch = in.read()) == 'c' &&
+                                       (ch = in.read()) == 'o' &&
+                                       (ch = in.read()) == 'd' &&
+                                       (ch = in.read()) == 'i' &&
+                                       (ch = in.read()) == 'n' &&
+                                       (ch = in.read()) == 'g' ) {
+                               break;
+                       }
+
+                       whitespace = false;
+               }
+
+               // '='
+               while ( true ) {
+                       ch = in.read();
+                       if ( ch < 0 ) {
+                               return false;
+                       }
+
+                       if ( detector.isWhitespace((char) ch) ) {
+                               continue;
+                       }
+
+                       if ( ch == '=' ) {
+                               break;
+                       }
+
+                       return false;
+               }
+
+               return true;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AnnotationAdapter.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AnnotationAdapter.java
new file mode 100644 (file)
index 0000000..d7f05e6
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz 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:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: AnnotationAdapter.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.reconciler.IReconcileResult;
+import org.eclipse.jface.text.source.Annotation;
+
+/**
+ * Adapts a temporary or persistent annotation to a reconcile result.
+ */
+public abstract class AnnotationAdapter implements IReconcileResult {
+
+       /**
+        * Creates and returns the annotation adapted by this adapter.
+        * 
+        * @return an annotation (can be temporary or persistent)
+        */
+       public abstract Annotation createAnnotation();
+       
+       /**
+        * The position of the annotation adapted by this adapter.
+        * 
+        * @return the position
+        */
+       public abstract Position getPosition();
+
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AttValueDoubleClickStrategy.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AttValueDoubleClickStrategy.java
new file mode 100644 (file)
index 0000000..c995f9a
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: AttValueDoubleClickStrategy.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITypedRegion;
+
+import net.sourceforge.phpeclipse.ui.text.TextDoubleClickStrategy;
+
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public class AttValueDoubleClickStrategy extends TextDoubleClickStrategy {
+       /*
+        * @see org.eclipse.jface.text.ITextDoubleClickStrategy#doubleClicked(ITextViewer)
+        */
+       public void doubleClicked(ITextViewer viewer) {
+               int offset = viewer.getSelectedRange().x;
+               if (offset < 0) {
+                       return;
+               }
+
+               try {
+                       IDocument document = viewer.getDocument();
+
+                       ITypedRegion region = document.getPartition(offset);
+
+                       int start = region.getOffset();
+                       int length = region.getLength();
+                       int end = start + length - 1;
+
+                       if (offset == start) {
+                               if (document.getChar(start) == document.getChar(end)) {
+                                       viewer.setSelectedRange(start + 1, length - 2);
+                               } else {
+                                       viewer.setSelectedRange(start + 1, length - 1);
+                               }
+
+                               return;
+                       }
+
+                       if (offset == end) {
+                               if (document.getChar(start) == document.getChar(end)) {
+                                       viewer.setSelectedRange(start + 1, length - 2);
+                                       return;
+                               }
+                       }
+
+                       super.doubleClicked(viewer);
+               } catch (BadLocationException e) {}
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DTDConfiguration.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DTDConfiguration.java
new file mode 100644 (file)
index 0000000..32bf38f
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: DTDConfiguration.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+import net.sourceforge.phpeclipse.ui.text.TextDoubleClickStrategy;
+import net.sourceforge.phpeclipse.xml.ui.text.DTDTextTools;
+
+
+/**
+ * DTD editor configuration.
+ * 
+ * @author Igor Malinin
+ */
+public class DTDConfiguration extends SourceViewerConfiguration {
+       private DTDTextTools dtdTextTools;
+
+       private ITextDoubleClickStrategy dcsDefault;
+       private ITextDoubleClickStrategy dcsSimple;
+
+       public DTDConfiguration( DTDTextTools tools ) {
+               dtdTextTools = tools;
+
+               dcsDefault = new TextDoubleClickStrategy();
+               dcsSimple = new SimpleDoubleClickStrategy();
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getDoubleClickStrategy(ISourceViewer, String)
+        */
+       public ITextDoubleClickStrategy getDoubleClickStrategy(
+               ISourceViewer sourceViewer, String contentType
+       ) {
+               if ( XMLPartitionScanner.XML_PI.equals(contentType) ) {
+                       return dcsSimple;
+               }
+
+               if ( XMLPartitionScanner.XML_COMMENT.equals(contentType) ) {
+                       return dcsSimple;
+               }
+
+               if ( XMLPartitionScanner.XML_DECL.equals(contentType) ) {
+                       return dcsSimple;
+               }
+
+               if ( XMLPartitionScanner.DTD_CONDITIONAL.equals(contentType) ) {
+                       return dcsSimple;
+               }
+
+               return dcsDefault;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getConfiguredContentTypes(ISourceViewer)
+        */
+       public String[] getConfiguredContentTypes( ISourceViewer sourceViewer ) {
+               return new String[] {
+                       IDocument.DEFAULT_CONTENT_TYPE,
+                       XMLPartitionScanner.XML_PI,
+                       XMLPartitionScanner.XML_COMMENT,
+                       XMLPartitionScanner.XML_DECL,
+                       XMLPartitionScanner.DTD_CONDITIONAL,
+               };
+       }
+
+       /*
+        * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getPresentationReconciler(ISourceViewer)
+        */
+       public IPresentationReconciler getPresentationReconciler(
+               ISourceViewer sourceViewer
+       ) {
+               PresentationReconciler reconciler = new PresentationReconciler();
+
+               DefaultDamagerRepairer dr;
+
+               dr = new DefaultDamagerRepairer( dtdTextTools.getDTDTextScanner() );
+               reconciler.setDamager( dr, IDocument.DEFAULT_CONTENT_TYPE );
+               reconciler.setRepairer( dr, IDocument.DEFAULT_CONTENT_TYPE );
+
+               reconciler.setDamager( dr, XMLPartitionScanner.XML_PI );
+               reconciler.setRepairer( dr, XMLPartitionScanner.XML_PI );
+
+               dr = new DefaultDamagerRepairer( dtdTextTools.getXMLPIScanner() );
+
+               reconciler.setDamager( dr, XMLPartitionScanner.XML_PI );
+               reconciler.setRepairer( dr, XMLPartitionScanner.XML_PI );
+
+               dr = new DefaultDamagerRepairer( dtdTextTools.getXMLCommentScanner() );
+
+               reconciler.setDamager( dr, XMLPartitionScanner.XML_COMMENT );
+               reconciler.setRepairer( dr, XMLPartitionScanner.XML_COMMENT );
+
+               dr = new DefaultDamagerRepairer( dtdTextTools.getXMLDeclScanner() );
+
+               reconciler.setDamager( dr, XMLPartitionScanner.XML_DECL );
+               reconciler.setRepairer( dr, XMLPartitionScanner.XML_DECL );
+
+               dr = new DefaultDamagerRepairer( dtdTextTools.getDTDConditionalScanner() );
+
+               reconciler.setDamager( dr, XMLPartitionScanner.DTD_CONDITIONAL );
+               reconciler.setRepairer( dr, XMLPartitionScanner.DTD_CONDITIONAL );
+
+               return reconciler;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DTDDocumentProvider.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DTDDocumentProvider.java
new file mode 100644 (file)
index 0000000..d03d456
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: DTDDocumentProvider.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+
+
+/**
+ * DTD document provider.
+ * 
+ * @author Igor Malinin
+ */
+public class DTDDocumentProvider extends AbstractDocumentProvider {
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#createDocument(Object)
+        */
+       protected IDocument createDocument( Object element ) throws CoreException {
+               IDocument document = super.createDocument( element );
+               if ( document != null ) {
+                       IDocumentPartitioner partitioner = XMLPlugin
+                               .getDefault().getDTDTextTools().createDTDPartitioner();
+
+                       if ( partitioner != null ) {
+                               partitioner.connect( document );
+                               document.setDocumentPartitioner( partitioner );
+                       }
+               }
+
+               return document;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DeclScanner.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DeclScanner.java
new file mode 100644 (file)
index 0000000..e48c100
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: DeclScanner.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.Map;
+
+import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.MultiLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WordRule;
+
+import net.sourceforge.phpeclipse.xml.ui.text.IXMLSyntaxConstants;
+
+/**
+ * @author Igor Malinin
+ */
+public class DeclScanner extends BufferedRuleBasedScanner {
+
+       /**
+        * Creates a color scanner for XML text or attribute value.
+        */
+       public DeclScanner(Map tokens) {
+               IToken decl = (Token) tokens.get(IXMLSyntaxConstants.XML_DECL);
+
+               setDefaultReturnToken(decl);
+
+               IToken markup = (Token) tokens.get(IXMLSyntaxConstants.XML_ATT_NAME);
+
+               WordRule rule = new WordRule(new NmtokenDetector(), markup);
+               rule.addWord("ATTLIST", decl);
+               rule.addWord("CDATA", decl);
+               rule.addWord("DOCTYPE", decl);
+               rule.addWord("ELEMENT", decl);
+               rule.addWord("EMPTY", decl);
+               rule.addWord("ENTITY", decl);
+               rule.addWord("FIXED", decl);
+               rule.addWord("ID", decl);
+               rule.addWord("IDREF", decl);
+               rule.addWord("IDREFS", decl);
+               rule.addWord("IMPLIED", decl);
+               rule.addWord("PCDATA", decl);
+               rule.addWord("PUBLIC", decl);
+               rule.addWord("REQUIRED", decl);
+               rule.addWord("SYSTEM", decl);
+
+               IToken string = (Token) tokens.get(IXMLSyntaxConstants.XML_ATT_VALUE);
+               IToken entity = (Token) tokens.get(IXMLSyntaxConstants.XML_ENTITY);
+
+               IRule[] rules = { rule, new MultiLineRule("\"", "\"", string),
+                               new MultiLineRule("'", "'", string),
+                               new EntityRule('%', entity),};
+
+               setRules(rules);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/EntityRule.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/EntityRule.java
new file mode 100644 (file)
index 0000000..efedb0f
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: EntityRule.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * Rule detecting XML or DTD entities.
+ * 
+ * @author Igor Malinin
+ */
+public class EntityRule implements IRule {
+
+       private static NameDetector detector = new NameDetector();
+
+       private char start;
+
+       private IToken token;
+
+       public EntityRule(char start, IToken token) {
+               this.start = start;
+               this.token = token;
+       }
+
+       public IToken evaluate(ICharacterScanner scanner) {
+               int ch = scanner.read();
+
+               if (ch == start) {
+                       ch = scanner.read();
+                       if (ch == ICharacterScanner.EOF) {
+                               scanner.unread();
+                               return token;
+                       }
+                       if (ch == ';') {
+                               return token;
+                       }
+                       if (!detector.isWordStart((char) ch)) {
+                               scanner.unread();
+                               return token;
+                       }
+
+                       while (true) {
+                               ch = scanner.read();
+                               if (ch == ICharacterScanner.EOF) {
+                                       scanner.unread();
+                                       return token;
+                               }
+                               if (ch == ';') {
+                                       return token;
+                               }
+                               if (!detector.isWordPart((char) ch)) {
+                                       scanner.unread();
+                                       return token;
+                               }
+                       }
+               }
+               scanner.unread();
+
+               return Token.UNDEFINED;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/NameDetector.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/NameDetector.java
new file mode 100644 (file)
index 0000000..e241e00
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: NameDetector.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.rules.IWordDetector;
+
+/**
+ * XML Name detector.
+ * 
+ * @author Igor Malinin
+ */
+public class NameDetector implements IWordDetector {
+
+       /**
+        * @see IWordDetector#isWordPart(char)
+        */
+       public boolean isWordPart(char ch) {
+               if (Character.isUnicodeIdentifierPart(ch)) {
+                       return true;
+               }
+               switch (ch) {
+                       case '.':
+                       case '-':
+                       case '_':
+                       case ':':
+                               return true;
+               }
+               return false;
+       }
+
+       /**
+        * @see IWordDetector#isWordStart(char)
+        */
+       public boolean isWordStart(char ch) {
+               if (Character.isUnicodeIdentifierStart(ch)) {
+                       return true;
+               }
+               switch (ch) {
+                       case '_':
+                       case ':':
+                               return true;
+               }
+               return false;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/NmtokenDetector.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/NmtokenDetector.java
new file mode 100644 (file)
index 0000000..75faf5a
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: NmtokenDetector.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.rules.IWordDetector;
+
+/**
+ * XML Nmtoken detector.
+ * 
+ * @author Igor Malinin
+ */
+public class NmtokenDetector implements IWordDetector {
+
+       /**
+        * @see IWordDetector#isWordPart(char)
+        */
+       public boolean isWordPart(char ch) {
+               if (Character.isUnicodeIdentifierPart(ch)) {
+                       return true;
+               }
+               switch (ch) {
+                       case '.':
+                       case '-':
+                       case '_':
+                       case ':':
+                               return false;
+               }
+               return false;
+       }
+
+       /**
+        * @see IWordDetector#isWordStart(char)
+        */
+       public boolean isWordStart(char ch) {
+               return isWordPart(ch);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/SimpleDoubleClickStrategy.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/SimpleDoubleClickStrategy.java
new file mode 100644 (file)
index 0000000..d57691b
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: SimpleDoubleClickStrategy.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITypedRegion;
+
+import net.sourceforge.phpeclipse.ui.text.TextDoubleClickStrategy;
+
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public class SimpleDoubleClickStrategy extends TextDoubleClickStrategy {
+       /*
+        * @see org.eclipse.jface.text.ITextDoubleClickStrategy#doubleClicked(ITextViewer)
+        */
+       public void doubleClicked( ITextViewer viewer ) {
+               int offset = viewer.getSelectedRange().x;
+               if ( offset < 0 ) {
+                       return;
+               }
+
+               try {
+                       IDocument document = viewer.getDocument();
+
+                       ITypedRegion region = document.getPartition( offset );
+
+                       int start = region.getOffset();
+                       int length = region.getLength();
+
+                       if ( offset == start ) {
+                               viewer.setSelectedRange( start, length );
+                               return;
+                       }
+
+                       int end = start + length - 1;
+
+                       if ( offset == end && document.getChar(end) == '>' ) {
+                               viewer.setSelectedRange( start, length );
+                               return;
+                       }
+
+                       super.doubleClicked( viewer );
+               } catch ( BadLocationException e ) {}
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/SingleTokenScanner.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/SingleTokenScanner.java
new file mode 100644 (file)
index 0000000..b78c796
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: SingleTokenScanner.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.Map;
+
+import org.eclipse.jface.text.rules.RuleBasedScanner;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * @author Igor Malinin
+ */
+public class SingleTokenScanner extends RuleBasedScanner {
+
+       /**
+        * Creates a single token scanner.
+        */
+       public SingleTokenScanner(Map tokens, String property) {
+               setDefaultReturnToken((Token) tokens.get(property));
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/TagDoubleClickStrategy.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/TagDoubleClickStrategy.java
new file mode 100644 (file)
index 0000000..a4d093a
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: TagDoubleClickStrategy.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITypedRegion;
+
+import net.sourceforge.phpeclipse.ui.text.TextDoubleClickStrategy;
+
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public class TagDoubleClickStrategy extends TextDoubleClickStrategy {
+       /*
+        * @see org.eclipse.jface.text.ITextDoubleClickStrategy#doubleClicked(ITextViewer)
+        */
+       public void doubleClicked( ITextViewer viewer ) {
+               int offset = viewer.getSelectedRange().x;
+               if ( offset < 0 ) {
+                       return;
+               }
+
+               try {
+                       IDocument document = viewer.getDocument();
+
+                       ITypedRegion region = document.getPartition( offset );
+
+                       int start = region.getOffset();
+
+                       if ( offset == start && document.getChar(offset) == '<' ) {
+                               region = document.getPartition( offset );
+                               offset = region.getOffset() + region.getLength();
+
+                               if ( document.getChar(offset - 1) != '>' ) {
+                                       while ( true ) {
+                                               if ( offset >= document.getLength() ) {
+                                                       break;
+                                               }
+
+                                               region = document.getPartition( offset );
+                                               offset = region.getOffset() + region.getLength();
+
+                                               if ( XMLPartitionScanner.XML_ATTRIBUTE
+                                                               .equals(region.getType()) ) {
+                                                       continue;
+                                               }
+
+                                               if ( XMLPartitionScanner.XML_TAG
+                                                               .equals(region.getType()) ) {
+                                                       if ( document.getChar(region.getOffset()) == '<' ) {
+                                                               break;
+                                                       }
+
+                                                       if ( document.getChar(offset - 1) == '>' ) {
+                                                               break;
+                                                       }
+
+                                                       continue;
+                                               }
+
+                                               offset = region.getOffset();
+                                               break;
+                                       }
+                               }
+
+                               viewer.setSelectedRange( start, offset - start );
+                               return;
+                       }
+
+                       int end = start + region.getLength();
+
+                       if ( offset == end - 1 && document.getChar(offset) == '>' ) {
+                               region = document.getPartition( offset );
+                               offset = region.getOffset();
+
+                               if ( document.getChar(offset) != '<' ) {
+                                       while ( true ) {
+                                               if ( offset <= 0 ) {
+                                                       break;
+                                               }
+
+                                               region = document.getPartition( offset - 1 );
+                                               offset = region.getOffset();
+
+                                               if ( XMLPartitionScanner.XML_ATTRIBUTE
+                                                               .equals(region.getType()) ) {
+                                                       continue;
+                                               }
+
+                                               if ( XMLPartitionScanner.XML_TAG
+                                                               .equals(region.getType()) ) {
+                                                       if ( document.getChar(offset) == '<' ) {
+                                                               break;
+                                                       }
+
+                                                       continue;
+                                               }
+
+                                               offset += region.getLength();
+                                               break;
+                                       }
+                               }
+
+                               viewer.setSelectedRange( offset, end - offset );
+                               return;
+                       }
+
+                       super.doubleClicked( viewer );
+               } catch ( BadLocationException e ) {}
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/TextScanner.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/TextScanner.java
new file mode 100644 (file)
index 0000000..60b35af
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: TextScanner.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.Map;
+
+import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+
+import net.sourceforge.phpeclipse.xml.ui.text.IXMLSyntaxConstants;
+
+/**
+ * @author Igor Malinin
+ */
+public class TextScanner extends BufferedRuleBasedScanner {
+
+       /**
+        * Creates a color scanner for XML text or attribute value.
+        */
+       public TextScanner(Map tokens, char startEntity, String defaultProperty) {
+               setDefaultReturnToken((Token) tokens.get(defaultProperty));
+
+               IToken entity = (Token) tokens.get(IXMLSyntaxConstants.XML_ENTITY);
+
+               IRule[] rules = { new EntityRule(startEntity, entity)};
+
+               setRules(rules);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/WhitespaceDetector.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/WhitespaceDetector.java
new file mode 100644 (file)
index 0000000..7591394
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: WhitespaceDetector.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.rules.IWhitespaceDetector;
+
+/**
+ * XML white-space detector.
+ * 
+ * @author Igor Malinin
+ */
+public class WhitespaceDetector implements IWhitespaceDetector {
+
+       /**
+        * @see IWhitespaceDetector#isWhitespace(char)
+        */
+       public boolean isWhitespace(char ch) {
+               switch (ch) {
+                       case 0x09:
+                       case 0x0A:
+                       case 0x0D:
+                       case 0x20:
+                               return true;
+
+                       default:
+                               return false;
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotation.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotation.java
new file mode 100644 (file)
index 0000000..153c7f7
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLAnnotation.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.source.Annotation;
+
+
+/**
+ * @author Igor Malinin
+ */
+public class XMLAnnotation extends Annotation {
+       public static final String TYPE_ERROR =
+               "org.eclipse.ui.workbench.texteditor.warning"; //$NON-NLS-1$
+       public static final String TYPE_WARNING =
+               "org.eclipse.ui.workbench.texteditor.error"; //$NON-NLS-1$
+       public static final String TYPE_INFO =
+               "org.eclipse.ui.workbench.texteditor.info"; //$NON-NLS-1$
+
+       public XMLAnnotation(String type, boolean persistent, String text) {
+               super(type, persistent, text);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotationHover.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotationHover.java
new file mode 100644 (file)
index 0000000..11d45ca
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz 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:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: XMLAnnotationHover.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.ISourceViewer;
+
+
+/**
+ * Implements simple annotation hover to show the associated messages.
+ */
+public class XMLAnnotationHover implements IAnnotationHover {
+       /*
+        * @see org.eclipse.jface.text.source.IAnnotationHover#getHoverInfo(org.eclipse.jface.text.source.ISourceViewer, int)
+        */
+       public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
+               List annotations = getAnnotationsForLine(sourceViewer, lineNumber);
+               if (annotations != null) {
+                       List messages = new ArrayList();
+
+                       Iterator e = annotations.iterator();
+                       while (e.hasNext()) {
+                               Annotation annotation = (Annotation) e.next();
+
+                               String message = annotation.getText();
+                               if (message != null) {
+                                       message = message.trim();
+                                       if (message.length() > 0) {
+                                               messages.add(message);
+                                       }
+                               }
+                       }
+
+                       if (messages.size() == 1) {
+                               return (String) messages.get(0);
+                       }
+
+                       if (messages.size() > 1) {
+                               return formatMessages(messages);
+                       }
+               }
+
+               return null;
+       }
+
+       /**
+        * Formats multiple annotation messages for display.
+        */
+       private String formatMessages(List messages) {
+               StringBuffer buffer = new StringBuffer();
+
+               Iterator e = messages.iterator();
+               while (e.hasNext())  {
+                       buffer.append("- "); //$NON-NLS-1$
+                       buffer.append(e.next());
+                       buffer.append('\n');
+               }
+
+               return buffer.toString();
+       }
+
+       /**
+        * Returns annotations for the ruler's line of activity.
+        */
+       private List getAnnotationsForLine(ISourceViewer viewer, int line) {
+               IDocument document = viewer.getDocument();
+
+               IAnnotationModel model = viewer.getAnnotationModel();
+               if (model == null) {
+                       return null;
+               }
+
+               List retVal = new ArrayList();
+
+               Iterator e = new XMLAnnotationIterator(model, true);
+               while (e.hasNext()) {
+                       Annotation a = (Annotation) e.next();
+
+                       Position position = model.getPosition(a);
+                       if (position != null) {
+                               try {
+                                       int annotationLine = document
+                                                       .getLineOfOffset(position.getOffset());
+                                       if (annotationLine == line) {
+                                               retVal.add(a);
+                                       }
+                               } catch (BadLocationException e1) {
+                                       // ignore
+                               }
+                       }
+               }
+
+               return retVal;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotationIterator.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotationIterator.java
new file mode 100644 (file)
index 0000000..838bd66
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLAnnotationIterator.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.Iterator;
+
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+
+
+/**
+ * @author Igor Malinin
+ */
+public class XMLAnnotationIterator implements Iterator {
+       private boolean skipIrrelevants;
+
+       private Iterator iterator;
+       private Annotation next;
+
+       public XMLAnnotationIterator(
+               IAnnotationModel model, boolean skipIrrelevants
+       ) {
+               this.skipIrrelevants = skipIrrelevants;
+
+               iterator = model.getAnnotationIterator();
+               skip();
+       }
+
+       private void skip() {
+               while (iterator.hasNext()) {
+                       Annotation next = (Annotation) iterator.next();
+                       if (next instanceof XMLAnnotation) {
+                               if (skipIrrelevants) {
+                                       if (!next.isMarkedDeleted()) {
+                                               this.next = next;
+                                               return;
+                                       }
+                               } else {
+                                       this.next = next;
+                                       return;
+                               }
+                       }
+               }
+
+               this.next = null;
+       }
+
+       /*
+        * @see java.util.Iterator#hasNext()
+        */
+       public boolean hasNext() {
+               return (next != null);
+       }
+
+       /*
+        * @see java.util.Iterator#next()
+        */
+       public Object next() {
+               try {
+                       return next;
+               } finally {
+                       skip();
+               }
+       }
+
+       /*
+        * @see java.util.Iterator#remove()
+        */
+       public void remove() {
+               throw new UnsupportedOperationException();
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLCDATAScanner.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLCDATAScanner.java
new file mode 100644 (file)
index 0000000..e99172a
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLCDATAScanner.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.Map;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.ITokenScanner;
+import org.eclipse.jface.text.rules.Token;
+
+import net.sourceforge.phpeclipse.xml.ui.text.IXMLSyntaxConstants;
+
+/**
+ * @author Igor Malinin
+ */
+public class XMLCDATAScanner implements ITokenScanner {
+
+       private Map tokens;
+
+       private IDocument document;
+
+       private int begin;
+
+       private int end;
+
+       private int offset;
+
+       private int length;
+
+       private int position;
+
+       public XMLCDATAScanner(Map tokens) {
+               this.tokens = tokens;
+       }
+
+       /*
+        * @see ITokenScanner#setRange(IDocument, int, int)
+        */
+       public void setRange(IDocument document, int offset, int length) {
+               this.document = document;
+
+               this.begin = offset;
+               this.end = offset + length;
+
+               this.offset = offset;
+               this.position = offset;
+               this.length = 0;
+       }
+
+       /*
+        * @see ITokenScanner#nextToken()
+        */
+       public IToken nextToken() {
+               offset += length;
+
+               if (position == begin) {
+                       position += 3; // <![
+
+                       try {
+                               if (document.get(position, 6).equals("CDATA[")) {
+                                       position += 6;
+                               }
+                       } catch (BadLocationException e) {
+                       }
+
+                       return getToken(IXMLSyntaxConstants.XML_CDATA);
+               }
+
+               if (position == end) {
+                       return getToken(null);
+               }
+
+               try {
+                       int p = end - 3;
+                       if (document.get(p, 3).equals("]]>")) {
+                               if (position == p) {
+                                       position = end;
+                                       return getToken(IXMLSyntaxConstants.XML_CDATA);
+                               }
+
+                               position = p;
+                       } else {
+                               position = end;
+                       }
+               } catch (BadLocationException e) {
+               }
+
+               return getToken(IXMLSyntaxConstants.XML_DEFAULT);
+       }
+
+       private IToken getToken(String type) {
+               length = position - offset;
+
+               if (length == 0) {
+                       return Token.EOF;
+               }
+
+               if (type == null) {
+                       return Token.UNDEFINED;
+               }
+
+               IToken token = (IToken) tokens.get(type);
+               if (token == null) {
+                       return Token.UNDEFINED;
+               }
+
+               return token;
+       }
+
+       /*
+        * @see ITokenScanner#getTokenOffset()
+        */
+       public int getTokenOffset() {
+               return offset;
+       }
+
+       /*
+        * @see ITokenScanner#getTokenLength()
+        */
+       public int getTokenLength() {
+               return length;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLConfiguration.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLConfiguration.java
new file mode 100644 (file)
index 0000000..eeb3235
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLConfiguration.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import net.sourceforge.phpeclipse.ui.templates.template.BasicCompletionProcessor;
+import net.sourceforge.phpeclipse.ui.text.TextDoubleClickStrategy;
+import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.contentassist.ContentAssistant;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.contentassist.IContentAssistant;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.reconciler.IReconciler;
+import org.eclipse.jface.text.reconciler.MonoReconciler;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * XML editor configuration.
+ * 
+ * @author Igor Malinin
+ */
+public class XMLConfiguration extends TextSourceViewerConfiguration {
+  protected XMLTextTools xmlTextTools;
+
+  private ITextDoubleClickStrategy dcsDefault;
+
+  private ITextDoubleClickStrategy dcsSimple;
+
+  private ITextDoubleClickStrategy dcsTag;
+
+  private ITextDoubleClickStrategy dcsAttValue;
+
+  /** The associated editor. */
+  private ITextEditor editor;
+
+  public XMLConfiguration(XMLTextTools tools) {
+    this(tools, null);
+  }
+
+  public XMLConfiguration(XMLTextTools tools, ITextEditor editor) {
+    xmlTextTools = tools;
+    this.editor = editor;
+    dcsDefault = new TextDoubleClickStrategy();
+    dcsSimple = new SimpleDoubleClickStrategy();
+    dcsTag = new TagDoubleClickStrategy();
+    dcsAttValue = new AttValueDoubleClickStrategy();
+  }
+
+  /*
+   * @see SourceViewerConfiguration#getAnnotationHover(ISourceViewer)
+   */
+  public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
+    return new XMLAnnotationHover();
+  }
+
+  /*
+   * @see SourceViewerConfiguration#getTextHover(ISourceViewer, String)
+   */
+  public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
+    if (editor != null) {
+      IDocumentProvider provider = editor.getDocumentProvider();
+      IEditorInput input = editor.getEditorInput();
+      IAnnotationModel model = provider.getAnnotationModel(input);
+      return new XMLTextHover(model);
+    }
+
+    return super.getTextHover(sourceViewer, contentType);
+  }
+
+  /*
+   * @see SourceViewerConfiguration#getDoubleClickStrategy(ISourceViewer, String)
+   */
+  public ITextDoubleClickStrategy getDoubleClickStrategy(ISourceViewer sourceViewer, String contentType) {
+    if (XMLPartitionScanner.XML_COMMENT.equals(contentType)) {
+      return dcsSimple;
+    }
+
+    if (XMLPartitionScanner.XML_PI.equals(contentType)) {
+      return dcsSimple;
+    }
+
+    if (XMLPartitionScanner.XML_TAG.equals(contentType)) {
+      return dcsTag;
+    }
+
+    if (XMLPartitionScanner.XML_ATTRIBUTE.equals(contentType)) {
+      return dcsAttValue;
+    }
+
+    if (XMLPartitionScanner.XML_CDATA.equals(contentType)) {
+      return dcsSimple;
+    }
+
+    if (contentType.startsWith(XMLPartitionScanner.DTD_INTERNAL)) {
+      return dcsSimple;
+    }
+
+    return dcsDefault;
+  }
+
+  /*
+   * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getConfiguredContentTypes(ISourceViewer)
+   */
+  public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
+    return new String[] { IDocument.DEFAULT_CONTENT_TYPE, XMLPartitionScanner.XML_PI, XMLPartitionScanner.XML_COMMENT,
+        XMLPartitionScanner.XML_DECL, XMLPartitionScanner.XML_TAG, XMLPartitionScanner.XML_ATTRIBUTE,
+        XMLPartitionScanner.XML_CDATA, XMLPartitionScanner.DTD_INTERNAL, XMLPartitionScanner.DTD_INTERNAL_PI,
+        XMLPartitionScanner.DTD_INTERNAL_COMMENT, XMLPartitionScanner.DTD_INTERNAL_DECL, };
+  }
+
+  /*
+   * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getPresentationReconciler(ISourceViewer)
+   */
+  public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
+    PresentationReconciler reconciler = new PresentationReconciler();
+
+    DefaultDamagerRepairer dr;
+
+    dr = new DefaultDamagerRepairer(xmlTextTools.getXMLTextScanner());
+    reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+    reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+
+    dr = new DefaultDamagerRepairer(xmlTextTools.getDTDTextScanner());
+    reconciler.setDamager(dr, XMLPartitionScanner.DTD_INTERNAL);
+    reconciler.setRepairer(dr, XMLPartitionScanner.DTD_INTERNAL);
+
+    dr = new DefaultDamagerRepairer(xmlTextTools.getXMLPIScanner());
+
+    reconciler.setDamager(dr, XMLPartitionScanner.XML_PI);
+    reconciler.setRepairer(dr, XMLPartitionScanner.XML_PI);
+    reconciler.setDamager(dr, XMLPartitionScanner.DTD_INTERNAL_PI);
+    reconciler.setRepairer(dr, XMLPartitionScanner.DTD_INTERNAL_PI);
+
+    dr = new DefaultDamagerRepairer(xmlTextTools.getXMLCommentScanner());
+
+    reconciler.setDamager(dr, XMLPartitionScanner.XML_COMMENT);
+    reconciler.setRepairer(dr, XMLPartitionScanner.XML_COMMENT);
+    reconciler.setDamager(dr, XMLPartitionScanner.DTD_INTERNAL_COMMENT);
+    reconciler.setRepairer(dr, XMLPartitionScanner.DTD_INTERNAL_COMMENT);
+
+    dr = new DefaultDamagerRepairer(xmlTextTools.getXMLDeclScanner());
+
+    reconciler.setDamager(dr, XMLPartitionScanner.XML_DECL);
+    reconciler.setRepairer(dr, XMLPartitionScanner.XML_DECL);
+    reconciler.setDamager(dr, XMLPartitionScanner.DTD_INTERNAL_DECL);
+    reconciler.setRepairer(dr, XMLPartitionScanner.DTD_INTERNAL_DECL);
+
+    dr = new DefaultDamagerRepairer(xmlTextTools.getXMLTagScanner());
+
+    reconciler.setDamager(dr, XMLPartitionScanner.XML_TAG);
+    reconciler.setRepairer(dr, XMLPartitionScanner.XML_TAG);
+
+    dr = new DefaultDamagerRepairer(xmlTextTools.getXMLAttributeScanner());
+
+    reconciler.setDamager(dr, XMLPartitionScanner.XML_ATTRIBUTE);
+    reconciler.setRepairer(dr, XMLPartitionScanner.XML_ATTRIBUTE);
+
+    dr = new DefaultDamagerRepairer(xmlTextTools.getXMLCDATAScanner());
+
+    reconciler.setDamager(dr, XMLPartitionScanner.XML_CDATA);
+    reconciler.setRepairer(dr, XMLPartitionScanner.XML_CDATA);
+
+    return reconciler;
+  }
+
+  /*
+   * @see SourceViewerConfiguration#getReconciler(ISourceViewer)
+   */
+  public IReconciler getReconciler(ISourceViewer sourceViewer) {
+    if ((editor != null) && editor.isEditable()) {
+      MonoReconciler reconciler = new MonoReconciler(new XMLReconcilingStrategy(editor), false);
+      reconciler.setProgressMonitor(new NullProgressMonitor());
+      reconciler.setDelay(500);
+      return reconciler;
+    }
+
+    return null;
+  }
+
+  public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
+    ContentAssistant assistant = new ContentAssistant();
+    assistant.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+
+    IContentAssistProcessor processor = new BasicCompletionProcessor();
+    assistant.setContentAssistProcessor(processor, IDocument.DEFAULT_CONTENT_TYPE);
+    assistant.setContentAssistProcessor(processor, XMLPartitionScanner.XML_TAG);
+    assistant.setContentAssistProcessor(processor, XMLPartitionScanner.XML_PI);
+    assistant.setContentAssistProcessor(processor, XMLPartitionScanner.XML_COMMENT);
+    assistant.setContentAssistProcessor(processor, XMLPartitionScanner.XML_DECL);
+    assistant.setContentAssistProcessor(processor, XMLPartitionScanner.XML_TAG);
+    assistant.setContentAssistProcessor(processor, XMLPartitionScanner.XML_ATTRIBUTE);
+    assistant.setContentAssistProcessor(processor, XMLPartitionScanner.XML_CDATA);
+    assistant.setContentAssistProcessor(processor, XMLPartitionScanner.DTD_INTERNAL);
+    assistant.setContentAssistProcessor(processor, XMLPartitionScanner.DTD_INTERNAL_PI);
+    assistant.setContentAssistProcessor(processor, XMLPartitionScanner.DTD_INTERNAL_COMMENT);
+    assistant.setContentAssistProcessor(processor, XMLPartitionScanner.DTD_INTERNAL_DECL);
+    assistant.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE);
+    assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
+
+    return assistant;
+  }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLPartitionScanner.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLPartitionScanner.java
new file mode 100644 (file)
index 0000000..4434faa
--- /dev/null
@@ -0,0 +1,553 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLPartitionScanner.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public class XMLPartitionScanner implements IPartitionTokenScanner {
+       public static final String XML_PI         = "__xml_processing_instruction";
+       public static final String XML_COMMENT    = "__xml_comment";
+       public static final String XML_DECL       = "__xml_declaration";
+       public static final String XML_TAG        = "__xml_tag";
+       public static final String XML_ATTRIBUTE  = "__xml_attribute";
+       public static final String XML_CDATA      = "__xml_cdata";
+
+       public static final String DTD_INTERNAL         = "__dtd_internal";
+       public static final String DTD_INTERNAL_PI      = "__dtd_internal_pi";
+       public static final String DTD_INTERNAL_COMMENT = "__dtd_internal_comment";
+       public static final String DTD_INTERNAL_DECL    = "__dtd_internal_declaration";
+       public static final String DTD_CONDITIONAL      = "__dtd_conditional";
+
+       public static final int STATE_DEFAULT     = 0;
+       public static final int STATE_TAG         = 1;
+       public static final int STATE_DECL        = 2;
+       public static final int STATE_CDATA       = 4;
+
+       public static final int STATE_INTERNAL    = 8;
+
+       protected IDocument document;
+       protected int end;
+
+       protected int offset;
+       protected int length;
+
+       protected int position;
+       protected int state;
+
+       protected boolean parsedtd;
+
+       protected Map tokens = new HashMap();
+
+       public XMLPartitionScanner(boolean parsedtd) {
+               this.parsedtd = parsedtd;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
+        */
+       public IToken nextToken() {
+               offset += length;
+
+               switch (state) {
+                       case STATE_TAG:
+                               return nextTagToken();
+
+                       case STATE_DECL:
+                               return nextDeclToken();
+
+                       case STATE_CDATA:
+                               return nextCDATAToken();
+               }
+
+               switch (read()) {
+                       case ICharacterScanner.EOF:
+                               state = STATE_DEFAULT;
+                               return getToken(null);
+
+                       case '<':
+                               switch (read()) {
+                                       case ICharacterScanner.EOF:
+                                               if (parsedtd || isInternal()) {
+                                                       break;
+                                               }
+
+                                               state = STATE_DEFAULT;
+                                               return getToken(XML_TAG);
+
+                                       case '?': // <?  <?PI
+                                               return nextPIToken();
+
+                                       case '!': // <!  <!DEFINITION or <![CDATA[ or <!--COMMENT
+                                               switch (read()) {
+                                                       case ICharacterScanner.EOF:
+                                                               state = STATE_DEFAULT;
+                                                               return getToken(XML_TAG);
+
+                                                       case '-': // <!-  <!--COMMENT
+                                                               switch (read()) {
+                                                                       case ICharacterScanner.EOF:
+                                                                               return nextDeclToken();
+
+                                                                       case '-': // <!--
+                                                                               return nextCommentToken();
+                                                               }
+
+                                                       case '[': // <![  <![CDATA[ or <![%cond;[
+                                                               if (parsedtd) {
+                                                                       return nextConditionalToken();
+                                                               }
+
+                                                               if (!isInternal()) {
+                                                                       return nextCDATAToken();
+                                                               }
+                                               }
+
+                                               return nextDeclToken();
+                               }
+
+                               if (parsedtd || isInternal()) {
+                                       break;
+                               }
+
+                               unread();
+
+                               return nextTagToken();
+
+                       case ']':
+                               if (isInternal()) {
+                                       unread();
+
+                                       state = STATE_DECL;
+                                       length = 0;
+                                       return nextToken();
+                               }
+               }
+
+loop:
+               while (true) {
+                       switch (read()) {
+                               case ICharacterScanner.EOF:
+                                       state = STATE_DEFAULT;
+                                       return getToken(null);
+
+                               case '<':
+                                       if (parsedtd || isInternal()) {
+                                               switch (read()) {
+                                                       case ICharacterScanner.EOF:
+                                                               state = STATE_DEFAULT;
+                                                               return getToken(null);
+
+                                                       case '!':
+                                                       case '?':
+                                                               unread();
+                                                               break;
+
+                                                       default:
+                                                               continue loop;
+                                               }
+                                       }
+
+                                       unread();
+
+                                       state &= STATE_INTERNAL;
+                                       return getToken(isInternal() ? DTD_INTERNAL : null);
+
+                               case ']':
+                                       if (isInternal()) {
+                                               unread();
+
+                                               state = STATE_DECL;
+                                               if (position == offset) {
+                                                       // nothing between
+                                                       length = 0;
+                                                       return nextToken();
+                                               }
+
+                                               return getToken(DTD_INTERNAL);
+                                       }
+                       }
+               }
+       }
+
+       private IToken nextTagToken() {
+               int quot = read();
+
+               switch (quot) {
+                       case ICharacterScanner.EOF:
+                       case '>':
+                               state = STATE_DEFAULT;
+                               return getToken(XML_TAG);
+
+                       case '"': case '\'':
+                               while (true) {
+                                       int ch = read();
+
+                                       if (ch == quot) {
+                                               state = STATE_TAG;
+                                               return getToken(XML_ATTRIBUTE);
+                                       }
+
+                                       switch (ch) {
+                                               case '<':
+                                                       unread();
+
+                                               case ICharacterScanner.EOF:
+                                                       state = STATE_DEFAULT;
+                                                       return getToken(XML_ATTRIBUTE);
+                                       }
+                               }
+               }
+
+               while (true) {
+                       switch (read()) {
+                               case '<':
+                                       unread();
+
+                               case ICharacterScanner.EOF:
+                               case '>':
+                                       state = STATE_DEFAULT;
+                                       return getToken(XML_TAG);
+
+                               case '"': case '\'':
+                                       unread();
+
+                                       state = STATE_TAG;
+                                       return getToken(XML_TAG);
+                       }
+               }
+       }
+
+       private IToken nextDeclToken() {
+               loop: while (true) {
+                       switch (read()) {
+                               case ICharacterScanner.EOF:
+                                       state = STATE_DEFAULT;
+                                       return getToken(isInternal() ? DTD_INTERNAL_DECL : XML_DECL);
+
+                               case '<':
+                                       if (parsedtd || isInternal()) {
+                                               switch (read()) {
+                                                       case ICharacterScanner.EOF:
+                                                               state = STATE_DEFAULT;
+                                                               return getToken(isInternal() ? DTD_INTERNAL : null);
+
+                                                       case '!':
+                                                       case '?':
+                                                               unread();
+                                                               break;
+
+                                                       default:
+                                                               continue loop;
+                                               }
+                                       }
+
+                                       unread();
+
+                               case '>':
+                                       state &= STATE_INTERNAL;
+                                       return getToken(isInternal() ? DTD_INTERNAL_DECL : XML_DECL);
+
+                               case '[': // <!DOCTYPE xxx [dtd]>
+                                       if (!isInternal()) {
+                                               state = STATE_INTERNAL;
+                                               return getToken(XML_DECL);
+                                       }
+                       }
+               }
+       }
+
+       private IToken nextCommentToken() {
+               state &= STATE_INTERNAL;
+
+               loop: while (true) {
+                       switch (read()) {
+                               case ICharacterScanner.EOF:
+                                       break loop;
+
+                               case '-': // -  -->
+                                       switch (read()) {
+                                               case ICharacterScanner.EOF:
+                                                       break loop;
+
+                                               case '-': // --  -->
+                                                       switch (read()) {
+                                                               case ICharacterScanner.EOF:
+                                                               case '>':
+                                                                       break loop;
+                                                       }
+
+                                                       unread();
+                                                       break loop;
+                                       }
+                       }
+               }
+
+               return getToken(isInternal() ? DTD_INTERNAL_COMMENT : XML_COMMENT);
+       }
+
+       private IToken nextPIToken() {
+               state &= STATE_INTERNAL;
+
+               loop: while (true) {
+                       switch (read()) {
+                               case ICharacterScanner.EOF:
+                                       break loop;
+
+                               case '?': // ?  ?>
+                                       switch (read()) {
+                                               case ICharacterScanner.EOF:
+                                               case '>':
+                                                       break loop;
+                                       }
+
+                                       unread();
+                       }
+               }
+
+               return getToken(isInternal() ? DTD_INTERNAL_PI : XML_PI);
+       }
+
+       private IToken nextCDATAToken() {
+               state = STATE_DEFAULT;
+
+loop:
+       while (true) {
+                       switch (read()) {
+                               case ICharacterScanner.EOF:
+                                       break loop;
+
+                               case ']': // ]  ]]>
+                                       switch (read()) {
+                                               case ICharacterScanner.EOF:
+                                                       break loop;
+
+                                               case ']': // ]]  ]]>
+                                                       switch (read()) {
+                                                               case ICharacterScanner.EOF:
+                                                               case '>': // ]]>
+                                                                       break loop;
+                                                       }
+
+                                                       unread();
+                                                       unread();
+                                                       continue loop;
+                                       }
+                       }
+               }
+
+               return getToken(XML_CDATA);
+       }
+
+       private IToken nextConditionalToken() {
+               state = STATE_DEFAULT;
+
+               int level = 1;
+
+loop:
+       while (true) {
+                       switch (read()) {
+                               case ICharacterScanner.EOF:
+                                       break loop;
+
+                               case '<': // -  -->
+                                       switch (read()) {
+                                               case ICharacterScanner.EOF:
+                                                       break loop;
+
+                                               case '!': // --  -->
+                                                       switch (read()) {
+                                                               case ICharacterScanner.EOF:
+                                                                       break loop;
+
+                                                               case '[':
+                                                                       ++level;
+                                                                       continue loop;
+                                                       }
+
+                                                       unread();
+                                                       continue loop;
+                                       }
+
+                                       unread();
+                                       continue loop;
+
+                               case ']': // -  -->
+                                       switch (read()) {
+                                               case ICharacterScanner.EOF:
+                                                       break loop;
+
+                                               case ']': // --  -->
+                                                       switch (read()) {
+                                                               case ICharacterScanner.EOF:
+                                                               case '>':
+                                                                       if (--level == 0) {
+                                                                               break loop;
+                                                                       }
+
+                                                                       continue loop;
+                                                       }
+
+                                                       unread();
+                                                       unread();
+                                                       continue loop;
+                                       }
+                       }
+               }
+
+               return getToken(DTD_CONDITIONAL);
+       }
+
+       private IToken getToken(String type) {
+               length = position - offset;
+
+               if (length == 0) {
+                       return Token.EOF;
+               }
+
+               if (type == null) {
+                       return Token.UNDEFINED;
+               }
+
+               IToken token = (IToken) tokens.get(type);
+               if (token == null) {
+                       token = new Token(type);
+                       tokens.put(type, token);
+               }
+
+               return token;
+       }
+
+       private boolean isInternal() {
+               return (state & STATE_INTERNAL) != 0;
+       }
+
+       private int read() {
+               if (position >= end) {
+                       return ICharacterScanner.EOF;
+               }
+
+               try {
+                       return document.getChar(position++);
+               } catch (BadLocationException e) {
+                       --position;
+                       return ICharacterScanner.EOF;
+               }
+       }
+
+       private void unread() {
+               --position;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenOffset()
+        */
+       public int getTokenOffset() {
+         Assert.isTrue(offset>=0, Integer.toString(offset));
+               return offset;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenLength()
+        */
+       public int getTokenLength() {
+               return length;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.ITokenScanner#setRange(IDocument, int, int)
+        */
+       public void setRange(IDocument document, int offset, int length) {
+               this.document = document;
+               this.end = offset + length;
+
+               this.offset = offset;
+               this.position = offset;
+               this.length = 0;
+
+               this.state = STATE_DEFAULT;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.rules.IPartitionTokenScanner
+        */
+       public void setPartialRange(
+               IDocument document, int offset, int length,
+               String contentType, int partitionOffset
+       ) {
+               this.document = document;
+               this.end = offset + length;
+
+               // NB! Undocumented value: -1
+               if (partitionOffset >= 0) {
+                       offset = partitionOffset;
+               }
+
+               this.offset = offset;
+               this.position = offset;
+               this.length = 0;
+
+               if (contentType == XML_ATTRIBUTE) {
+                       state = STATE_TAG;
+                       return;
+               }
+
+               if (contentType == XML_TAG) {
+                       state = isContinuationPartition() ? STATE_TAG : STATE_DEFAULT;
+                       return;
+               }
+
+               if (contentType == XML_DECL) {
+                       state = isContinuationPartition() ? STATE_DECL : STATE_DEFAULT;
+                       return;
+               }
+
+               if (contentType == DTD_INTERNAL ||
+                       contentType == DTD_INTERNAL_PI ||
+                       contentType == DTD_INTERNAL_DECL ||
+                       contentType == DTD_INTERNAL_COMMENT
+               ) {
+                       state = STATE_INTERNAL;
+                       return;
+               }
+
+               state = STATE_DEFAULT;
+       }
+
+       private boolean isContinuationPartition() {
+               try {
+                       String type = document.getContentType(offset - 1);
+
+                       if (type != IDocument.DEFAULT_CONTENT_TYPE) {
+                               return true;
+                       }
+               } catch (BadLocationException e) {}
+
+               return false;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLReconcileStep.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLReconcileStep.java
new file mode 100644 (file)
index 0000000..3b54d70
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz 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:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: XMLReconcileStep.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import net.sourceforge.phpeclipse.xml.core.model.IXMLDocument;
+import net.sourceforge.phpeclipse.xml.core.parser.IProblem;
+import net.sourceforge.phpeclipse.xml.core.parser.IProblemCollector;
+import net.sourceforge.phpeclipse.xml.ui.internal.editor.XMLDocumentProvider;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.reconciler.AbstractReconcileStep;
+import org.eclipse.jface.text.reconciler.DirtyRegion;
+import org.eclipse.jface.text.reconciler.IReconcilableModel;
+import org.eclipse.jface.text.reconciler.IReconcileResult;
+import org.eclipse.jface.text.reconciler.IReconcileStep;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Implementation of a reconcile step for building the XML parse tree on changes
+ * to the editor content.
+ */
+public class XMLReconcileStep extends AbstractReconcileStep {
+
+       // Inner Classes -----------------------------------------------------------
+
+       /**
+        * Adapts an <code>IXMLDocument</code> to the
+        * <code>IReconcilableModel</code> interface.
+        */
+       private class XMLDocumentAdapter implements IReconcilableModel {
+               private IXMLDocument document;
+
+               public XMLDocumentAdapter(IXMLDocument document) {
+                       this.document = document;
+               }
+
+               public IXMLDocument getDocument() {
+                       return document;
+               }
+
+       }
+
+       /**
+        * Implementation of the problem collector interface for creating problem
+        * annotations when there are problems parsing the style sheet.
+        */
+       private class ProblemCollector implements IProblemCollector {
+               /**
+                * The list of problems added to this collector.
+                */
+               private List collectedProblems = new ArrayList();
+
+               /**
+                * @see IProblemCollector#addProblem(IProblem)
+                */
+               public void addProblem(IProblem problem) {
+                       collectedProblems.add(problem);
+               }
+
+               /**
+                * Returns the list of problems collected while the CSS source has been
+                * parsed, in the order they were reported. The list returned is
+                * immutable.
+                * 
+                * @return the list of collected problems (of type {@link IProblem})
+                */
+               public List getProblems() {
+                       return Collections.unmodifiableList(collectedProblems);
+               }
+       }
+
+       /**
+        * Adapter that adapts an {@link IProblem} to an {@link Annotation}.
+        */
+       private class ProblemAdapter extends AnnotationAdapter {
+               private IProblem problem;
+               private Position position;
+
+               public ProblemAdapter(IProblem problem)  {
+                       this.problem = problem;
+               }
+
+               public Position getPosition()  {
+                       if (position == null) {
+                               position = createPositionFromProblem();
+                       }
+
+                       return position;
+               }
+
+               public Annotation createAnnotation() {
+                       int start = problem.getSourceStart();
+                       if (start < 0) {
+                               return null;
+                       }
+
+                       int length = problem.getSourceEnd() - start + 1;
+                       if (length < 0) {
+                               return null;
+                       }
+
+                       String type;
+                       if (problem.isWarning()) {
+                               type = XMLAnnotation.TYPE_ERROR;
+                       } else if (problem.isError()) {
+                               type = XMLAnnotation.TYPE_WARNING;
+                       } else {
+                               type = XMLAnnotation.TYPE_INFO;
+                       }
+
+                       return new XMLAnnotation(type, false, problem.getMessage());
+               }
+
+               private Position createPositionFromProblem() {
+                       int start = problem.getSourceStart();
+                       if (start < 0) {
+                               return null;
+                       }
+
+                       int length = problem.getSourceEnd() - problem.getSourceStart() + 1;
+                       if (length < 0) {
+                               return null;
+                       }
+
+                       return new Position(start, length);
+               }
+
+       }
+
+       // Instance Variables ------------------------------------------------------
+
+       private ITextEditor editor;
+
+       private XMLDocumentAdapter xmlDocumentAdapter;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Default constructor.
+        */
+       public XMLReconcileStep(ITextEditor editor) {
+               this.editor = editor;
+
+               xmlDocumentAdapter = new XMLDocumentAdapter(getXMLDocument());
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param step the step to add to the pipe
+        * @param editor the associated text editor
+        */
+       public XMLReconcileStep(IReconcileStep step, ITextEditor editor) {
+               super(step);
+
+               this.editor = editor;
+
+               xmlDocumentAdapter = new XMLDocumentAdapter(getXMLDocument());
+       }
+
+       // AbstractReconcileStep Implementation ------------------------------------
+
+       /*
+        * @see AbstractReconcileStep#reconcileModel(DirtyRegion, IRegion)
+        */
+       protected IReconcileResult[] reconcileModel(
+               DirtyRegion dirtyRegion, IRegion subRegion
+       ) {
+               IXMLDocument model = xmlDocumentAdapter.getDocument();
+
+               
+               IEditorInput editorInput = null;
+               IFile file = null;
+           if (editor != null) {
+             editorInput = editor.getEditorInput();
+           }
+
+           if (editorInput instanceof IFileEditorInput)
+             file = ((IFileEditorInput) editorInput).getFile();
+           ProblemCollector problemCollector = new ProblemCollector();
+               model.reconcile(problemCollector, file);
+
+               List problems = problemCollector.getProblems();
+               IReconcileResult[] retVal = new IReconcileResult[problems.size()];
+               for (int i = 0; i < problems.size(); i++) {
+                       IProblem problem = (IProblem) problems.get(i);
+                       retVal[i] = new ProblemAdapter(problem);
+               }
+
+               return retVal;
+       }
+
+       /*
+        * @see AbstractReconcileStep#getModel()
+        */
+       public IReconcilableModel getModel() {
+               return xmlDocumentAdapter;
+       }
+
+       // Private Methods Implementation ------------------------------------------
+
+       /**
+        * Retrieve the style sheet associated with the editor input.
+        */
+       private IXMLDocument getXMLDocument() {
+               IDocumentProvider documentProvider = editor.getDocumentProvider();
+               if (documentProvider instanceof XMLDocumentProvider) {
+                       XMLDocumentProvider xmlDocumentProvider =
+                                       (XMLDocumentProvider) documentProvider;
+                       return xmlDocumentProvider.getModel(editor.getEditorInput());
+               }
+
+               return null;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLReconcilingStrategy.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLReconcilingStrategy.java
new file mode 100644 (file)
index 0000000..95639d0
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz 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:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: XMLReconcilingStrategy.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Iterator;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.reconciler.DirtyRegion;
+import org.eclipse.jface.text.reconciler.IReconcileResult;
+import org.eclipse.jface.text.reconciler.IReconcileStep;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+import net.sourceforge.phpeclipse.ui.text.IReconcilingParticipant;
+
+/**
+ * Reconciling strategy for XML document. This class is responsible for keeping
+ * the parsed model in sync with the text.
+ */
+public class XMLReconcilingStrategy
+       implements IReconcilingStrategy, IReconcilingStrategyExtension {
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The associated text editor.
+        */
+       private ITextEditor editor;
+
+       /**
+        * A progress monitor that should be used for long-running operations.
+        */
+       IProgressMonitor progressMonitor;
+
+       /**
+        * The first (and only) reconcile step is the parsing of the style sheet.
+        */
+       private IReconcileStep firstStep;
+
+       // Constructors ------------------------------------------------------------
+
+       public XMLReconcilingStrategy(ITextEditor editor) {
+               this.editor = editor;
+               firstStep = new XMLReconcileStep(editor);
+       }
+
+       // IReconcilingStrategy Implementation -------------------------------------
+
+       /**
+        * @see IReconcilingStrategy#reconcile(DirtyRegion, IRegion)
+        */
+       public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
+               removeTemporaryAnnotations();
+               process(firstStep.reconcile(dirtyRegion, subRegion));
+       }
+
+       /**
+        * @see IReconcilingStrategy#reconcile(IRegion)
+        */
+       public void reconcile(IRegion partition) {
+               removeTemporaryAnnotations();
+               process(firstStep.reconcile(partition));
+       }
+
+       /**
+        * @see IReconcilingStrategy#setDocument(IDocument)
+        */
+       public void setDocument(IDocument document) {
+               // FIXME
+               firstStep.setInputModel(null); //new DocumentAdapter(document);
+       }
+
+       // IReconcilingStrategyExtension Implementation ----------------------------
+
+       /**
+        * @see IReconcilingStrategyExtension#initialReconcile()
+        */
+       public void initialReconcile() {
+               process(firstStep.reconcile(null));
+       }
+
+       /**
+        * @see IReconcilingStrategyExtension#setProgressMonitor(IProgressMonitor)
+        */
+       public void setProgressMonitor(IProgressMonitor monitor) {
+               firstStep.setProgressMonitor(monitor);
+               progressMonitor = monitor;
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       /**
+        * Returns the annotation model for the editor input.
+        * 
+        * @return the annotation model
+        */
+       IAnnotationModel getAnnotationModel()  {
+               IEditorInput input = editor.getEditorInput();
+               return editor.getDocumentProvider().getAnnotationModel(input);
+       }
+
+       /**
+        * Adds results of the reconcilation to the annotation model.
+        */
+       private void process(final IReconcileResult[] results) {
+               if (results == null) {
+                       return;
+               }
+
+               IRunnableWithProgress runnable = new WorkspaceModifyOperation() {
+                       protected void execute(IProgressMonitor monitor) {
+                               for (int i = 0; i < results.length; i++) {                         
+                                       if ((progressMonitor != null) &&
+                                               (progressMonitor.isCanceled()))
+                                       {
+                                               return;
+                                       }
+
+                                       if (results[i] instanceof AnnotationAdapter) {
+                                               AnnotationAdapter result = (AnnotationAdapter) results[i];
+                                               Position pos = result.getPosition();
+                                               Annotation annotation = result.createAnnotation();
+                                               getAnnotationModel().addAnnotation(annotation, pos);
+                                       }
+                               }
+                       }
+               };
+
+               try {
+                       runnable.run(null);
+               } catch (InvocationTargetException e) {
+                       e.printStackTrace();
+               } catch (InterruptedException e) {
+                       e.printStackTrace();
+               }
+
+               if (editor instanceof IReconcilingParticipant) {
+                       ((IReconcilingParticipant) editor).reconciled();
+               }
+       }
+
+       /*
+        * TODO A "real" implementation must be smarter, i.e. don't remove and add
+        *      the annotations which are the same.
+        */ 
+       private void removeTemporaryAnnotations() {
+               Iterator i = getAnnotationModel().getAnnotationIterator();
+               while (i.hasNext())  {
+                       Annotation annotation = (Annotation) i.next();
+                       if (!annotation.isPersistent()) {
+                               getAnnotationModel().removeAnnotation(annotation);
+                       }
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTagRule.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTagRule.java
new file mode 100644 (file)
index 0000000..7c4c4f7
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLTagRule.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * Rule detecting XML tag brackets and name.
+ * 
+ * @author Igor Malinin
+ */
+public class XMLTagRule implements IRule {
+
+       private IToken token;
+
+       public XMLTagRule(IToken token) {
+               this.token = token;
+       }
+
+       public IToken evaluate(ICharacterScanner scanner) {
+               int ch = scanner.read();
+               if (ch == '>') {
+                       return token;
+               }
+               if (ch == '/') {
+                       ch = scanner.read();
+                       if (ch == '>') {
+                               return token;
+                       }
+
+                       scanner.unread();
+                       scanner.unread();
+                       return Token.UNDEFINED;
+               }
+               if (ch == '<') {
+                       ch = scanner.read();
+                       if (ch == '/') {
+                               ch = scanner.read();
+                       }
+                       loop: while (true) {
+                               switch (ch) {
+                                       case ICharacterScanner.EOF:
+                                       case 0x09:
+                                       case 0x0A:
+                                       case 0x0D:
+                                       case 0x20:
+                                               break loop;
+                               }
+
+                               ch = scanner.read();
+                       }
+
+                       scanner.unread();
+                       return token;
+               }
+               scanner.unread();
+               return Token.UNDEFINED;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTagScanner.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTagScanner.java
new file mode 100644 (file)
index 0000000..6466d72
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLTagScanner.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.Map;
+
+import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WordRule;
+
+import net.sourceforge.phpeclipse.xml.ui.text.IXMLSyntaxConstants;
+
+/**
+ * @author Igor Malinin
+ */
+public class XMLTagScanner extends BufferedRuleBasedScanner {
+
+       /**
+        * Creates a color token scanner.
+        */
+       public XMLTagScanner(Map tokens) {
+               setDefaultReturnToken((Token) tokens.get(
+                               IXMLSyntaxConstants.XML_DEFAULT));
+
+               IToken tag = (Token) tokens.get(IXMLSyntaxConstants.XML_TAG);
+               IToken attribute = (Token) tokens.get(IXMLSyntaxConstants.XML_ATT_NAME);
+
+               IRule[] rules = { new XMLTagRule(tag),
+                               new WordRule(new NameDetector(), attribute),};
+
+               setRules(rules);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTextHover.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTextHover.java
new file mode 100644 (file)
index 0000000..29a61dc
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz 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:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: XMLTextHover.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import java.util.Iterator;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+
+
+/**
+ * Implements simple annotation hover to show the associated messages.
+ */
+public class XMLTextHover implements ITextHover {
+       /**
+        * This hovers annotation model.
+        */
+       private IAnnotationModel model;
+
+       /**
+        * Creates a new annotation hover.
+        * 
+        * @param model this hover's annotation model
+        */
+       public XMLTextHover(IAnnotationModel model)  {
+               this.model = model;
+       }
+       
+       /*
+        * @see ITextHover#getHoverInfo(ITextViewer, IRegion)
+        */
+       public String getHoverInfo(ITextViewer textViewer, IRegion region) {
+               Iterator e = new XMLAnnotationIterator(model, true);
+               while (e.hasNext()) {
+                       Annotation a = (Annotation) e.next();
+
+                       Position p = model.getPosition(a);
+                       if (p.overlapsWith(region.getOffset(), region.getLength())) {
+                               String text = a.getText();
+                               if ((text != null) && (text.trim().length() > 0)) {
+                                       return text;
+                               }
+                       }
+               }
+
+               return null;
+       }
+
+       /*
+        * @see ITextHover#getHoverRegion(ITextViewer, int)
+        */
+       public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+               return XMLWordFinder.findWord(textViewer.getDocument(), offset);
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLWordFinder.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLWordFinder.java
new file mode 100644 (file)
index 0000000..7348ff5
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2004 Widespace, OU 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:
+ *     Igor Malinin - initial implementation
+ * 
+ * $Id: XMLWordFinder.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+package net.sourceforge.phpeclipse.xml.ui.internal.text;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public class XMLWordFinder {
+       public static IRegion findWord(IDocument document, int offset) {
+               int length = document.getLength();
+
+               try {
+                       int pos = offset;
+
+                       while (pos >= 0) {
+                               if (!Character.isUnicodeIdentifierPart(document.getChar(pos))) {
+                                       break;
+                               }
+                               --pos;
+                       }
+
+                       int start = pos;
+
+                       pos = offset;
+
+                       while (pos < length) {
+                               if (!Character.isUnicodeIdentifierPart(document.getChar(pos))) {
+                                       break;
+                               }
+                               ++pos;
+                       }
+
+                       int end = pos;
+
+                       if (start == offset) {
+                               return new Region(start, end - start);
+                       }
+
+                       return new Region(start + 1, end - start - 1);
+               } catch (BadLocationException x) {
+                       return null;
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/text/DTDTextTools.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/text/DTDTextTools.java
new file mode 100644 (file)
index 0000000..e787c54
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: DTDTextTools.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.text;
+
+import java.util.Map;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.rules.DefaultPartitioner;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+import org.eclipse.jface.text.rules.RuleBasedScanner;
+
+import net.sourceforge.phpeclipse.ui.text.AbstractTextTools;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.DeclScanner;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.SingleTokenScanner;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.TextScanner;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLPartitionScanner;
+
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public class DTDTextTools extends AbstractTextTools {
+       private static final String[] TOKENS = {
+               IXMLSyntaxConstants.XML_DEFAULT,
+               IXMLSyntaxConstants.XML_ATT_NAME,
+               IXMLSyntaxConstants.XML_ATT_VALUE,
+               IXMLSyntaxConstants.XML_ENTITY,
+               IXMLSyntaxConstants.XML_PI,
+               IXMLSyntaxConstants.XML_COMMENT,
+               IXMLSyntaxConstants.XML_DECL,
+               IXMLSyntaxConstants.DTD_CONDITIONAL,
+       };
+
+       private static final String[] TYPES = {
+               XMLPartitionScanner.XML_PI,
+               XMLPartitionScanner.XML_COMMENT,
+               XMLPartitionScanner.XML_DECL,
+               XMLPartitionScanner.DTD_CONDITIONAL,
+       };
+
+       /** The DTD partitions scanner */
+       private XMLPartitionScanner dtdPartitionScanner;
+
+       /** The DTD text scanner */
+       private TextScanner dtdTextScanner;
+
+       /** The DTD conditional sections scanner */
+       private SingleTokenScanner dtdConditionalScanner;
+
+       /** The XML processing instructions scanner */
+       private SingleTokenScanner xmlPIScanner;
+
+       /** The XML comments scanner */ 
+       private SingleTokenScanner xmlCommentScanner;
+
+       /** The XML declarations scanner */
+       private DeclScanner xmlDeclScanner;
+
+       /**
+        * Creates a new DTD text tools collection.
+        */
+       public DTDTextTools( IPreferenceStore store ) {
+               super( store, TOKENS );
+
+               dtdPartitionScanner = new XMLPartitionScanner( true );
+
+               Map tokens = getTokens();
+
+               dtdTextScanner = new TextScanner(
+                       tokens, '%', IXMLSyntaxConstants.XML_DEFAULT );
+
+               dtdConditionalScanner = new SingleTokenScanner(
+                               tokens, IXMLSyntaxConstants.DTD_CONDITIONAL ); //cond
+
+               xmlPIScanner = new SingleTokenScanner(
+                               tokens, IXMLSyntaxConstants.XML_PI );
+
+               xmlCommentScanner = new SingleTokenScanner(
+                               tokens, IXMLSyntaxConstants.XML_COMMENT );
+
+               xmlDeclScanner = new DeclScanner( tokens );
+       }
+
+       /**
+        * 
+        */
+       public IDocumentPartitioner createDTDPartitioner() {
+               return new DefaultPartitioner( dtdPartitionScanner, TYPES );
+       }
+
+       /**
+        * 
+        */
+       public IPartitionTokenScanner getDTDPartitionScanner() {
+               return dtdPartitionScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan DTD text.
+        * 
+        * @return  an DTD text scanner
+        */
+       public RuleBasedScanner getDTDTextScanner() {
+               return dtdTextScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan DTD
+        * conditional sections.
+        * 
+        * @return  an DTD conditional section scanner
+        */
+       public RuleBasedScanner getDTDConditionalScanner() {
+               return dtdConditionalScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan XML
+        * processing instructions.
+        * 
+        * @return  an XML processing instruction scanner
+        */
+       public RuleBasedScanner getXMLPIScanner() {
+               return xmlPIScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan XML comments.
+        * 
+        * @return  an XML comment scanner
+        */
+       public RuleBasedScanner getXMLCommentScanner() {
+               return xmlCommentScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan XML declarations.
+        * 
+        * @return  an XML declaration scanner
+        */
+       public RuleBasedScanner getXMLDeclScanner() {
+               return xmlDeclScanner;
+       }
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/text/IXMLSyntaxConstants.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/text/IXMLSyntaxConstants.java
new file mode 100644 (file)
index 0000000..e279c65
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: IXMLSyntaxConstants.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.text;
+
+/**
+ * @author Igor Malinin
+ */
+public interface IXMLSyntaxConstants {
+
+       /**
+        * Note: This constant is for internal use only. Clients should not use
+        * this constant. The prefix all color constants start with.
+        */
+       String PREFIX = "xml_"; //$NON-NLS-1$
+
+       /** The style key for XML text. */
+       String XML_DEFAULT = PREFIX + "text"; //$NON-NLS-1$
+
+       /** The style key for XML tag names. */
+       String XML_TAG = PREFIX + "tag"; //$NON-NLS-1$
+
+       /** The style key for XML attribute names. */
+       String XML_ATT_NAME = PREFIX + "attribute"; //$NON-NLS-1$
+
+       /** The style key for XML attribute values. */
+       String XML_ATT_VALUE = PREFIX + "string"; //$NON-NLS-1$
+
+       /** The style key for XML entities. */
+       String XML_ENTITY = PREFIX + "entity"; //$NON-NLS-1$
+
+       /** The style key for XML processing instructions. */
+       String XML_PI = PREFIX + "processing_instruction"; //$NON-NLS-1$
+
+       /** The style key for XML CDATA sections. */
+       String XML_CDATA = PREFIX + "cdata"; //$NON-NLS-1$
+
+       /** The style key for XML comments. */
+       String XML_COMMENT = PREFIX + "comment"; //$NON-NLS-1$
+
+       /** The style key for XML declaration. */
+       String XML_DECL = PREFIX + "declaration"; //$NON-NLS-1$
+
+       /** The style key for external DTD conditional sections. */
+       String DTD_CONDITIONAL = PREFIX + "conditional"; //$NON-NLS-1$
+       
+       /** The style key for SMARTY tag names. */
+       String XML_SMARTY = PREFIX + "smarty"; //$NON-NLS-1$
+}
diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/text/XMLTextTools.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/text/XMLTextTools.java
new file mode 100644 (file)
index 0000000..ba74a9f
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU 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:
+ *     Igor Malinin - initial contribution
+ *
+ * $Id: XMLTextTools.java,v 1.1 2004-09-02 18:28:03 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.ui.text;
+
+import java.util.Map;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.rules.DefaultPartitioner;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+import org.eclipse.jface.text.rules.ITokenScanner;
+import org.eclipse.jface.text.rules.RuleBasedScanner;
+
+import net.sourceforge.phpeclipse.ui.text.AbstractTextTools;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.DeclScanner;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.SingleTokenScanner;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.TextScanner;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLCDATAScanner;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLPartitionScanner;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLTagScanner;
+
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public class XMLTextTools extends AbstractTextTools {
+       /** Text Attributes for XML editors */
+       public static final String[] TOKENS = {
+               IXMLSyntaxConstants.XML_DEFAULT,
+               IXMLSyntaxConstants.XML_TAG,
+               IXMLSyntaxConstants.XML_ATT_NAME,
+               IXMLSyntaxConstants.XML_ATT_VALUE,
+               IXMLSyntaxConstants.XML_ENTITY,
+               IXMLSyntaxConstants.XML_PI,
+               IXMLSyntaxConstants.XML_CDATA,
+               IXMLSyntaxConstants.XML_COMMENT,
+               IXMLSyntaxConstants.XML_SMARTY,
+               IXMLSyntaxConstants.XML_DECL,
+       };
+
+       /** Content types for XML editors */
+       public static final String[] TYPES = {
+               XMLPartitionScanner.XML_PI,
+               XMLPartitionScanner.XML_COMMENT,
+               XMLPartitionScanner.XML_DECL,
+               XMLPartitionScanner.XML_TAG,
+               XMLPartitionScanner.XML_ATTRIBUTE,
+               XMLPartitionScanner.XML_CDATA,
+               XMLPartitionScanner.DTD_INTERNAL,
+               XMLPartitionScanner.DTD_INTERNAL_PI,
+               XMLPartitionScanner.DTD_INTERNAL_COMMENT,
+               XMLPartitionScanner.DTD_INTERNAL_DECL,
+       };
+
+       /** The XML partitions scanner */
+       private XMLPartitionScanner xmlPartitionScanner;
+
+       /** The XML text scanner */
+       private TextScanner xmlTextScanner;
+
+       /** The DTD text scanner */
+       private TextScanner dtdTextScanner;
+
+       /** The XML tags scanner */
+       private XMLTagScanner xmlTagScanner;
+
+       /** The XML attributes scanner */
+       private TextScanner xmlAttributeScanner;
+
+       /** The XML CDATA sections scanner */
+       private XMLCDATAScanner xmlCDATAScanner;
+
+       /** The XML processing instructions scanner */
+       private SingleTokenScanner xmlPIScanner;
+
+       /** The XML comments scanner */ 
+       private SingleTokenScanner xmlCommentScanner;
+
+       /** The XML declarations scanner */
+       private DeclScanner xmlDeclScanner;
+       public XMLTextTools( IPreferenceStore store ) {
+               this( store, TOKENS );
+       }
+       /**
+        * Creates a new XML text tools collection.
+        */
+       public XMLTextTools( IPreferenceStore store, String[] strTokens ) {
+               super( store, strTokens );
+
+               xmlPartitionScanner = new XMLPartitionScanner( false );
+
+               Map tokens = getTokens();
+
+               xmlTextScanner = new TextScanner(
+                       tokens, '&', IXMLSyntaxConstants.XML_DEFAULT );
+
+               dtdTextScanner = new TextScanner(
+                       tokens, '%', IXMLSyntaxConstants.XML_DEFAULT );
+
+               xmlPIScanner = new SingleTokenScanner(
+                               tokens, IXMLSyntaxConstants.XML_PI );
+
+               xmlCommentScanner = new SingleTokenScanner(
+                               tokens, IXMLSyntaxConstants.XML_COMMENT );
+
+               xmlDeclScanner = new DeclScanner( tokens );
+
+               xmlTagScanner = new XMLTagScanner( tokens );
+
+               xmlAttributeScanner = new TextScanner(
+                       tokens, '&', IXMLSyntaxConstants.XML_ATT_VALUE );
+
+               xmlCDATAScanner = new XMLCDATAScanner( tokens );
+       }
+
+       /**
+        * 
+        */
+       public IDocumentPartitioner createXMLPartitioner() {
+               return new DefaultPartitioner( xmlPartitionScanner, TYPES );
+       }
+
+       /**
+        * 
+        */
+       public IPartitionTokenScanner getXMLPartitionScanner() {
+               return xmlPartitionScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan XML text.
+        * 
+        * @return  an XML text scanner
+        */
+       public RuleBasedScanner getXMLTextScanner() {
+               return xmlTextScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan DTD text.
+        * 
+        * @return  an DTD text scanner
+        */
+       public RuleBasedScanner getDTDTextScanner() {
+               return dtdTextScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan XML tags.
+        * 
+        * @return  an XML tag scanner
+        */
+       public RuleBasedScanner getXMLTagScanner() {
+               return xmlTagScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan XML tag attributes.
+        * 
+        * @return  an XML tag attribute scanner
+        */
+       public RuleBasedScanner getXMLAttributeScanner() {
+               return xmlAttributeScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan XML CDATA sections.
+        * 
+        * @return  an XML CDATA section scanner
+        */
+       public ITokenScanner getXMLCDATAScanner() {
+               return xmlCDATAScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan XML
+        * processing instructions.
+        * 
+        * @return  an XML processing instruction scanner
+        */
+       public RuleBasedScanner getXMLPIScanner() {
+               return xmlPIScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan XML comments.
+        * 
+        * @return  an XML comment scanner
+        */
+       public RuleBasedScanner getXMLCommentScanner() {
+               return xmlCommentScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan XML declarations.
+        * 
+        * @return  an XML declaration scanner
+        */
+       public RuleBasedScanner getXMLDeclScanner() {
+               return xmlDeclScanner;
+       }
+}