From 67b08e4784c5b5ee2ae70a6d85d3201d2cf9cd8b Mon Sep 17 00:00:00 2001 From: jsurfer Date: Thu, 2 Sep 2004 18:28:05 +0000 Subject: [PATCH] *** empty log message *** --- net.sourceforge.phpeclipse.xml.ui/.classpath | 7 + net.sourceforge.phpeclipse.xml.ui/.cvsignore | 5 + net.sourceforge.phpeclipse.xml.ui/.project | 31 ++ net.sourceforge.phpeclipse.xml.ui/build.properties | 2 + .../icons/basic/obj16/htmledit.gif | Bin 0 -> 560 bytes .../icons/basic/obj16/xml.png | Bin 0 -> 257 bytes .../icons/element_obj.gif | Bin 0 -> 78 bytes .../plugin.properties | 23 + net.sourceforge.phpeclipse.xml.ui/plugin.xml | 114 ++++ .../sourceforge/phpeclipse/xml/ui/XMLPlugin.java | 148 ++++++ .../xml/ui/XMLPluginResources.properties | 54 ++ .../xml/ui/internal/compare/DTDMergeViewer.java | 147 ++++++ .../ui/internal/compare/DTDMergeViewerCreator.java | 34 ++ .../xml/ui/internal/compare/XMLMergeViewer.java | 145 +++++ .../ui/internal/compare/XMLMergeViewerCreator.java | 34 ++ .../xml/ui/internal/editor/DTDEditor.java | 74 +++ .../ui/internal/editor/XMLDocumentProvider.java | 129 +++++ .../editor/XMLDocumentSetupParticipant.java | 40 ++ .../xml/ui/internal/editor/XMLEditor.java | 182 +++++++ .../xml/ui/internal/editor/XMLEditorMessages.java | 45 ++ .../internal/editor/XMLEditorMessages.properties | 10 + .../outline/XMLOutlineContentProvider.java | 94 ++++ .../internal/outline/XMLOutlineLabelProvider.java | 57 ++ .../xml/ui/internal/outline/XMLOutlinePage.java | 135 +++++ .../preferences/XMLPreferenceInitializer.java | 100 ++++ .../preferences/XMLSyntaxPreferencePage.java | 498 ++++++++++++++++++ .../xml/ui/internal/preferences/preview.xml | 18 + .../ui/internal/text/AbstractDocumentProvider.java | 193 +++++++ .../xml/ui/internal/text/AnnotationAdapter.java | 39 ++ .../internal/text/AttValueDoubleClickStrategy.java | 68 +++ .../xml/ui/internal/text/DTDConfiguration.java | 123 +++++ .../xml/ui/internal/text/DTDDocumentProvider.java | 46 ++ .../xml/ui/internal/text/DeclScanner.java | 68 +++ .../xml/ui/internal/text/EntityRule.java | 75 +++ .../xml/ui/internal/text/NameDetector.java | 57 ++ .../xml/ui/internal/text/NmtokenDetector.java | 48 ++ .../internal/text/SimpleDoubleClickStrategy.java | 62 +++ .../xml/ui/internal/text/SingleTokenScanner.java | 32 ++ .../ui/internal/text/TagDoubleClickStrategy.java | 127 +++++ .../xml/ui/internal/text/TextScanner.java | 42 ++ .../xml/ui/internal/text/WhitespaceDetector.java | 40 ++ .../xml/ui/internal/text/XMLAnnotation.java | 32 ++ .../xml/ui/internal/text/XMLAnnotationHover.java | 114 ++++ .../ui/internal/text/XMLAnnotationIterator.java | 82 +++ .../xml/ui/internal/text/XMLCDATAScanner.java | 136 +++++ .../xml/ui/internal/text/XMLConfiguration.java | 226 ++++++++ .../xml/ui/internal/text/XMLPartitionScanner.java | 553 ++++++++++++++++++++ .../xml/ui/internal/text/XMLReconcileStep.java | 236 +++++++++ .../ui/internal/text/XMLReconcilingStrategy.java | 176 +++++++ .../xml/ui/internal/text/XMLTagRule.java | 73 +++ .../xml/ui/internal/text/XMLTagScanner.java | 46 ++ .../xml/ui/internal/text/XMLTextHover.java | 69 +++ .../xml/ui/internal/text/XMLWordFinder.java | 62 +++ .../phpeclipse/xml/ui/text/DTDTextTools.java | 158 ++++++ .../xml/ui/text/IXMLSyntaxConstants.java | 59 ++ .../phpeclipse/xml/ui/text/XMLTextTools.java | 215 ++++++++ 56 files changed, 5383 insertions(+), 0 deletions(-) create mode 100644 net.sourceforge.phpeclipse.xml.ui/.classpath create mode 100644 net.sourceforge.phpeclipse.xml.ui/.cvsignore create mode 100644 net.sourceforge.phpeclipse.xml.ui/.project create mode 100644 net.sourceforge.phpeclipse.xml.ui/build.properties create mode 100644 net.sourceforge.phpeclipse.xml.ui/icons/basic/obj16/htmledit.gif create mode 100644 net.sourceforge.phpeclipse.xml.ui/icons/basic/obj16/xml.png create mode 100644 net.sourceforge.phpeclipse.xml.ui/icons/element_obj.gif create mode 100644 net.sourceforge.phpeclipse.xml.ui/plugin.properties create mode 100644 net.sourceforge.phpeclipse.xml.ui/plugin.xml create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/XMLPlugin.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/XMLPluginResources.properties create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/DTDMergeViewer.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/DTDMergeViewerCreator.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/XMLMergeViewer.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/XMLMergeViewerCreator.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/DTDEditor.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLDocumentProvider.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLDocumentSetupParticipant.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditor.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditorMessages.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditorMessages.properties create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlineContentProvider.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlineLabelProvider.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlinePage.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/XMLPreferenceInitializer.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/XMLSyntaxPreferencePage.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/preview.xml create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AbstractDocumentProvider.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AnnotationAdapter.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AttValueDoubleClickStrategy.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DTDConfiguration.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DTDDocumentProvider.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/DeclScanner.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/EntityRule.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/NameDetector.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/NmtokenDetector.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/SimpleDoubleClickStrategy.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/SingleTokenScanner.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/TagDoubleClickStrategy.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/TextScanner.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/WhitespaceDetector.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotation.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotationHover.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotationIterator.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLCDATAScanner.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLConfiguration.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLPartitionScanner.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLReconcileStep.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLReconcilingStrategy.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTagRule.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTagScanner.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTextHover.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLWordFinder.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/text/DTDTextTools.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/text/IXMLSyntaxConstants.java create mode 100644 net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/text/XMLTextTools.java diff --git a/net.sourceforge.phpeclipse.xml.ui/.classpath b/net.sourceforge.phpeclipse.xml.ui/.classpath new file mode 100644 index 0000000..275b34c --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/net.sourceforge.phpeclipse.xml.ui/.cvsignore b/net.sourceforge.phpeclipse.xml.ui/.cvsignore new file mode 100644 index 0000000..b0f6f7c --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/.cvsignore @@ -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 index 0000000..5351da1 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/.project @@ -0,0 +1,31 @@ + + + net.sourceforge.phpeclipse.xml.ui + + + net.sf.wdte.core + net.sf.wdte.ui + net.sf.wdte.xml.core + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + + diff --git a/net.sourceforge.phpeclipse.xml.ui/build.properties b/net.sourceforge.phpeclipse.xml.ui/build.properties new file mode 100644 index 0000000..6a9fa87 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/build.properties @@ -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 index 0000000000000000000000000000000000000000..5dae869b39b6083a09a02216e0f0aa3d551d4106 GIT binary patch literal 560 zcmZ?wbhEHb6krfwc;?2Sku>f2!?)QJ_H61h`1$KkO@ZC}&%b{B{PXhN&s%$I9>4nW zmOf#{Qmai_mxeVE82`d ze);|V$Dc3Xe^0M9pH^euTW(bihRyh`(0}YNWZXE2aObpfl5D3EX literal 0 HcmV?d00001 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 index 0000000000000000000000000000000000000000..ec16b480f2aee1940600b15e591fd3d64ba9d1a5 GIT binary patch literal 257 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv4DbnY{r~@eLqo&=`}2W}`1tt! z`~NdA>}O_!@hljQC0!qCAg>jC6&7I;J! zGca%qfiUBxyLEqng6t)pzOL+-nFU15_^f>5HUNbpJzX3_D&{07G%&k4Iyy2MIN!Vx z!E(mH%uKAP!N@1Zq31!+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 index 0000000..bbbf329 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/XMLPlugin.java @@ -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 null 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 index 0000000..3b08588 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/XMLPluginResources.properties @@ -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 index 0000000..d20f85a --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/DTDMergeViewer.java @@ -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 index 0000000..6eeb9fc --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/DTDMergeViewerCreator.java @@ -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 index 0000000..6d817c3 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/XMLMergeViewer.java @@ -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 index 0000000..60f84c0 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/compare/XMLMergeViewerCreator.java @@ -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 index 0000000..e5de102 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/DTDEditor.java @@ -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 index 0000000..73c9c3f --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLDocumentProvider.java @@ -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 index 0000000..c7cac74 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLDocumentSetupParticipant.java @@ -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 index 0000000..931ea8b --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditor.java @@ -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 index 0000000..1af6716 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditorMessages.java @@ -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 index 0000000..bea66ef --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/editor/XMLEditorMessages.properties @@ -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 index 0000000..9096ce6 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlineContentProvider.java @@ -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 index 0000000..29c3d7a --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlineLabelProvider.java @@ -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 index 0000000..a07f25a --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/outline/XMLOutlinePage.java @@ -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 index 0000000..b1186e7 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/XMLPreferenceInitializer.java @@ -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 index 0000000..d55505a --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/XMLSyntaxPreferencePage.java @@ -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 null if there is no such + * information available. + */ + private Color createColor(IPreferenceStore store, String key, Display display) { + RGB rgb = null; + + if (store.contains(key)) { + if (store.isDefault(key)) { + rgb = PreferenceConverter.getDefaultColor(store, key); + } else { + rgb = PreferenceConverter.getColor(store, key); + } + + if (rgb != 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 index 0000000..2fc0edc --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/preferences/preview.xml @@ -0,0 +1,18 @@ + + + + +]> + + + + + + <text> + ]]> + + 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 index 0000000..1b3a58c --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/AbstractDocumentProvider.java @@ -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 ' ) { + 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 index 0000000..b78c796 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/SingleTokenScanner.java @@ -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 index 0000000..a4d093a --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/TagDoubleClickStrategy.java @@ -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 index 0000000..60b35af --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/TextScanner.java @@ -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 index 0000000..7591394 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/WhitespaceDetector.java @@ -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 index 0000000..153c7f7 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotation.java @@ -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 index 0000000..11d45ca --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotationHover.java @@ -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 index 0000000..838bd66 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLAnnotationIterator.java @@ -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 index 0000000..e99172a --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLCDATAScanner.java @@ -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; // ")) { + 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 index 0000000..eeb3235 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLConfiguration.java @@ -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 index 0000000..4434faa --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLPartitionScanner.java @@ -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 '?': // ': + 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 '[': // + 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 index 0000000..3b54d70 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLReconcileStep.java @@ -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 IXMLDocument to the + * IReconcilableModel 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 index 0000000..95639d0 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLReconcilingStrategy.java @@ -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 index 0000000..7c4c4f7 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTagRule.java @@ -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 index 0000000..6466d72 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTagScanner.java @@ -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 index 0000000..29a61dc --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLTextHover.java @@ -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 index 0000000..7348ff5 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLWordFinder.java @@ -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 index 0000000..e787c54 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/text/DTDTextTools.java @@ -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 index 0000000..e279c65 --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/text/IXMLSyntaxConstants.java @@ -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 index 0000000..ba74a9f --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/text/XMLTextTools.java @@ -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; + } +} -- 1.7.1