intial source from ttp://www.sf.net/projects/wdte
authorjsurfer <jsurfer>
Thu, 2 Sep 2004 18:14:39 +0000 (18:14 +0000)
committerjsurfer <jsurfer>
Thu, 2 Sep 2004 18:14:39 +0000 (18:14 +0000)
175 files changed:
archive/net.sourceforge.phpeclipse.css.core/.classpath [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/.cvsignore [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/.project [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/build.properties [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/plugin.properties [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/plugin.xml [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/schema/profiles.exsd [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/CssCore.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/CssCoreMessages.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/CssCoreMessages.properties [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/CssCorePreferences.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/model/AbstractRule.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/model/AtRule.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/model/Declaration.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/model/PropertyInfo.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/model/StyleRule.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/model/StyleSheet.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/parser/AbstractProblemReporter.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/parser/DefaultCssParser.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/parser/DefaultCssScanner.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/parser/DefaultProblem.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/parser/MutableRegion.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/profiles/ProfileDescriptor.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/profiles/ProfileManager.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/text/CssCodeReader.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/text/CssTextUtils.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/model/IAtRule.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/model/IDeclaration.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/model/IPropertyInfo.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/model/IRule.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/model/IStyleRule.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/model/IStyleSheet.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/ICssParser.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/ICssScanner.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/ICssTokens.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/IProblem.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/IProblemCollector.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/IProblemReporter.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/LexicalErrorException.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/SyntaxErrorException.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/profiles/AbstractProfile.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/profiles/Css1Profile.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/profiles/Css2Profile.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/profiles/IProfile.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/profiles/IProfileDescriptor.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/profiles/IProfileManager.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/.classpath [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/.cvsignore [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/.project [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/build.properties [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/icons/at_rule_obj.gif [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/icons/class_obj.gif [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/icons/full/ovr16/error_co.gif [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/icons/full/ovr16/warning_co.gif [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/icons/important_obj.gif [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/icons/int_obj.gif [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/icons/property_obj.gif [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/icons/pseudo_class_obj.gif [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/icons/shorthand_obj.gif [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/icons/style_rule_obj.gif [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/icons/style_sheet_obj.gif [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/plugin.properties [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/plugin.xml [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/CssUI.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/CssDocumentProvider.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/CssDocumentSetupParticipant.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/CssUIMessages.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/CssUIMessages.properties [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/CssUIPreferences.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/ICssUIHelpContextIds.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/compare/CssMergeViewer.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/compare/CssMergeViewerCreator.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/compare/CssNode.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/compare/CssStructureCreator.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/CommentAction.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/CssEditor.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/CssEditorActionContributor.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/ICssEditorActionConstants.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/ICssEditorActionDefinitionIds.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/ShowSelectedElementOnlyAction.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/UncommentAction.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/CssOutlineContentProvider.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/CssOutlineDoubleClickListener.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/CssOutlineLabelProvider.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/CssOutlinePage.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/link_editor.gif [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/sort_alpha.gif [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/AbstractConfigurationBlock.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssEditorAnnotationsConfigurationBlock.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssEditorAppearanceConfigurationBlock.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssEditorContentAssistConfigurationBlock.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssEditorPreferencePage.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssEditorSyntaxConfigurationBlock.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssEditorTypingConfigurationBlock.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssPreferencePage.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/OverlayPreferenceStore.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/SyntaxPreviewer.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/preview.css [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/properties/CssPropertiesAdapterFactory.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/properties/CssPropertyPage.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/properties/CssRulePropertySource.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/AbstractCssScanner.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/AnnotationAdapter.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssAnnotationHover.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssAutoEditStrategy.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssCodeScanner.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssColorManager.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssCommentScanner.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssContentAssistProcessor.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssDoubleClickStrategy.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssPairMatcher.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssPartitionScanner.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssReconcileStep.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssReconcilingStrategy.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssSourceViewerConfiguration.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssStringScanner.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssTextHover.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssWordFinder.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/IReconcilingParticipant.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/text/CssTextTools.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/text/IColorManager.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.html.ui/.classpath [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.html.ui/.cvsignore [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.html.ui/.project [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.html.ui/build.properties [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.html.ui/icons/full/obj16/html.png [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.html.ui/plugin.xml [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/HTMLUI.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/HTMLUIMessages.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/HTMLUIMessages.properties [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/editor/HTMLDocumentProvider.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/editor/HTMLDocumentSetupParticipant.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/editor/HTMLEditor.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/editor/HTMLEditorMessages.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/editor/HTMLEditorMessages.properties [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/preview/HTMLPreviewPage.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/text/HTMLCompletionProcessor.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/text/HTMLConfiguration.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/.classpath [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/.cvsignore [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/.project [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/build.properties [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/plugin.properties [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/plugin.xml [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/JSCorePlugin.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSClassElement.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSClassMethodElement.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSClassVariableElement.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSElement.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSElementCategories.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSElementList.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSFunctionElement.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSGlobalVariableElement.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSInstanceMethodElement.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSInstanceVariableElement.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSParser.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSPartitionScanner.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSReferenceDetector.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSScanner.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSStringScanner.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSSyntaxModelFactory.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSSyntaxScanner.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSWhitespaceDetector.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSWordDetector.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/NonRuleBasedDamagerRepairer.java [new file with mode: 0644]
archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/PredicateWordRule.java [new file with mode: 0644]
net.sourceforge.phpeclipse.core/.classpath [new file with mode: 0644]
net.sourceforge.phpeclipse.core/.cvsignore [new file with mode: 0644]
net.sourceforge.phpeclipse.core/.project [new file with mode: 0644]
net.sourceforge.phpeclipse.core/build.properties [new file with mode: 0644]
net.sourceforge.phpeclipse.core/plugin.xml [new file with mode: 0644]
net.sourceforge.phpeclipse.core/src/net/sourceforge/phpeclipse/core/WebCore.java [new file with mode: 0644]
net.sourceforge.phpeclipse.core/src/net/sourceforge/phpeclipse/core/model/ISourceModel.java [new file with mode: 0644]
net.sourceforge.phpeclipse.core/src/net/sourceforge/phpeclipse/core/model/ISourceReference.java [new file with mode: 0644]
net.sourceforge.phpeclipse.core/src/net/sourceforge/phpeclipse/core/model/SourceReference.java [new file with mode: 0644]

diff --git a/archive/net.sourceforge.phpeclipse.css.core/.classpath b/archive/net.sourceforge.phpeclipse.css.core/.classpath
new file mode 100644 (file)
index 0000000..751c8f2
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/archive/net.sourceforge.phpeclipse.css.core/.cvsignore b/archive/net.sourceforge.phpeclipse.css.core/.cvsignore
new file mode 100644 (file)
index 0000000..67b544a
--- /dev/null
@@ -0,0 +1,3 @@
+bin
+build
+dist
diff --git a/archive/net.sourceforge.phpeclipse.css.core/.project b/archive/net.sourceforge.phpeclipse.css.core/.project
new file mode 100644 (file)
index 0000000..2f37b2f
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>net.sourceforge.phpeclipse.css.core</name>
+       <comment></comment>
+       <projects>
+               <project>net.sf.wdte.core</project>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.pde.PluginNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/archive/net.sourceforge.phpeclipse.css.core/build.properties b/archive/net.sourceforge.phpeclipse.css.core/build.properties
new file mode 100644 (file)
index 0000000..3dcad1e
--- /dev/null
@@ -0,0 +1,12 @@
+source.csscore.jar = src/
+bin.includes = plugin.xml,\
+               *.jar,\
+               csscore.jar,\
+               plugin.properties
+src.includes = .project,\
+               .classpath,\
+               build.properties,\
+               plugin.properties,\
+               plugin.xml,\
+               schema/,\
+               src/
diff --git a/archive/net.sourceforge.phpeclipse.css.core/plugin.properties b/archive/net.sourceforge.phpeclipse.css.core/plugin.properties
new file mode 100644 (file)
index 0000000..b13b3db
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# 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 english resources
+# 
+# $Id: plugin.properties,v 1.1 2004-09-02 18:07:13 jsurfer Exp $
+#
+
+pluginName = Web Development Tools CSS Core
+providerName= WDTE Project
+
+css1Profile.name = CSS Level 1
+css1Profile.description = \
+  Profile correspondong to the CSS 1.0 specification
+css2Profile.name = CSS Level 2
+css2Profile.description =\
+  Profile correspondong to the CSS 2.0 specification
diff --git a/archive/net.sourceforge.phpeclipse.css.core/plugin.xml b/archive/net.sourceforge.phpeclipse.css.core/plugin.xml
new file mode 100644 (file)
index 0000000..87a6460
--- /dev/null
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin
+   id="net.sourceforge.phpeclipse.css.core"
+   name="Web Development Tools CSS Core"
+   version="0.0.1"
+   provider-name="WDTE Project"
+   class="net.sourceforge.phpeclipse.css.core.CssCore">
+
+   <runtime>
+      <library name="csscore.jar">
+         <export name="*"/>
+      </library>
+   </runtime>
+   <requires>
+      <import plugin="net.sourceforge.phpeclipse.core"/>
+      <import plugin="org.eclipse.core.resources"/>
+      <import plugin="org.eclipse.core.runtime"/>
+      <import plugin="org.eclipse.text"/>
+   </requires>
+
+   <extension-point id="profiles" name="CSS Profiles" schema="schema/profiles.exsd"/>
+
+   <extension point="org.eclipse.team.core.fileTypes">
+      <fileTypes type="text" extension="css"/>
+   </extension>
+
+   <extension
+         point="net.sourceforge.phpeclipse.css.core.profiles">
+      <profile
+            name="%css1Profile.name"
+            description="%css1Profile.description"
+            class="net.sourceforge.phpeclipse.css.core.profiles.Css1Profile"
+            id="net.sourceforge.phpeclipse.css.core.profiles.css1">
+      </profile>
+      <profile
+            name="%css2Profile.name"
+            description="%css2Profile.description"
+            class="net.sourceforge.phpeclipse.css.core.profiles.Css2Profile"
+            id="net.sourceforge.phpeclipse.css.core.profiles.css2">
+      </profile>
+   </extension>
+
+</plugin>
diff --git a/archive/net.sourceforge.phpeclipse.css.core/schema/profiles.exsd b/archive/net.sourceforge.phpeclipse.css.core/schema/profiles.exsd
new file mode 100644 (file)
index 0000000..ed3b206
--- /dev/null
@@ -0,0 +1,120 @@
+<?xml version='1.0' encoding='UTF-8'?>\r
+<!-- Schema file written by PDE -->\r
+<schema targetNamespace="net.sf.wdte.css.ui">\r
+<annotation>\r
+      <appInfo>\r
+         <meta.schema plugin="net.sf.wdte.css.ui" id="profiles" name="CSS Profiles"/>\r
+      </appInfo>\r
+      <documentation>\r
+         [Enter description of this extension point.]\r
+      </documentation>\r
+   </annotation>\r
+\r
+   <element name="extension">\r
+      <complexType>\r
+         <sequence>\r
+            <element ref="profile" minOccurs="1" maxOccurs="unbounded"/>\r
+         </sequence>\r
+         <attribute name="point" type="string" use="required">\r
+            <annotation>\r
+               <documentation>\r
+                  \r
+               </documentation>\r
+            </annotation>\r
+         </attribute>\r
+         <attribute name="id" type="string">\r
+            <annotation>\r
+               <documentation>\r
+                  \r
+               </documentation>\r
+            </annotation>\r
+         </attribute>\r
+         <attribute name="name" type="string">\r
+            <annotation>\r
+               <documentation>\r
+                  \r
+               </documentation>\r
+            </annotation>\r
+         </attribute>\r
+      </complexType>\r
+   </element>\r
+\r
+   <element name="profile">\r
+      <complexType>\r
+         <attribute name="id" type="string" use="required">\r
+            <annotation>\r
+               <documentation>\r
+                  \r
+               </documentation>\r
+            </annotation>\r
+         </attribute>\r
+         <attribute name="name" type="string" use="required">\r
+            <annotation>\r
+               <documentation>\r
+                  \r
+               </documentation>\r
+            </annotation>\r
+         </attribute>\r
+         <attribute name="class" type="string" use="required">\r
+            <annotation>\r
+               <documentation>\r
+                  \r
+               </documentation>\r
+            </annotation>\r
+         </attribute>\r
+         <attribute name="description" type="string">\r
+            <annotation>\r
+               <documentation>\r
+                  \r
+               </documentation>\r
+            </annotation>\r
+         </attribute>\r
+      </complexType>\r
+   </element>\r
+\r
+   <annotation>\r
+      <appInfo>\r
+         <meta.section type="since"/>\r
+      </appInfo>\r
+      <documentation>\r
+         [Enter the first release in which this extension point appears.]\r
+      </documentation>\r
+   </annotation>\r
+\r
+   <annotation>\r
+      <appInfo>\r
+         <meta.section type="examples"/>\r
+      </appInfo>\r
+      <documentation>\r
+         [Enter extension point usage example here.]\r
+      </documentation>\r
+   </annotation>\r
+\r
+   <annotation>\r
+      <appInfo>\r
+         <meta.section type="apiInfo"/>\r
+      </appInfo>\r
+      <documentation>\r
+         [Enter API information here.]\r
+      </documentation>\r
+   </annotation>\r
+\r
+   <annotation>\r
+      <appInfo>\r
+         <meta.section type="implementation"/>\r
+      </appInfo>\r
+      <documentation>\r
+         [Enter information about supplied implementation of this extension point.]\r
+      </documentation>\r
+   </annotation>\r
+\r
+   <annotation>\r
+      <appInfo>\r
+         <meta.section type="copyright"/>\r
+      </appInfo>\r
+      <documentation>\r
+         \r
+      </documentation>\r
+   </annotation>\r
+\r
+</schema>\r
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/CssCore.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/CssCore.java
new file mode 100644 (file)
index 0000000..7daa73d
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * 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: CssCore.java,v 1.1 2004-09-02 18:07:13 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core;
+
+import net.sourceforge.phpeclipse.css.core.internal.CssCorePreferences;
+import net.sourceforge.phpeclipse.css.core.internal.profiles.ProfileManager;
+import net.sourceforge.phpeclipse.css.core.profiles.IProfileManager;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+public class CssCore extends Plugin {
+
+       // Class Variables ---------------------------------------------------------
+
+       /** The shared instance. */
+       private static CssCore plugin;
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The profile manager.
+        */
+       private IProfileManager profileManager;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        */
+       public CssCore() {
+               plugin = this;
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Returns the shared instance.
+        */
+       public static CssCore getDefault() {
+               return plugin;
+       }
+
+       /**
+        * Returns the plugin ID.
+        * 
+        * @return the plugin ID
+        */
+       public static String getPluginId() {
+               return getDefault().getBundle().getSymbolicName();
+       }
+
+       /**
+        * Returns the object that manages the CSS profiles.
+        * 
+        * @return the profile manager
+        */
+       public synchronized IProfileManager getProfileManager() {
+               if (profileManager == null) {
+                       profileManager = new ProfileManager(getPluginPreferences());
+               }
+               return profileManager;
+       }
+
+       /**
+        * Writes a status message and the associated exception stack trace (if
+        * provided) to the error log.
+        * 
+        * @param status the status to log
+        */
+       public static void log(IStatus status) {
+               getDefault().getLog().log(status);
+               if (status.getException() != null) {
+                       status.getException().printStackTrace(System.err);
+               }
+       }
+
+       /**
+        * Writes the specified error message and exception stack trace to the error
+        * log.
+        * 
+        * @param message the error message
+        * @param e the exception that caused the error, or <tt>null</tt> to omit
+        *        the stack trace in the log
+        */
+       public static void log(String message, Throwable e) {
+               IStatus status = new Status(IStatus.ERROR, getPluginId(), IStatus.ERROR,
+                       message, e); 
+               log(status);
+       }
+
+       /**
+        * Writes the specified error message to the error log.
+        * 
+        * @param message the error message
+        */
+       public static void log(String message) {
+               IStatus status = new Status(IStatus.ERROR, getPluginId(), IStatus.ERROR,
+                       message, null); 
+               log(status);
+       }
+
+       /**
+        * Writes the stack trace of the given exception to the error log.
+        * 
+        * @param e the exception that caused the error
+        */
+       public static void log(Throwable e) {
+               log(e.getMessage(), e);
+       }
+
+       // Plugin Implementation ---------------------------------------------------
+
+       /* 
+        * @see Plugin#initializeDefaultPluginPreferences()
+        */
+       protected void initializeDefaultPluginPreferences() {
+               CssCorePreferences.initializeDefaultValues(getPluginPreferences());
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/CssCoreMessages.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/CssCoreMessages.java
new file mode 100644 (file)
index 0000000..fde7d55
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * 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: CssCoreMessages.java,v 1.1 2004-09-02 18:07:12 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.internal;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Utility class that provides easy access to externalized strings.
+ */
+public final class CssCoreMessages {
+
+       // Constants ---------------------------------------------------------------
+
+       /**
+        * Qualified name of the resource bundle containing the localized messages.
+        */
+       private static final String RESOURCE_BUNDLE =
+               "net.sourceforge.phpeclipse.css.core.internal.CssCoreMessages"; //$NON-NLS-1$
+
+       // Class Variables ---------------------------------------------------------
+
+       /**
+        * The resource bundle.
+        */
+       private static ResourceBundle resourceBundle =
+               ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Hidden constructor.
+        */
+       private CssCoreMessages() {
+               // Hidden
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Returns the resource bundle.
+        * 
+        * @return the resource bundle
+        */
+       public static ResourceBundle getResourceBundle() {
+               return resourceBundle;
+       }
+
+       /**
+        * Returns the message identified by the specified key.
+        * 
+        * @param key the message key
+        * @return the localized message, or the key enclosed by exclamation marks
+        *         if no message was found for the key
+        */
+       public static String getString(String key) {
+               try {
+                       return resourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!"; //$NON-NLS-2$ //$NON-NLS-1$
+               }
+       }
+
+       /**
+        * Returns the message identified by the specified key, replacing a single
+        * parameter with the provided value.
+        * 
+        * @param key the message key
+        * @param arg the parameter value
+        * @return the formatted string, or the key enclosed by exclamation marks
+        *         if no message was found for the key
+        */
+       public static String getString(String key, String arg) {
+               return getString(key, new String[] { arg });
+       }
+
+       /**
+        * Returns the message identified by the specified key, replacing all
+        * parameters with the provided values.
+        * 
+        * @param key the message key
+        * @param args the parameter values
+        * @return the formatted string, or the key enclosed by exclamation marks
+        *         if no message was found for the key
+        */
+       public static String getString(String key, String[] args) {
+               return MessageFormat.format(getString(key), args);      
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/CssCoreMessages.properties b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/CssCoreMessages.properties
new file mode 100644 (file)
index 0000000..f545808
--- /dev/null
@@ -0,0 +1,46 @@
+#
+# 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: CssCoreMessages.properties,v 1.1 2004-09-02 18:07:12 jsurfer Exp $
+#
+
+# Problem Messages -------------------------------------------------------------
+
+CssParser.problem.emptyDeclarationValue = Empty declaration value
+CssParser.problem.expectedDeclaration = Expected declaration
+CssParser.problem.expectedProperty = Expected property
+CssParser.problem.expectedSelectorOrAtKeyword = Expected selector or at-keyword
+CssParser.problem.expectedToken = Expected token {0}
+CssParser.problem.illegalPositionForCDC = '-->' may only appear at the beginning of the style sheet
+CssParser.problem.illegalPositionForCDO = '<!--' may only appear at the beginning of the style sheet
+CssParser.problem.nestedComment = Comments cannot be nested
+CssParser.problem.unescapedNewlineInString = Newlines in strings need to be escaped with a backslash
+CssParser.problem.unexpectedEndOfFile = Unexpected end of file
+CssParser.problem.unexpectedToken = Expected {0}
+CssParser.problem.unterminatedComment = Unterminated comment
+CssParser.problem.runawayDeclaration = Runaway declaration?
+CssParser.problem.unterminatedString = Unterminated string
+CssParser.identifier = identifier
+CssParser.number = number
+CssParser.string = string
+
+# Profiles ---------------------------------------------------------------------
+
+CssProfile.category.aural = Aural
+CssProfile.category.box = Boxes and borders
+CssProfile.category.colorAndBackground = Color and background
+CssProfile.category.font = Fonts
+CssProfile.category.generatedContent = Generated content
+CssProfile.category.pagedMedia = Paged media
+CssProfile.category.table = Table
+CssProfile.category.text = Text properties
+CssProfile.category.userInterface = User interface
+CssProfile.category.visualEffects = Visual effects
+CssProfile.category.visualFormatting = Visual formatting
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/CssCorePreferences.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/CssCorePreferences.java
new file mode 100644 (file)
index 0000000..6b7c5de
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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: CssCorePreferences.java,v 1.1 2004-09-02 18:07:12 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.internal;
+
+import org.eclipse.core.runtime.Preferences;
+
+/**
+ * TODO type comment
+ */
+public final class CssCorePreferences {
+
+       // Constants ---------------------------------------------------------------
+
+       public static final String PROFILE =
+               "profile"; //$NON-NLS-1$
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Hidden constructor.
+        */
+       private CssCorePreferences() {
+               // Hidden
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Initializes the given plugin preferences with the default values.
+        * 
+        * @param preferences the preferences to initialize
+        */
+       public static void initializeDefaultValues(Preferences preferences) {
+               preferences.setDefault(PROFILE,
+                       "net.sourceforge.phpeclipse.css.core.profiles.css2"); //$NON-NLS-1$
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/model/AbstractRule.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/model/AbstractRule.java
new file mode 100644 (file)
index 0000000..21962ff
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * 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: AbstractRule.java,v 1.1 2004-09-02 18:07:12 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.internal.model;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpeclipse.core.model.SourceReference;
+import net.sourceforge.phpeclipse.css.core.model.IDeclaration;
+import net.sourceforge.phpeclipse.css.core.model.IRule;
+import net.sourceforge.phpeclipse.css.core.model.IStyleSheet;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+
+/**
+ * 
+ */
+public abstract class AbstractRule extends SourceReference
+       implements IRule {
+
+       // Instance Variables ------------------------------------------------------
+
+       private IStyleSheet styleSheet;
+
+       private IRule parent;
+
+       private List children = new ArrayList(); 
+
+       private List declarations = new ArrayList();
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param document the document that contains the rule
+        * @param styleSheet the style sheet that contains the rule
+        */
+       public AbstractRule(IDocument document, IStyleSheet styleSheet) {
+               this(document, styleSheet, null);
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param document the document that contains the rule
+        * @param styleSheet the style sheet that contains the rule
+        * @param parent the parent rule, or <code>null</code> if the rule is at top
+        *        level
+        */
+       public AbstractRule(IDocument document, IStyleSheet styleSheet,
+               IRule parent) {
+               super(document);
+               this.styleSheet = styleSheet;
+               this.parent = parent;
+       }
+
+       // IAdaptable Implementation -----------------------------------------------
+
+       /*
+        * @see IAdaptable#getAdapter(Class)
+        */
+       public Object getAdapter(Class adapter) {
+               return Platform.getAdapterManager().getAdapter(this, adapter);
+       }
+
+       // IStyleRule Implementation -----------------------------------------------
+
+       /*
+        * @see IRule#getStyleSheet()
+        */
+       public final IStyleSheet getStyleSheet() {
+               return styleSheet;
+       }
+
+       /*
+        * @see IRule#getParent()
+        */
+       public final IRule getParent() {
+               return parent;
+       }
+
+       /*
+        * @see IRule#getChildren()
+        */
+       public final IRule[] getChildren() {
+               return (IRule[]) children.toArray(new IRule[children.size()]);
+       }
+
+       /*
+        * @see IRule#getDeclarationAt(int)
+        */
+       public final IDeclaration getDeclarationAt(int offset) {
+               for (Iterator i = declarations.iterator(); i.hasNext(); ) {
+                       IDeclaration declaration = (IDeclaration) i.next();
+                       IRegion region = declaration.getSourceRegion();
+                       if ((offset > region.getOffset())
+                        && (offset < (region.getOffset() + region.getLength()))) {
+                               return declaration;
+                       }
+               }
+               return null;
+       }
+
+       /*
+        * @see IRule#getDeclarations()
+        */
+       public final IDeclaration[] getDeclarations() {
+               return (IDeclaration[]) declarations.toArray(
+                       new IDeclaration[declarations.size()]);
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       public final void addChild(IRule rule) {
+               children.add(rule);
+       }
+
+       public final void addDeclaration(IDeclaration declaration) {
+               declarations.add(declaration);
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/model/AtRule.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/model/AtRule.java
new file mode 100644 (file)
index 0000000..ed28c99
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * 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: AtRule.java,v 1.1 2004-09-02 18:07:12 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.internal.model;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.css.core.model.IAtRule;
+import net.sourceforge.phpeclipse.css.core.model.IRule;
+import net.sourceforge.phpeclipse.css.core.model.IStyleSheet;
+
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * 
+ */
+public class AtRule extends AbstractRule
+       implements IAtRule {
+
+       // Instance Variables ------------------------------------------------------
+
+       private ISourceReference name;
+
+       private ISourceReference value;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param document The document that contains the rule
+        */
+       public AtRule(IDocument document, IStyleSheet styleSheet) {
+               this(document, styleSheet, null);
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param document The document that contains the rule
+        * @param parent The parent rule, or <code>null</code> if the rule is at top
+        *        level
+        */
+       public AtRule(IDocument document, IStyleSheet styleSheet, IRule parent) {
+               super(document, styleSheet, parent);
+       }
+
+       // IAtRule Implementation --------------------------------------------------
+
+       /*
+        * @see IAtRule#getName()
+        */
+       public final ISourceReference getName() {
+               return name;
+       }
+
+       /*
+        * @see IAtRule#getValue()
+        */
+       public final ISourceReference getValue() {
+               return value;
+       }
+
+       // Public Methods --------------------------------------------------
+
+       public final void setName(ISourceReference name) {
+               this.name = name;
+       }
+
+       public final void setValue(ISourceReference value) {
+               this.value = value;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/model/Declaration.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/model/Declaration.java
new file mode 100644 (file)
index 0000000..ed37c38
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * 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: Declaration.java,v 1.1 2004-09-02 18:07:12 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.internal.model;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.core.model.SourceReference;
+import net.sourceforge.phpeclipse.css.core.model.IDeclaration;
+import net.sourceforge.phpeclipse.css.core.model.IRule;
+
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * 
+ */
+public class Declaration extends SourceReference
+       implements IDeclaration {
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The rule that contains this declaration.
+        */
+       private IRule rule;
+
+       /**
+        * The part of the declaration that contains the property name.
+        */
+       private ISourceReference property;
+
+       /**
+        * The value part of the declaration.
+        */
+       private ISourceReference value;
+
+       /**
+        * The priority part of the declaration.
+        */
+       private ISourceReference priority;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param document the document that contains the property
+        * @param rule the rule that contains this property, or <code>null</code> if
+        *        the declaration does not belong to a specific rule 
+        */
+       public Declaration(IDocument document, IRule rule) {
+               super(document);
+               this.rule = rule;
+       }
+
+       // IProperty Implementation ------------------------------------------------
+
+       /*
+        * @see IDeclaration#getRule()
+        */
+       public final IRule getRule() {
+               return rule;
+       }
+
+       /*
+        * @see IDeclaration#getProperty()
+        */
+       public final ISourceReference getProperty() {
+               return property;
+       }
+
+       /*
+        * @see IDeclaration#getValue()
+        */
+       public final ISourceReference getValue() {
+               return value;
+       }
+
+       /*
+        * @see IDeclaration#getPriority()
+        */
+       public final ISourceReference getPriority() {
+               return priority;
+       }
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * Sets the property.
+        * 
+        * @param property The property to set
+        */
+       public final void setProperty(ISourceReference property) {
+               this.property = property;
+       }
+
+       /**
+        * Sets the value.
+        * 
+        * @param value The value to set
+        */
+       public final void setValue(ISourceReference value) {
+               this.value = value;
+       }
+
+       /**
+        * Sets the priority.
+        * 
+        * @param priority The priority to set
+        */
+       public final void setPriority(ISourceReference priority) {
+               this.priority = priority;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/model/PropertyInfo.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/model/PropertyInfo.java
new file mode 100644 (file)
index 0000000..1587b2b
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * 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: PropertyInfo.java,v 1.1 2004-09-02 18:07:12 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.internal.model;
+
+import net.sourceforge.phpeclipse.css.core.model.IPropertyInfo;
+
+/**
+ * 
+ */
+public class PropertyInfo implements IPropertyInfo {
+
+       // Instance Variables ------------------------------------------------------
+
+       private String name;
+
+       private String category;
+
+       private String description;
+
+       private boolean shorthand;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param name The name of the property
+        * @param category The category of the property
+        */
+       public PropertyInfo(String name, String category) {
+               this(name, category, false);
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param name The name of the property
+        * @param category The category of the property
+        * @param shorthand Whether the property is a shorthand property
+        */
+       public PropertyInfo(String name, String category, boolean shorthand) {
+               this(name, category, null, shorthand);
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param name The name of the property
+        * @param category The category of the property
+        * @param description An optional description of the property
+        * @param shorthand Whether the property is a shorthand property
+        */
+       public PropertyInfo(String name, String category, String description,
+               boolean shorthand) {
+               this.name = name;
+               this.category = category;
+               this.description = description;
+               this.shorthand = shorthand;
+       }
+
+       // IPropertyInfo Implementation --------------------------------------------
+
+       /*
+        * @see IPropertyInfo#getName()
+        */
+       public String getName() {
+               return name;
+       }
+
+       /*
+        * @see IPropertyInfo#getCategory()
+        */
+       public String getCategory() {
+               return category;
+       }
+
+       /*
+        * @see IPropertyInfo#getDescription()
+        */
+       public String getDescription() {
+               return description;
+       }
+
+       /*
+        * @see IPropertyInfo#isShorthand()
+        */
+       public boolean isShorthand() {
+               return shorthand;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/model/StyleRule.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/model/StyleRule.java
new file mode 100644 (file)
index 0000000..d767d65
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 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: StyleRule.java,v 1.1 2004-09-02 18:07:12 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.internal.model;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.css.core.model.IRule;
+import net.sourceforge.phpeclipse.css.core.model.IStyleRule;
+import net.sourceforge.phpeclipse.css.core.model.IStyleSheet;
+
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * 
+ */
+public class StyleRule extends AbstractRule
+       implements IStyleRule {
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The selector.
+        */
+       private ISourceReference selector;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param document The document that contains the rule
+        */
+       public StyleRule(IDocument document, IStyleSheet styleSheet) {
+               this(document, styleSheet, null);
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param document The document that contains the rule
+        * @param parent The parent rule, or <code>null</code> if the rule is at top
+        *        level
+        */
+       public StyleRule(IDocument document, IStyleSheet styleSheet, IRule parent) {
+               super(document, styleSheet, parent);
+       }
+
+       // IStyleRule Implementation -----------------------------------------------
+
+       /**
+        * @see IStyleRule#getSelector()
+        */
+       public final ISourceReference getSelector() {
+               return selector;
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       public final void setSelector(ISourceReference selector) {
+               this.selector = selector;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/model/StyleSheet.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/model/StyleSheet.java
new file mode 100644 (file)
index 0000000..eda232c
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * 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: StyleSheet.java,v 1.1 2004-09-02 18:07:12 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.internal.model;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import net.sourceforge.phpeclipse.core.model.SourceReference;
+import net.sourceforge.phpeclipse.css.core.internal.parser.DefaultCssParser;
+import net.sourceforge.phpeclipse.css.core.model.IRule;
+import net.sourceforge.phpeclipse.css.core.model.IStyleSheet;
+import net.sourceforge.phpeclipse.css.core.parser.ICssParser;
+import net.sourceforge.phpeclipse.css.core.parser.IProblemCollector;
+import net.sourceforge.phpeclipse.css.core.parser.LexicalErrorException;
+import net.sourceforge.phpeclipse.css.core.parser.SyntaxErrorException;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.text.IRegion;
+
+/**
+ * 
+ */
+public class StyleSheet extends SourceReference
+       implements IStyleSheet, IDocumentListener {
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The list of top-level CSS rules defined in the style sheet.
+        */
+       private List rules = new ArrayList();
+
+       private Object dirtyLock = new Object();
+       private boolean dirty = true;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param document The document that contains the style sheet
+        */
+       public StyleSheet(IDocument document) {
+               super(document);
+       }
+
+       // IAdaptable Implementation -----------------------------------------------
+
+       /*
+        * @see IAdaptable#getAdapter(Class)
+        */
+       public Object getAdapter(Class adapter) {
+               return Platform.getAdapterManager().getAdapter(this, adapter);
+       }
+
+       // IStyleSheet Implementation ----------------------------------------------
+
+       /*
+        * @see IStyleSheet#getRuleAt(int)
+        */
+       public IRule getRuleAt(int offset) {
+               return getRuleAtInternal(getRules(), offset);
+       }
+
+       /*
+        * @see IStyleSheet#getRules()
+        */
+       public IRule[] getRules() {
+               return (IRule[]) rules.toArray(new IRule[rules.size()]);
+       }
+
+       /*
+        * @see IStyleSheet#reconcile(IProblemCollector)
+        */
+       public void reconcile(IProblemCollector problemCollector)
+               throws LexicalErrorException, SyntaxErrorException {
+               
+               synchronized (dirtyLock) {
+                       if (!dirty) {
+                               return;
+                       }
+                       dirty = false;
+               }
+
+               synchronized (this) {
+                       rules.clear();
+                       ICssParser parser = new DefaultCssParser();
+                       parser.setProblemCollector(problemCollector);
+                       parser.setSource(getDocument());
+                       rules.addAll(Arrays.asList(parser.parseRules(this)));
+               }
+       }
+
+       // IDocumentListener Implementation ----------------------------------------
+
+       /*
+        * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent)
+        */
+       public void documentAboutToBeChanged(DocumentEvent event) {
+               // do nothing yet
+       }
+
+       /*
+        * @see IDocumentListener#documentChanged(DocumentEvent)
+        */
+       public void documentChanged(DocumentEvent event) {
+               synchronized (dirtyLock) {
+                       dirty = true;
+               }
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Adds a rule to the style sheet.
+        * 
+        * @param rule The rule to add
+        */
+       public void addRule(IRule rule) {
+               rules.add(rule);
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private static IRule getRuleAtInternal(IRule rules[], int offset) {
+               IRule retVal = null;
+               for (int i = 0; i < rules.length; i++) {
+                       IRule rule = rules[i];
+                       IRegion region = rule.getSourceRegion();
+                       if ((offset > region.getOffset())
+                        && (offset < (region.getOffset() + region.getLength()))) {
+                               if (rule.getChildren().length > 0) {
+                                       retVal = getRuleAtInternal(rule.getChildren(), offset);
+                                       if (retVal != null) {
+                                               break;
+                                       }
+                               }
+                               if (retVal == null) {
+                                       retVal = rule;
+                               }
+                       }
+               }
+               return retVal;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/parser/AbstractProblemReporter.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/parser/AbstractProblemReporter.java
new file mode 100644 (file)
index 0000000..ba0352a
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * 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: AbstractProblemReporter.java,v 1.1 2004-09-02 18:07:13 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.internal.parser;
+
+import net.sourceforge.phpeclipse.css.core.internal.CssCoreMessages;
+import net.sourceforge.phpeclipse.css.core.parser.IProblem;
+import net.sourceforge.phpeclipse.css.core.parser.IProblemCollector;
+import net.sourceforge.phpeclipse.css.core.parser.IProblemReporter;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+
+public abstract class AbstractProblemReporter implements IProblemReporter {
+
+       // Instance Variables ------------------------------------------------------
+
+       protected IDocument document;
+
+       protected IProblemCollector problemCollector = new IProblemCollector() {
+               public void addProblem(IProblem problem) {
+                       // do nothing
+               }
+       };
+
+       // IProblemReporter Implementation -----------------------------------------
+
+       /*
+        * @see IProblemReporter#setProblemCollector(IProblemCollector)
+        */
+       public void setProblemCollector(IProblemCollector problemCollector) {
+               this.problemCollector = problemCollector;
+       }
+
+       // Protected Methods -------------------------------------------------------
+
+       protected final IProblem createError(String id, IRegion region) {
+               return createError(id, new String[0], region);
+       }
+
+       protected final IProblem createError(String id, String arg,
+               IRegion region) {
+               return createError(id, new String[] {arg}, region);
+       }
+
+       protected final IProblem createError(String id, String args[],
+               IRegion region) {
+               return createProblem(id, args, region, true);
+       }
+
+       protected final IProblem createWarning(String id, IRegion region) {
+               return createWarning(id, new String[0], region);
+       }
+
+       protected final IProblem createWarning(String id, String arg,
+               IRegion region) {
+               return createWarning(id, new String[] {arg}, region);
+       }
+
+       protected final IProblem createWarning(String id, String args[],
+               IRegion region) {
+               return createProblem(id, args, region, false);
+       }
+
+       protected final IProblem reportError(String id, IRegion region) {
+               return reportProblem(createError(id, region));
+       }
+
+       protected final IProblem reportError(String id, String arg,
+               IRegion region) {
+               return reportProblem(createError(id, arg, region));
+       }
+
+       protected final IProblem reportError(String id, String args[],
+               IRegion region) {
+               return reportProblem(createError(id, args, region));
+       }
+
+       protected final IProblem reportWarning(String id, IRegion region) {
+               return reportProblem(createWarning(id, region));
+       }
+
+       protected final IProblem reportWarning(String id, String arg,
+               IRegion region) {
+               return reportProblem(createWarning(id, arg, region));
+       }
+
+       protected final IProblem reportWarning(String id, String args[],
+               IRegion region) {
+               return reportProblem(createWarning(id, args, region));
+       }
+
+       protected final IProblem reportProblem(IProblem problem) {
+               problemCollector.addProblem(problem);
+               return problem;
+       }
+
+       protected final void setDocument(IDocument document) {
+               this.document = document;
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private IProblem createProblem(String id, String args[],
+               IRegion region, boolean error) {
+               String message = CssCoreMessages.getString(
+                       "CssParser.problem." + id, args); //$NON-NLS-1$
+               int offset = region.getOffset();
+               int lineNumber = -1;
+               try {
+                       lineNumber = document.getLineOfOffset(offset);
+               } catch (BadLocationException e) {
+                       // ignore
+               }
+               return new DefaultProblem(id, message, null, offset,
+                       offset + region.getLength(), lineNumber, error);
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/parser/DefaultCssParser.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/parser/DefaultCssParser.java
new file mode 100644 (file)
index 0000000..7e80c9f
--- /dev/null
@@ -0,0 +1,474 @@
+/*
+ * 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: DefaultCssParser.java,v 1.1 2004-09-02 18:07:13 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.internal.parser;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.core.model.SourceReference;
+import net.sourceforge.phpeclipse.css.core.internal.model.AtRule;
+import net.sourceforge.phpeclipse.css.core.internal.model.Declaration;
+import net.sourceforge.phpeclipse.css.core.internal.model.StyleRule;
+import net.sourceforge.phpeclipse.css.core.internal.text.CssTextUtils;
+import net.sourceforge.phpeclipse.css.core.model.IAtRule;
+import net.sourceforge.phpeclipse.css.core.model.IDeclaration;
+import net.sourceforge.phpeclipse.css.core.model.IRule;
+import net.sourceforge.phpeclipse.css.core.model.IStyleRule;
+import net.sourceforge.phpeclipse.css.core.model.IStyleSheet;
+import net.sourceforge.phpeclipse.css.core.parser.ICssParser;
+import net.sourceforge.phpeclipse.css.core.parser.ICssScanner;
+import net.sourceforge.phpeclipse.css.core.parser.ICssTokens;
+import net.sourceforge.phpeclipse.css.core.parser.IProblem;
+import net.sourceforge.phpeclipse.css.core.parser.IProblemCollector;
+import net.sourceforge.phpeclipse.css.core.parser.LexicalErrorException;
+import net.sourceforge.phpeclipse.css.core.parser.SyntaxErrorException;
+
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * A simple CSS parser implementation.
+ * 
+ * TODO At-rules can contain child rules as well as declarations. Currently we
+ *      only handle child rules.
+ */
+public class DefaultCssParser extends AbstractProblemReporter
+       implements ICssParser {
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The underlying CSS token scanner.
+        */
+       private ICssScanner scanner;
+
+       /**
+        * The token being currently processed.
+        */
+       private int currentToken;
+
+       /**
+        * Whether the parser is currently initializer. Is <code>true</code> as soon
+        * as currentToken has been initialized.
+        */
+       private boolean initialized;
+
+       // ICssParser Implementation -----------------------------------------------
+
+       /**
+        * @see ICssParser#parseRules(IStyleSheet)
+        */
+       public IRule[] parseRules(IStyleSheet styleSheet)
+               throws LexicalErrorException, SyntaxErrorException {
+               List rules = new ArrayList();
+               nextToken();
+               if (currentToken == ICssTokens.CDO) {
+                       // ignore an opening SGML comment delimiter at the start of the
+                       // style sheet
+                       nextToken();
+               }
+               while (currentToken != ICssTokens.EOF) {
+                       if (currentToken == ICssTokens.CDC) {
+                               // ignore a closing SGML comment delimiter at the end of the
+                               // style sheet
+                               IProblem problem = createWarning(
+                                       "illegalPositionForCDC", //$NON-NLS-1$
+                                       scanner.getTokenRegion());
+                               if (nextToken() != ICssTokens.EOF) {
+                                       reportProblem(problem);
+                               }
+                       } else if (currentToken == ICssTokens.CDO) {
+                               reportWarning("illegalPositionForCDO", //$NON-NLS-1$
+                                       scanner.getTokenRegion());
+                               nextToken();
+                       } else {
+                               IRule rule = parseRule(styleSheet, null);
+                               if (rule != null) {
+                                       rules.add(rule);
+                               } else {
+                                       break;
+                               }
+                       }
+               }
+               return (IRule[]) rules.toArray(new IRule[rules.size()]);
+       }
+
+       /**
+        * Parses a CSS rule, which can be either an at-rule like
+        * <code>@import</code> or a normal style rule.
+        * 
+        * @param parent the parent rule in which the rule to parse is nested, or
+        *        <code>null</code> if the rule to parse is at the top level of the
+        *        style sheet
+        * @return the parsed rule
+        * @throws LexicalErrorException if a lexical error is reported by the
+        *         scanner
+        * @throws SyntaxErrorException if a syntax error has been encountered from
+        *         which recovery is not possible
+        */
+       public IRule parseRule(IStyleSheet styleSheet, IRule parent)
+               throws LexicalErrorException, SyntaxErrorException {
+               if (!initialized) {
+                       nextToken();
+               }
+               if ((currentToken == -1) || (currentToken == '}')) {
+                       reportError("expectedRule", //$NON-NLS-1$
+                               scanner.getTokenRegion());
+                       return null;
+               }
+               switch (currentToken) {
+                       case ICssTokens.AT: {
+                               return parseAtRule(styleSheet, parent);
+                       }
+                       default: {
+                               return parseStyleRule(styleSheet, parent);
+                       }
+               }
+       }
+
+       /**
+        * Parses a CSS selector. The provided reader is expected to be positioned
+        * at the beginning of the selector (leading whitespace will be ignored).
+        * 
+        * @return the parsed selector
+        * @throws LexicalErrorException if a lexical error is reported by the
+        *         scanner
+        * @throws SyntaxErrorException if a syntax error has been encountered from
+        *         which recovery is not possible
+        */
+       public ISourceReference parseSelector(IRule rule)
+               throws LexicalErrorException, SyntaxErrorException {
+               if (!initialized) {
+                       nextToken();
+               }
+               return parseAnythingUpto(new int[] { ICssTokens.LBRACE });
+       }
+
+       /**
+        * Parses a declaration. The provided reader is expected to be positioned at
+        * the beginning of the property name (leading whitespace will be ignored).
+        * The return declaration will start with the start of the property, and
+        * will end at the end of the value, excluding the semicolon, if one is 
+        * present.
+        * 
+        * @return the parsed style declaration
+        * @throws LexicalErrorException if a lexical error is reported by the
+        *         scanner
+        * @throws SyntaxErrorException if a syntax error has been encountered from
+        *         which recovery is not possible
+        */
+       public IDeclaration parseDeclaration(IRule rule)
+               throws LexicalErrorException, SyntaxErrorException {
+               if (!initialized) {
+                       nextToken();
+               }
+               if ((currentToken == -1) || (currentToken == '}')) {
+                       return null;
+               }
+               Declaration declaration = new Declaration(document, rule);
+               MutableRegion declarationRegion = newRegion();
+
+               // parse the property
+               if (currentToken == ICssTokens.IDENT) {
+                       SourceReference property = new SourceReference(document);
+                       property.setSourceRegion(scanner.getTokenRegion());
+                       declaration.setProperty(property);
+                       nextToken(declarationRegion);
+               } else {
+                       reportError("expectedProperty", //$NON-NLS-1$
+                               scanner.getTokenRegion());
+               }
+
+               // expect a colon to delimit the property from the value
+               if (currentToken == ICssTokens.COLON) {
+                       nextToken(declarationRegion);
+               } else {
+                       reportError("expectedToken", ":", //$NON-NLS-1$ //$NON-NLS-2$
+                               scanner.getTokenRegion());
+               }
+
+               // parse the declaration value (excluding the priority)
+               ISourceReference value = parseAnythingUpto(new int[] {
+                       ICssTokens.RBRACE, ICssTokens.SEMICOLON, ICssTokens.EXCLAMATION
+               });
+               if (value != null) {
+                       declaration.setValue(value);
+                       declarationRegion.add(value.getSourceRegion());
+               } else {
+                       reportError("emptyDeclarationValue", //$NON-NLS-1$
+                               scanner.getTokenRegion());
+               }
+
+               // if present, parse the declaration priority
+               if (currentToken == '!') {
+                       SourceReference priority = new SourceReference(document);
+                       MutableRegion priorityRegion = newRegion();
+                       if (nextToken() == ICssTokens.IDENT) {
+                               nextToken(priorityRegion);
+                       } else {
+                               reportError("priorityExpected", //$NON-NLS-1$
+                                       scanner.getTokenRegion());
+                       }
+                       priority.setSourceRegion(priorityRegion);
+                       declaration.setPriority(priority);
+                       declarationRegion.add(priority.getSourceRegion());
+               }
+
+               declaration.setSourceRegion(declarationRegion);
+               return declaration;
+       }
+
+       /**
+        * @see ICssParser#setProblemCollector(IProblemCollector)
+        */
+       public void setProblemCollector(IProblemCollector problemCollector) {
+               super.setProblemCollector(problemCollector);
+               if (scanner != null) {
+                       scanner.setProblemCollector(problemCollector);
+               }
+       }
+
+       /**
+        * @see ICssParser#setSource(IDocument)
+        */
+       public void setSource(IDocument document) {
+               setDocument(document);
+               if (scanner != null) {
+                       scanner.setSource(document);
+               }
+       }
+
+       // Protected Methods -------------------------------------------------------
+
+       protected ICssScanner createScanner(IDocument document) {
+               ICssScanner retVal = new DefaultCssScanner();
+               retVal.setSource(document);
+               retVal.setProblemCollector(problemCollector);
+               return retVal;
+       }
+
+       /**
+        * Parses a region of the source until one of the specified tokens is 
+        * encountered. In addition, this method keeps track of opened parenthesis
+        * and brackets, and will report an error if they are not closed.
+        * 
+        * @param tokens an array containing the tokens that should delimit the
+        *        range of source to parse
+        * @return the parsed source reference
+        * @throws LexicalErrorException if a lexical error is reported by the
+        *         scanner
+        * @throws SyntaxErrorException if a syntax error has been encountered from
+        *         which recovery is not possible
+        */
+       protected final ISourceReference parseAnythingUpto(int tokens[])
+               throws LexicalErrorException, SyntaxErrorException {
+               Arrays.sort(tokens);
+               SourceReference any = null;
+               MutableRegion region = newRegion();
+               while (currentToken != ICssTokens.EOF) {
+                       if (Arrays.binarySearch(tokens, currentToken) >= 0) {
+                               break;
+                       } else {
+                               any = new SourceReference(document);
+                               if ((currentToken == '(') || (currentToken == '[')) {
+                                       char peer = CssTextUtils.getPeerCharacter(
+                                               (char) currentToken);
+                                       nextToken(region);
+                                       ISourceReference ref =
+                                               parseAnythingUpto(new int[] { peer } );
+                                       if (currentToken != peer) {
+                                               reportError("expectedToken", //$NON-NLS-1$
+                                                       String.valueOf(peer), scanner.getTokenRegion());
+                                       }
+                                       if (ref != null) {
+                                               region.add(ref.getSourceRegion());
+                                       }
+                               }
+                       }
+                       nextToken(region);
+               }
+               if (any != null) {
+                       any.setSourceRegion(region);
+               }
+               return any;
+       }
+
+       /**
+        * Parses an at-rule.
+        *      
+        * @param styleSheet the owning style sheet
+        * @param parent the rule in which the rule to parse is nested, or
+        *        <code>null</code> if this rule is at the top level of the style
+        *        sheet
+        * @return the parsed rule
+        * @throws LexicalErrorException if a lexical error is reported by the
+        *         scanner
+        * @throws SyntaxErrorException if a syntax error has been encountered from
+        *         which recovery is not possible
+        */
+       protected final IAtRule parseAtRule(IStyleSheet styleSheet, IRule parent)
+               throws LexicalErrorException, SyntaxErrorException {
+               AtRule rule = new AtRule(document, styleSheet, parent);
+               MutableRegion ruleRegion = newRegion();
+               if (currentToken == ICssTokens.AT) {
+                       nextToken();
+               } else {
+                       reportError("expectedToken", "@",  //$NON-NLS-1$//$NON-NLS-2$
+                               scanner.getTokenRegion());
+               }
+               if (currentToken == ICssTokens.IDENT) {
+                       SourceReference name = new SourceReference(document);
+                       name.setSourceRegion(scanner.getTokenRegion());
+                       rule.setName(name);
+                       nextToken(ruleRegion);
+               } else {
+                       reportError("expectedAtKeyword", //$NON-NLS-1$
+                               scanner.getTokenRegion());
+               }
+               if ((currentToken != ICssTokens.LBRACE)
+                && (currentToken != ICssTokens.SEMICOLON)
+                && (currentToken != ICssTokens.EOF)) {
+                       ISourceReference value = parseAnythingUpto(new int[] {
+                               ICssTokens.LBRACE, ICssTokens.SEMICOLON
+                       });
+                       rule.setValue(value);
+                       ruleRegion.add(value.getSourceRegion());
+               }
+               if (currentToken == ICssTokens.LBRACE) {
+                       nextToken(ruleRegion);
+                       while (currentToken != ICssTokens.RBRACE) {
+                               IRule child = parseRule(styleSheet, rule);
+                               if (child != null) {
+                                       rule.addChild(child);
+                                       ruleRegion.add(child.getSourceRegion());
+                               }
+                               if (currentToken == ICssTokens.EOF) {
+                                       reportError("unexpectedEndOfFile", //$NON-NLS-1$
+                                               scanner.getTokenRegion());
+                                       break;
+                               }
+                       }
+                       if (currentToken == ICssTokens.RBRACE) {
+                               nextToken(ruleRegion);
+                       } else {
+                               reportError("expectedToken", "}", //$NON-NLS-1$ //$NON-NLS-2$
+                                       scanner.getTokenRegion());
+                       }
+               } else {
+                       if ((rule.getValue() == null) && (rule.getChildren().length == 0)) {
+                               reportError("expectedValueOrBlock", //$NON-NLS-1$
+                                       scanner.getTokenRegion());
+                       } else if (currentToken != ICssTokens.SEMICOLON) {
+                               reportError("expectedToken", ";", //$NON-NLS-1$ //$NON-NLS-2$
+                                       scanner.getTokenRegion());
+                       }
+                       if (currentToken == ICssTokens.SEMICOLON) {
+                               nextToken(ruleRegion);
+                       }
+               }
+               rule.setSourceRegion(ruleRegion);
+               return rule;
+       }
+
+       /**
+        * Parses a style rule.
+        * 
+        * <p>
+        *  This corresponds to the <code>ruleset</code> production in the
+        *  specification       of the CSS 3 syntax module:
+        * </p>
+        * <pre>
+        *  selector? '{' S* declaration? [ ';' S* declaration? ]* '}' S*
+        * </pre>
+        * 
+        * <p>
+        *  <strong>Question</strong>: why is the selector optional in the above
+        *  production? In section 4.8 the specification says that <em>"A rule set
+        *  (also called 'rule') consists of a selector followed by a declaration
+        *  block."</em> So we should be able to assume that there
+        *  <strong>must</strong> be a selector, and otherwise report an error.
+        * </p>
+        * 
+        * @param parent the parent rule in which the style rule is nested, or
+        *        <code>null</code> if the style rule to parse is at the top level
+        *        of the style sheet
+        * @return the parsed style rule
+        * @throws LexicalErrorException if a lexical error is reported by the
+        *         scanner
+        * @throws SyntaxErrorException if a syntax error has been encountered from
+        *         which recovery is not possible
+        */
+       protected final IStyleRule parseStyleRule(IStyleSheet styleSheet,
+               IRule parent) throws LexicalErrorException, SyntaxErrorException {
+               StyleRule rule = new StyleRule(document, styleSheet, parent);
+               MutableRegion ruleRegion = newRegion();
+               ISourceReference selector = parseSelector(rule);
+               if (selector != null) {
+                       rule.setSelector(selector);
+               } else {
+                       reportError("expectedSelectorOrAtKeyword", //$NON-NLS-1$
+                               scanner.getTokenRegion());
+               }
+               if (currentToken == ICssTokens.LBRACE) {
+                       nextToken(ruleRegion);
+                       do {
+                               IDeclaration declaration = parseDeclaration(rule);
+                               if (declaration != null) {
+                                       rule.addDeclaration(declaration);
+                                       ruleRegion.add(declaration.getSourceRegion());
+                               }
+                               if (currentToken == ';') {
+                                       nextToken(ruleRegion);
+                               } else {
+                                       break;
+                               }
+                       } while ((currentToken != ICssTokens.RBRACE)
+                                 && (currentToken != ICssTokens.EOF));
+                       if (currentToken == ICssTokens.RBRACE) {
+                               nextToken(ruleRegion);
+                       } else {
+                               reportError("expectedToken", "}", //$NON-NLS-1$ //$NON-NLS-2$
+                                       scanner.getTokenRegion());
+                       }
+               } else {
+                       reportError("expectedToken", "{", //$NON-NLS-1$ //$NON-NLS-2$
+                               scanner.getTokenRegion());
+               }
+               rule.setSourceRegion(ruleRegion);
+               return rule;
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private int nextToken() throws LexicalErrorException {
+               return nextToken(null);
+       }
+
+       private int nextToken(MutableRegion region) throws LexicalErrorException {
+               initialized = true;
+               if (scanner == null) {
+                       scanner = createScanner(document);
+               }
+               if (region != null) {
+                       region.add(scanner.getTokenRegion());
+               }
+               currentToken = scanner.getNextToken();
+               return currentToken;
+       }
+
+       private MutableRegion newRegion() {
+               return new MutableRegion(scanner.getTokenRegion());
+       }
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/parser/DefaultCssScanner.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/parser/DefaultCssScanner.java
new file mode 100644 (file)
index 0000000..8482135
--- /dev/null
@@ -0,0 +1,318 @@
+/*
+ * 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: DefaultCssScanner.java,v 1.1 2004-09-02 18:07:13 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.internal.parser;
+
+import net.sourceforge.phpeclipse.css.core.internal.text.CssTextUtils;
+import net.sourceforge.phpeclipse.css.core.parser.ICssScanner;
+import net.sourceforge.phpeclipse.css.core.parser.ICssTokens;
+import net.sourceforge.phpeclipse.css.core.parser.IProblem;
+import net.sourceforge.phpeclipse.css.core.parser.LexicalErrorException;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+
+/**
+ * Default implementation of a lexical scanner for CSS.
+ * 
+ * TODO Add support for character escapes and unicode ranges
+ */
+public class DefaultCssScanner extends AbstractProblemReporter
+       implements ICssScanner {
+
+       // Instance Variables ------------------------------------------------------
+
+       private int currentChar;
+
+       private int offset;
+
+       private int tokenOffset;
+
+       // ICssScanner Implementation ----------------------------------------------
+
+       /**
+        * @see ICssScanner#getTokenRegion()
+        */
+       public IRegion getTokenRegion() {
+               return new Region(tokenOffset, offset - tokenOffset);
+       }
+
+       /**
+        * @see ICssScanner#getNextToken()
+        */
+       public int getNextToken() throws LexicalErrorException {
+               if (document == null) {
+                       throw new IllegalStateException("Source must be set"); //$NON-NLS-1$
+               }
+               if (currentChar == -1) {
+                       return ICssTokens.EOF;
+               }
+               tokenOffset = offset;
+               getNextCharOrEnd();
+               switch (currentChar) {
+                       case '@': {
+                               return ICssTokens.AT;
+                       }
+                       case ':': {
+                               return ICssTokens.COLON;
+                       }
+                       case '.': {
+                               if (Character.isDigit((char) peekNextChar())) {
+                                       return handleNumber();
+                               }
+                               return currentChar;
+                       }
+                       case '{': {
+                               return ICssTokens.LBRACE;
+                       }
+                       case '[': {
+                               return ICssTokens.LBRACKET;
+                       }
+                       case '(': {
+                               return ICssTokens.LPAREN;
+                       }
+                       case '}': {
+                               return ICssTokens.RBRACE;
+                       }
+                       case ']': {
+                               return ICssTokens.RBRACKET;
+                       }
+                       case ')': {
+                               return ICssTokens.RPAREN;
+                       }
+                       case ';': {
+                               return ICssTokens.SEMICOLON;
+                       }
+                       case '/': {
+                               if (peekNextChar() == '*') {
+                                       getNextCharOrEnd();
+                                       return handleComment();
+                               }
+                               return currentChar;
+                       }
+                       case '\'':
+                       case '"': {
+                               return handleString((char) currentChar);
+                       }
+                       case '<': {
+                               if (peekNextChar() == '!') {
+                                       getNextCharOrEnd();
+                                       return handleCdo();
+                               }
+                               return currentChar;
+                       }
+                       case '-': {
+                               if (peekNextChar() == '-') {
+                                       getNextCharOrEnd();
+                                       return handleCdc();
+                               } else if (CssTextUtils.isCssNumberStart((char)
+                                       peekNextChar())) {
+                                       return handleNumber();
+                               }
+                               return currentChar;
+                       }
+                       default: {
+                               if (CssTextUtils.isCssIdentifierStart((char) currentChar)) {
+                                       return handleIdentifier();
+                               } else if (Character.isDigit((char) currentChar)) {
+                                       return handleNumber();
+                               } else if (CssTextUtils.isCssWhitespace((char) currentChar)) {
+                                       return handleWhitespace();
+                               }
+                               return currentChar;
+                       }
+               }
+       }
+
+       /**
+        * @see ICssScanner#setSource(IDocument)
+        */
+       public void setSource(IDocument document) {
+               super.setDocument(document);
+               currentChar = 0;
+               offset = 0;
+               tokenOffset = 0;
+       }
+
+       // Protected Methods -------------------------------------------------------
+
+       protected int handleCdc() throws LexicalErrorException {
+               if (currentChar != '-') {
+                       throw new IllegalStateException(
+                               "Not at the beginning of a CDC"); //$NON-NLS-1$
+               }
+               if (peekNextChar() != '>') {
+                       // not a CDC, rewind and return the start character
+                       offset -= 2;
+                       return getNextCharOrEnd();
+               }
+               getNextCharOrEnd();
+               return ICssTokens.CDC;
+       }
+
+       protected int handleCdo() throws LexicalErrorException {
+               if (currentChar != '!') {
+                       throw new IllegalStateException(
+                               "Not at the beginning of a CDO"); //$NON-NLS-1$
+               }
+               if (peekNextChar() != '-') {
+                       // not a CDO, rewind and return the start character
+                       offset -= 2;
+                       return getNextCharOrEnd();
+               }
+               getNextCharOrEnd();
+               if (peekNextChar() != '-') {
+                       // not a CDO, rewind and return the start character
+                       offset -= "!--".length(); //$NON-NLS-1$
+                       return getNextCharOrEnd();
+               }
+               getNextCharOrEnd();
+               return ICssTokens.CDO;
+       }
+
+       protected int handleComment() throws LexicalErrorException {
+               if (currentChar != '*') {
+                       throw new IllegalStateException(
+                               "Not at the beginning of a comment"); //$NON-NLS-1$
+               }
+               do {
+                       do {
+                               getNextCharOrError("unterminatedComment"); //$NON-NLS-1$
+                       } while (currentChar != '*');
+                       getNextCharOrError("unterminatedComment"); //$NON-NLS-1$
+                       while (currentChar == '*') {
+                               getNextCharOrError("unterminatedComment"); //$NON-NLS-1$
+                       }
+               } while (currentChar != '/');
+               return getNextToken();
+       }
+
+       protected int handleIdentifier() throws LexicalErrorException {
+               if (!CssTextUtils.isCssIdentifierStart((char) currentChar)) {
+                       throw new IllegalStateException(
+                               "Not at the beginning of an identifier"); //$NON-NLS-1$
+               }
+               while (CssTextUtils.isCssIdentifierPart((char) peekNextChar())) {
+                       getNextCharOrEnd();
+               }
+               return ICssTokens.IDENT;
+       }
+
+       protected int handleNumber() throws LexicalErrorException {
+               if (!CssTextUtils.isCssNumberStart((char) currentChar)) {
+                       throw new IllegalStateException(
+                               "Not at the beginning of a number"); //$NON-NLS-1$
+               }
+               while (CssTextUtils.isCssNumberPart((char) peekNextChar())) {
+                       getNextCharOrEnd();
+               }
+               if (peekNextChar() == '.') {
+                       getNextCharOrEnd();
+                       while (Character.isDigit((char) peekNextChar())) {
+                               getNextCharOrEnd();
+                       }
+               }
+               return ICssTokens.NUM;
+       }
+
+       protected int handleString(char delim) throws LexicalErrorException {
+               if (currentChar != delim) {
+                       throw new IllegalStateException(
+                               "Not at the beginning of a string"); //$NON-NLS-1$
+               }
+               do {
+                       getNextCharOrError("unterminatedString"); //$NON-NLS-1$
+                       if (currentChar == '\\') {
+                               getNextCharOrEnd();
+                               getNextCharOrError("unterminatedString"); //$NON-NLS-1$
+                       } else if (currentChar == '\n') {
+                               reportError("unescapedNewlineInString", //$NON-NLS-1$
+                                       new Region(tokenOffset, offset - tokenOffset));
+                       }
+               } while (currentChar != delim);
+               return ICssTokens.STRING;
+       }
+
+       protected int handleWhitespace() throws LexicalErrorException {
+               if (!CssTextUtils.isCssWhitespace((char) currentChar)) {
+                       throw new IllegalStateException(
+                               "Not at the beginning of white space"); //$NON-NLS-1$
+               }
+               while (CssTextUtils.isCssWhitespace((char) peekNextChar())) {
+                       getNextCharOrEnd();
+               }
+               return getNextToken();
+       }
+
+       /**
+        * Positions the scanner over the next character in the source and returns
+        * that character. If the end of the source is reached, an 'unexpected end
+        * of file' error is reported. 
+        * 
+        * @param errorId the ID of the error to report
+        * @return the next character in the source, or -1 if the end of the source
+        *         has been reached
+        * @throws LexicalErrorException If the end of the source has been reached
+        *         and no problem collector has been configured to collect the 
+        *         problem
+        */
+       protected final int getNextCharOrError(String errorId)
+               throws LexicalErrorException {
+               getNextCharOrEnd();
+               if (currentChar == -1) {
+                       IProblem error = reportError(errorId,
+                               new Region(tokenOffset, offset - tokenOffset));
+                       throw new LexicalErrorException(error.getMessage());
+               }
+               return currentChar;
+       }
+
+       /**
+        * Positions the scanner over the next character in the source and returns
+        * that character.
+        * 
+        * @return the next character in the source, or -1 if the end of the source
+        *         has been reached
+        */
+       protected final int getNextCharOrEnd() {
+               try {
+                       currentChar = document.getChar(offset);
+                       if (currentChar != -1) {
+                               offset++;
+                       }
+               } catch (BadLocationException e) {
+                       currentChar = -1;
+               }
+               return currentChar;
+       }
+
+       /**
+        * Returns the next character in the source without changing the scanners
+        * current position (look ahead).
+        * 
+        * @return the next character in the source, or -1 if the end of the source
+        *         has been reached
+        */
+       protected final int peekNextChar() {
+               int retVal = -1;
+               try {
+                       retVal = document.getChar(offset);
+               } catch (BadLocationException e) {
+                       // ignore
+               }
+               return retVal;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/parser/DefaultProblem.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/parser/DefaultProblem.java
new file mode 100644 (file)
index 0000000..2cc0240
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * 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: DefaultProblem.java,v 1.1 2004-09-02 18:07:13 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.internal.parser;
+
+import net.sourceforge.phpeclipse.css.core.parser.IProblem;
+
+public class DefaultProblem implements IProblem {
+
+       // Instance Variables ------------------------------------------------------
+
+       private String id;
+
+       private String message;
+
+       private String originatingFileName;
+
+       private int sourceStart;
+
+       private int sourceEnd;
+
+       private int sourceLineNumber;
+
+       private boolean error;
+
+       // Constructors ------------------------------------------------------------
+
+       public DefaultProblem(String id, String message, String originatingFileName,
+               int sourceStart, int sourceEnd, int sourceLineNumber, boolean error) {
+               this.id = id;
+               this.message = message;
+               this.originatingFileName = originatingFileName;
+               this.sourceStart = sourceStart;
+               this.sourceEnd = sourceEnd;
+               this.sourceLineNumber = sourceLineNumber;
+               this.error = error;
+       }
+
+       // IProblem Implementation -------------------------------------------------
+
+       /*
+        * @see IProblem#getID()
+        */
+       public String getId() {
+               return id;
+       }
+
+       /*
+        * @see IProblem#getMessage()
+        */
+       public String getMessage() {
+               return message;
+       }
+
+       /*
+        * @see IProblem#getOriginatingFileName()
+        */
+       public String getOriginatingFileName() {
+               return originatingFileName;
+       }
+
+       /*
+        * @see IProblem#getSourceEnd()
+        */
+       public int getSourceEnd() {
+               return sourceEnd;
+       }
+
+       /*
+        * @see IProblem#getSourceLineNumber()
+        */
+       public int getSourceLineNumber() {
+               return sourceLineNumber;
+       }
+
+       /*
+        * @see IProblem#getSourceStart()
+        */
+       public int getSourceStart() {
+               return sourceStart;
+       }
+
+       /*
+        * @see IProblem#isError()
+        */
+       public boolean isError() {
+               return error;
+       }
+
+       /*
+        * @see IProblem#isWarning()
+        */
+       public boolean isWarning() {
+               return !error;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/parser/MutableRegion.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/parser/MutableRegion.java
new file mode 100644 (file)
index 0000000..41a7210
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * 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: MutableRegion.java,v 1.1 2004-09-02 18:07:13 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.internal.parser;
+
+import org.eclipse.jface.text.IRegion;
+
+/**
+ * 
+ */
+public class MutableRegion implements IRegion {
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The offset of the region.
+        */
+       private int offset = 0;
+
+       /**
+        * The length of the region.
+        */
+       private int length = 0;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Default constructor.
+        */
+       public MutableRegion() {
+               this(0);
+       }
+
+       /**
+        * Constructor with partial initialization.
+        * 
+        * @param offset the offset of the region
+        */
+       public MutableRegion(int offset) {
+               this.offset = offset;
+       }
+
+       /**
+        * Constructor with initialization.
+        * 
+        * @param offset the offset of the region
+        * @param length the length of the region
+        */
+       public MutableRegion(int offset, int length) {
+               this.offset = offset;
+               this.length = length;
+       }
+
+       /**
+        * Constructor with initialization.
+        * 
+        * @param region another region to initialize this region with
+        */
+       public MutableRegion(IRegion region) {
+               this.offset = region.getOffset();
+               this.length = region.getLength();
+       }
+
+       // IRegion Implementation --------------------------------------------------
+
+       /*
+        * @see org.eclipse.jface.text.IRegion#getLength()
+        */
+       public int getLength() {
+               return length;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IRegion#getOffset()
+        */
+       public int getOffset() {
+               return offset;
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Adds another region to this region, which will be enlarged so that the
+        * added region completely fits into this region.
+        * 
+        * @param region the region to add 
+        */
+       public void add(IRegion region) {
+               int start1 = offset;
+               int end1 = offset + length;
+               int start2 = region.getOffset();
+               int end2 = start2 + region.getLength();
+               offset = (start1 < start2) ? start1 : start2;
+               length = (end1 > end2) ? (end1 - offset) : (end2 - offset);
+       }
+
+       /**
+        * Sets the length of the region.
+        * 
+        * @param length the length to set
+        */
+       public void setLength(int length) {
+               this.length = length;
+       }
+
+       /**
+        * Sets the offset of the region.
+        * 
+        * @param offset the offset to set
+        */
+       public void setOffset(int offset) {
+               this.offset = offset;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/profiles/ProfileDescriptor.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/profiles/ProfileDescriptor.java
new file mode 100644 (file)
index 0000000..4ffa818
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * 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: ProfileDescriptor.java,v 1.1 2004-09-02 18:07:11 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.internal.profiles;
+
+import net.sourceforge.phpeclipse.css.core.profiles.IProfileDescriptor;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+
+
+/**
+ * 
+ */
+public class ProfileDescriptor implements IProfileDescriptor {
+
+       // Constants ---------------------------------------------------------------
+
+       private static final String ATTR_ID = "id"; //$NON-NLS-1$
+       private static final String ATTR_NAME = "name"; //$NON-NLS-1$
+       private static final String ATTR_CLASS = "class"; //$NON-NLS-1$
+       private static final String ATTR_DESCRIPTION = "description"; //$NON-NLS-1$
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The profile ID.
+        */
+       private String id;
+
+       /**
+        * The name of the profile.
+        */
+       private String name;
+
+       /**
+        * The name of the implementation class.
+        */
+       private String className;
+
+       /**
+        * An optional description.
+        */
+       private String description;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param element The configuration element corresponding to the declaration
+        *        of the profile
+        */
+       public ProfileDescriptor(IConfigurationElement element) {
+               this.id = element.getAttribute(ATTR_ID);
+               this.name = element.getAttribute(ATTR_NAME);
+               this.className = element.getAttribute(ATTR_CLASS);
+               this.description = element.getAttribute(ATTR_DESCRIPTION);
+       }
+
+       // IProfileDescriptor Implementation ---------------------------------------
+
+       /**
+        * @see IProfileDescriptor#getId()
+        */
+       public String getId() {
+               return id;
+       }
+
+       /**
+        * @see IProfileDescriptor#getName()
+        */
+       public String getName() {
+               return name;
+       }
+
+       /**
+        * @see IProfileDescriptor#getDescription()
+        */
+       public String getDescription() {
+               return description;
+       }
+
+       /**
+        * @see IProfileDescriptor#getClassName()
+        */
+       public String getClassName() {
+               return className;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/profiles/ProfileManager.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/profiles/ProfileManager.java
new file mode 100644 (file)
index 0000000..6eb26c9
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: ProfileManager.java,v 1.1 2004-09-02 18:07:11 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.internal.profiles;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import net.sourceforge.phpeclipse.css.core.CssCore;
+import net.sourceforge.phpeclipse.css.core.internal.CssCorePreferences;
+import net.sourceforge.phpeclipse.css.core.profiles.IProfile;
+import net.sourceforge.phpeclipse.css.core.profiles.IProfileDescriptor;
+import net.sourceforge.phpeclipse.css.core.profiles.IProfileManager;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.core.runtime.QualifiedName;
+
+/**
+ * Implementation of the <code>IProfileManager</code> interface.
+ */
+public class ProfileManager implements IProfileManager {
+
+       // Constants ---------------------------------------------------------------
+
+       /**
+        * The qualified name used to persist the selected profile on projects and
+        * resources.
+        */
+       public static final QualifiedName PROFILE_PROPERTY =
+               new QualifiedName(CssCore.getPluginId(), "profile"); //$NON-NLS-1$
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The plugin preferences.
+        */
+       private Preferences preferences;
+
+       /**
+        * The profile descriptors, keyed by extension ID.
+        */
+       private Map profileDescriptors;
+
+       /**
+        * Cache of the already loaded profiles.
+        */
+       private Map profiles = new WeakHashMap();
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param preferences the plugin preferences
+        */
+       public ProfileManager(Preferences preferences) {
+               this.preferences = preferences;
+       }
+
+       // IProfileManager Implementation ------------------------------------------
+
+       /**
+        * @see IProfileManager#getProfileDescriptors()
+        */
+       public IProfileDescriptor[] getProfileDescriptors() {
+               if (profileDescriptors == null) {
+                       loadProfileExtensions();
+               }
+               List retVal = new ArrayList();
+               retVal.addAll(profileDescriptors.values());
+               return (IProfileDescriptor[]) retVal.toArray(
+                       new IProfileDescriptor[retVal.size()]);
+       }
+
+       /**
+        * @see IProfileManager#getProfile(IResource)
+        */
+       public IProfile getProfile(IResource resource) {
+               String profileId = null;
+               if (resource != null) {
+                       try {
+                               profileId = resource.getPersistentProperty(PROFILE_PROPERTY);
+                       } catch (CoreException e) {
+                               CssCore.log(
+                                       "Failed to get profile for resource", e); //$NON-NLS-1$
+                       }
+                       if (profileId == null) {
+                               IProject project = resource.getProject();
+                               try {
+                                       profileId = project.getPersistentProperty(PROFILE_PROPERTY);
+                               } catch (CoreException e) {
+                                       CssCore.log(
+                                               "Failed to get profile for project", e); //$NON-NLS-1$
+                               }
+                       }
+               }
+               if (profileId == null) {
+                       profileId = preferences.getString(CssCorePreferences.PROFILE);
+               }
+               IProfile profile = getProfile(profileId);
+               return profile;
+       }
+
+       /**
+        * @see IProfileManager#setProfile(IResource, String)
+        */
+       public void setProfile(IResource resource, String profileId) {
+               if (resource != null) {
+                       try {
+                               resource.setPersistentProperty(
+                                       ProfileManager.PROFILE_PROPERTY, profileId);
+                       } catch (CoreException e) {
+                               CssCore.log(
+                                       "Cannot store profile as resource property", //$NON-NLS-1$
+                                       e);
+                       }
+               } else if (profileId != null) {
+                       preferences.setValue(CssCorePreferences.PROFILE, profileId);
+               } else {
+                       preferences.setToDefault(CssCorePreferences.PROFILE);
+               }
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       /**
+        * Returns the profile associated with the specified extension ID. The
+        * profile is instantiated if not already in the cache.
+        * 
+        * @param profileId the ID of the extension implementing the profile
+        */
+       private IProfile getProfile(String profileId) {
+               IProfile profile = (IProfile) profiles.get(profileId);
+               if (profile == null) {
+                       IProfileDescriptor descriptor = getProfileDescriptor(profileId);
+                       if (descriptor == null) {
+                               CssCore.log("Profile '" + profileId + //$NON-NLS-1$
+                                       "' not found."); //$NON-NLS-1$
+                               descriptor = getDefaultProfileDescriptor();
+                       }
+                       if (descriptor != null) {
+                               profile = instantiateProfile(descriptor);
+                               profiles.put(profileId, profile);
+                       }
+               }
+               return profile;
+       }
+
+       /**
+        * Returns the descriptor of the default profile.
+        * 
+        * @return the descriptor of the default profile
+        */
+       private IProfileDescriptor getDefaultProfileDescriptor() {
+               String profileId = preferences.getDefaultString(
+                               CssCorePreferences.PROFILE);
+               return getProfileDescriptor(profileId);
+       }
+
+       /**
+        * Returns the descriptor of the specified profile.
+        * 
+        * @param profileId the ID of the profile
+        * @return the descriptor of the profile with the given ID
+        */
+       private IProfileDescriptor getProfileDescriptor(String profileId) {
+               if (profileDescriptors == null) {
+                       loadProfileExtensions();
+               }
+               return (IProfileDescriptor) profileDescriptors.get(profileId);
+       }
+
+       /**
+        * Instantiates and the returns the profile.
+        * 
+        * @param descriptor the profile descriptor
+        * @return the instantiated profile, or <code>null</code> if there was a 
+        *         problem instantiating the profile
+        */
+       private IProfile instantiateProfile(IProfileDescriptor descriptor) {
+               try {
+                       Class clazz = Class.forName(descriptor.getClassName());
+                       Constructor ctor = clazz.getConstructor(
+                               new Class[] { IProfileDescriptor.class });
+                       return (IProfile) ctor.newInstance(new Object[] { descriptor });
+               } catch (Exception e) {
+                       CssCore.log("Failed to get CSS profile", e); //$NON-NLS-1$
+               }
+               return null;
+       }
+
+       /**
+        * Initializes the list of available profiles by querying the platform for
+        * extensions of the <em>profiles</em> extension point and storing an
+        * <code>IProfileDescriptor</code> for each extension found.
+        */
+       private void loadProfileExtensions() {
+               profileDescriptors = new HashMap();
+               IExtensionRegistry registry = Platform.getExtensionRegistry();
+               IExtensionPoint extensionPoint = registry.getExtensionPoint(
+                       IProfileDescriptor.EXTENSION_POINT_ID);
+               IExtension[] extensions = extensionPoint.getExtensions();
+               for (int i = 0; i < extensions.length; i++) {
+                       IExtension extension = extensions[i];
+                       IConfigurationElement[] elements =
+                               extension.getConfigurationElements();
+                       for (int j = 0; j < elements.length; j++) {
+                               IConfigurationElement element = elements[j];
+                               IProfileDescriptor descriptor = new ProfileDescriptor(element);
+                               profileDescriptors.put(descriptor.getId(), descriptor);
+                       }
+               }
+       }
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/text/CssCodeReader.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/text/CssCodeReader.java
new file mode 100644 (file)
index 0000000..0672123
--- /dev/null
@@ -0,0 +1,396 @@
+/*
+ * 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: CssCodeReader.java,v 1.1 2004-09-02 18:07:13 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.internal.text;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * 
+ */
+public class CssCodeReader extends Reader {
+
+       // Constants ---------------------------------------------------------------
+
+       /**
+        * Constant for configuring a reader to read the document backwards.
+        */
+       public static final int BACKWARD = -1;
+       
+       /**
+        * Constant for configuring a reader to read the document forwards.
+        */
+       public static final int FORWARD = 1;
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The document to read. Is <code>null</code> when the reader is closed.
+        */
+       private IDocument document;
+
+       /**
+        * The direction in which the document should be read. Can be either
+        * {@link CssCodeReader#BACKWARD} or {@link CssCodeReader#FORWARD}. 
+        */
+       private int direction;
+
+       /**
+        * The offset at which to start reading.
+        */
+       private int offset;
+       
+       /**
+        * The offset at which to end reading.
+        */
+       private int end = -1;
+       
+       /**
+        * Whether comments should be skipped.
+        */
+       private boolean skipComments;
+       
+       /**
+        * Whether string literals should be skipped.
+        */
+       private boolean skipStrings;
+       
+       /**
+        * Whether whitespace characters should be skipped.
+        */
+       private boolean skipWhitespace;
+       
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param document the document to read
+        * @param offset the offset at which to start reading
+        */
+       public CssCodeReader(IDocument document, int offset) {
+               this(document, offset, document.getLength() - offset, FORWARD);
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param document the document to read
+        * @param offset the offset at which to start reading
+        * @param length the number of characters to read at most
+        */
+       public CssCodeReader(IDocument document, int offset, int length) {
+               this(document, offset, length, FORWARD);
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param document the document to read
+        * @param offset the offset at which to start reading
+        * @param length the number of characters to read at most
+        * @param direction the reading direction (either
+        *        {@link CssCodeReader#BACKWARD} or {@link CssCodeReader#FORWARD})
+        */
+       public CssCodeReader(IDocument document, int offset, int length,
+               int direction) {
+               this(document, offset, length, direction, true, false, false);
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param document the document to read
+        * @param offset the offset at which to start reading
+        * @param length the number of characters to read at most
+        * @param direction the reading direction (either
+        *        {@link CssCodeReader#BACKWARD} or {@link CssCodeReader#FORWARD})
+        * @param skipComments whether the reader should skip comments
+        * @param skipStrings whether the reader should skip strings
+        * @param skipWhitespace whether the reader should skip whitespace
+        */
+       public CssCodeReader(IDocument document, int offset, int length,
+               int direction, boolean skipComments, boolean skipStrings,
+               boolean skipWhitespace) {
+               if ((direction != BACKWARD) && (direction != FORWARD)) {
+                       throw new IllegalArgumentException();
+               }
+               if ((offset < 0) || (offset > document.getLength())) {
+                       throw new IllegalArgumentException();
+               }
+               this.document = document;
+               this.offset = offset;
+               this.direction = direction;
+               if (direction == FORWARD) {
+                       end = Math.min(document.getLength(), offset + length);
+               } else {
+                       end = Math.max(0, offset - length);
+               }
+               this.skipComments = skipComments;
+               this.skipStrings = skipStrings;
+               this.skipWhitespace = skipWhitespace;
+       }
+
+       // Reader Implementation ---------------------------------------------------
+
+       /**
+        * @see Reader#close()
+        */
+       public void close() {
+               document = null;
+       }
+       
+       /**
+        * @see Reader#read(char[], int, int)
+        */
+       public int read(char[] cbuf, int off, int len) throws IOException {
+               for (int i = off; i < off + len; i++) {
+                       int c = read();
+                       if (c == -1) {
+                               if (i == off) {
+                                       return -1;
+                               } else {
+                                       return i - off;
+                               }
+                       }
+                       cbuf[i] = (char) c;
+               }
+               return len;
+       }
+
+       /**
+        * @see Reader#read()
+        */
+       public int read() throws IOException {
+               if (document == null) {
+                       throw new IllegalStateException();
+               }
+               try {
+                       if (direction == FORWARD) {
+                               return readForwards();
+                       } else {
+                               return readBackwards();
+                       }
+               } catch (BadLocationException ble) {
+                       throw new IOException(ble.getMessage());
+               }
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Returns the document that is being read.
+        * 
+        * @return The document
+        */
+       public IDocument getDocument() {
+               return document;
+       }
+
+       /**
+        * Returns the offset of the last read character. Should only be called 
+        * after read has been called.
+        * 
+        * @return The offset of the last read character
+        */
+       public int getOffset() {
+               return (direction == FORWARD) ? offset - 1 : offset;
+       }
+       
+       /**
+        * Returns whether the reader is currently configured to skip comments.
+        * 
+        * @return <code>true</code> if the reader is skipping comments and
+        *         <code>false</code> otherwise
+        */
+       public boolean isSkippingComments() {
+               return skipComments;
+       }
+
+       /**
+        * Configures the reader to skip comment blocks.
+        * 
+        * @param skipComments Whether comments should be skipped
+        */
+       public void setSkipComments(boolean skipComments) {
+               this.skipComments = skipComments;
+       }
+
+       /**
+        * Returns whether the reader is currently configured to skip string
+        * literals.
+        * 
+        * @return <code>true</code> if the reader is skipping strings and
+        *         <code>false</code> otherwise
+        */
+       public boolean isSkippingStrings() {
+               return skipStrings;
+       }
+
+       /**
+        * Configures the reader to skip strings.
+        * 
+        * @param skipStrings Whether strings should be skipped
+        */
+       public void setSkipStrings(boolean skipStrings) {
+               this.skipStrings = skipStrings;
+       }
+
+       /**
+        * Returns whether the reader is currently configured to skip whitespace.
+        * 
+        * @return <code>true</code> if the reader is skipping whitespace and
+        *         <code>false</code> otherwise
+        */
+       public boolean isSkippingWhitespace() {
+               return skipWhitespace;
+       }
+
+       /**
+        * Configures the reader to skip whitespace.
+        * 
+        * @param skipWhitespace Whether whitespace should be skipped
+        */
+       public void setSkipWhitespace(boolean skipWhitespace) {
+               this.skipWhitespace = skipWhitespace;
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private int readBackwards() throws BadLocationException {
+               while (offset > 0) {
+                       offset--;
+                       char current = document.getChar(offset);
+                       switch (current) {
+                               case '/': {
+                                       if (skipComments && (offset > 1)) {
+                                               char next = document.getChar(offset - 1);
+                                               if (next == '*') {
+                                                       // a comment ends, advance to the comment start
+                                                       offset -= 2;
+                                                       skipUntilStartOfComment();
+                                                       continue;
+                                               }
+                                       }
+                                       break;
+                               }
+                               case '"':
+                               case '\'': {
+                                       if (skipStrings) {
+                                               offset--;
+                                               skipUntilStartOfString(current);
+                                               continue;
+                                       }
+                                       break;
+                               }
+                               default: {
+                                       if (skipWhitespace && Character.isWhitespace(current)) {
+                                               continue;
+                                       }
+                               }
+                       }
+                       return current;
+               }
+               return -1;
+       }
+
+       private int readForwards() throws BadLocationException {
+               while (offset < end) {
+                       char current = document.getChar(offset++);
+                       switch (current) {
+                               case '/': {
+                                       if (skipComments && (offset < end)) {
+                                               char next = document.getChar(offset);
+                                               if (next == '*') {
+                                                       // a comment starts, advance to the comment end
+                                                       offset++;
+                                                       skipUntilEndOfComment();
+                                                       continue;
+                                               }
+                                       }
+                                       break;
+                               }
+                               case '"':
+                               case '\'': {
+                                       if (skipStrings) {
+                                               skipUntilEndOfString(current);
+                                               continue;
+                                       }
+                                       break;
+                               }
+                               default: {
+                                       if (skipWhitespace && Character.isWhitespace(current)) {
+                                               offset++;
+                                               continue;
+                                       }
+                               }
+                       }
+                       return current;
+               }
+               return -1;
+       }
+
+       private void skipUntilStartOfComment() throws BadLocationException {
+               while (offset > 0) {
+                       char current = document.getChar(offset--);
+                       if ((current == '*') && (0 <= offset)
+                        && (document.getChar(offset) == '/')) {
+                               return;
+                       }
+               }
+       }
+
+       private void skipUntilEndOfComment() throws BadLocationException {
+               while (offset < end) {
+                       char current = document.getChar(offset++);
+                       if (current == '*') {
+                               if ((offset < end)
+                                && (document.getChar(offset) == '/')) {
+                                       offset++;
+                                       return;
+                               }
+                       }
+               }
+       }
+
+       private void skipUntilStartOfString(char delimiter)
+               throws BadLocationException {
+               while (offset > 0) {
+                       char current = document.getChar(offset);
+                       if (current == delimiter) {
+                               if (!((0 <= offset) && document.getChar(offset - 1) == '\\')) {
+                                       return;
+                               }
+                       }
+                       offset--;
+               }
+       }
+
+       private void skipUntilEndOfString(char delimiter)
+               throws BadLocationException {
+               while (offset < end) {
+                       char current = document.getChar(offset++);
+                       if (current == '\\') {
+                               // ignore escaped characters
+                               offset++;
+                       } else if (current == delimiter) {
+                               return;
+                       }
+               }
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/text/CssTextUtils.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/internal/text/CssTextUtils.java
new file mode 100644 (file)
index 0000000..f545db5
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * 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: CssTextUtils.java,v 1.1 2004-09-02 18:07:13 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.internal.text;
+
+import java.io.IOException;
+
+import net.sourceforge.phpeclipse.css.core.CssCore;
+
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * Various utility methods for handling CSS source.
+ * 
+ * TODO Probably refactor so this class isn't needed
+ */
+public final class CssTextUtils {
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Hidden.
+        */
+       private CssTextUtils() {
+               // Hidden
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       public static int findMatchingClosingPeer(IDocument document, int offset,
+               char openingPeer) {
+               try {
+                       CssCodeReader reader = new CssCodeReader(document, offset,
+                               document.getLength(), CssCodeReader.FORWARD);
+                       char closingChar = getPeerCharacter(openingPeer);
+                       int stack = 1;
+                       int c = reader.read();
+                       while (c != -1) {
+                               if ((c == openingPeer) && (c != closingChar)) {
+                                       stack++;
+                               } else if (c == closingChar) {
+                                       stack--;
+                               }
+                               if (stack == 0) {
+                                       return reader.getOffset();
+                               }
+                               c = reader.read();
+                       }
+               } catch (IOException e) {
+                       CssCore.log(
+                               "Failed to find matching closing peer for '" + //$NON-NLS-1$
+                               openingPeer + '\'', e);
+               }
+               return -1;
+       }
+
+       public static int findMatchingOpeningPeer(IDocument document, int offset,
+               char closingPeer) {
+               try {
+                       CssCodeReader reader = new CssCodeReader(document, offset + 1,
+                               document.getLength(), CssCodeReader.BACKWARD);
+                       char openingChar = getPeerCharacter(closingPeer);
+                       int stack = 1;
+                       int c = reader.read();
+                       while (c != -1) {
+                               if ((c == closingPeer) && (c != openingChar)) {
+                                       stack++;
+                               } else if (c == openingChar) {
+                                       stack--;
+                               }
+                               if (stack == 0) {
+                                       return reader.getOffset();
+                               }
+                               c = reader.read();
+                       }
+               } catch (IOException e) {
+                       CssCore.log(
+                               "Failed to find matching opening peer for '" + //$NON-NLS-1$
+                               closingPeer + '\'', e);
+               }
+               return  -1;
+       }
+
+       public static char getPeerCharacter(char c) {
+               switch (c) {
+                       case '{': return '}';
+                       case '}': return '{';
+                       case '[': return ']';
+                       case ']': return '[';
+                       case '(': return ')';
+                       case ')': return '(';
+                       case '"': return '"';
+                       case '\'': return '\'';
+                       default: return 0;
+               }
+       }
+
+       public static boolean isCssIdentifierPart(char c) {
+               return ((c == '_') || Character.isLetterOrDigit(c) || (c == '-'));
+       }
+
+       public static boolean isCssIdentifierStart(char c) {
+               return ((c == '_') || Character.isLetter(c));
+       }
+
+       public static boolean isCssNumberPart(char c) {
+               return ((c == '.') || Character.isDigit(c));
+       }
+
+       public static boolean isCssNumberStart(char c) {
+               return ((c == '-') || (c == '.') || Character.isDigit(c));
+       }
+
+       public static boolean isCssWhitespace(char c) {
+               return Character.isWhitespace(c);
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/model/IAtRule.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/model/IAtRule.java
new file mode 100644 (file)
index 0000000..c07f478
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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
+ * 
+ * $Id: IAtRule.java,v 1.1 2004-09-02 18:07:11 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.model;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+
+/**
+ * 
+ */
+public interface IAtRule extends IRule {
+
+       ISourceReference getName();
+
+       // TODO Maybe choose a more descriptive term for this property?
+       ISourceReference getValue();
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/model/IDeclaration.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/model/IDeclaration.java
new file mode 100644 (file)
index 0000000..f06e476
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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
+ * 
+ * $Id: IDeclaration.java,v 1.1 2004-09-02 18:07:11 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.model;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+
+/**
+ * Represents a single CSS declaration.
+ */
+public interface IDeclaration extends ISourceReference {
+
+       /**
+        * Returns the rule that contains this declaration.
+        * 
+        * @return the rule containing this declaration, or <code>null</code> if the
+        *         declaration doesn't belong to a specific rule
+        */
+       IRule getRule();
+
+       /**
+        * Returns the source reference representing the property.
+        * 
+        * @return the property
+        */
+       ISourceReference getProperty();
+
+       /**
+        * Returns the source reference consisting of the value assigned to the
+        * property.
+        * 
+        * @return the value
+        */
+       ISourceReference getValue();
+
+       /**
+        * Returns the source reference representing the priority (mostly, that will
+        * be "<code>!important</code>") of the declaration, or <code>null</code>
+        * if no special priority was specified.
+        * 
+        * @return the priority
+        */
+       ISourceReference getPriority();
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/model/IPropertyInfo.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/model/IPropertyInfo.java
new file mode 100644 (file)
index 0000000..58e658d
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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
+ * 
+ * $Id: IPropertyInfo.java,v 1.1 2004-09-02 18:07:11 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.model;
+
+/**
+ * Encapsulates information about a specific property. 
+ */
+public interface IPropertyInfo {
+
+       String getName();
+
+       String getCategory();
+
+       String getDescription();
+
+       boolean isShorthand();
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/model/IRule.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/model/IRule.java
new file mode 100644 (file)
index 0000000..fb61fa7
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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
+ * 
+ * $Id: IRule.java,v 1.1 2004-09-02 18:07:11 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.model;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+
+import org.eclipse.core.runtime.IAdaptable;
+
+/**
+ * 
+ */
+public interface IRule extends IAdaptable, ISourceReference {
+
+       /**
+        * Returns the style sheet that contains this rule.
+        * 
+        * @return the style sheet
+        */
+       IStyleSheet getStyleSheet();
+
+       /**
+        * Returns the rule in which this rule is nested, or <code>null</code> if 
+        * this rule is at the top level of the style sheet.
+        * 
+        * @return the parent rule
+        */
+       IRule getParent();
+
+       IRule[] getChildren();
+
+       /**
+        * Returns the declaration at the specified offset into the rule.
+        * 
+        * @param offset the offset
+        * @return the declaration at the offset, or <code>null</code> if no
+        *         declaration is found at that position
+        */
+       IDeclaration getDeclarationAt(int offset);
+
+       IDeclaration[] getDeclarations();
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/model/IStyleRule.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/model/IStyleRule.java
new file mode 100644 (file)
index 0000000..e8dcd47
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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
+ * 
+ * $Id: IStyleRule.java,v 1.1 2004-09-02 18:07:11 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.model;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+
+/**
+ * 
+ */
+public interface IStyleRule extends IRule {
+
+       ISourceReference getSelector();
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/model/IStyleSheet.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/model/IStyleSheet.java
new file mode 100644 (file)
index 0000000..4a2239d
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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
+ * 
+ * $Id: IStyleSheet.java,v 1.1 2004-09-02 18:07:11 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.model;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.css.core.parser.IProblemCollector;
+import net.sourceforge.phpeclipse.css.core.parser.LexicalErrorException;
+import net.sourceforge.phpeclipse.css.core.parser.SyntaxErrorException;
+
+import org.eclipse.core.runtime.IAdaptable;
+
+/**
+ * 
+ */
+public interface IStyleSheet
+       extends IAdaptable, ISourceReference {
+
+       /**
+        * Returns the rule at the specified offset into the document.
+        * 
+        * @param offset the offset
+        * @return the rule at the offset, or <code>null</code> if no rule is found
+        *         at that position
+        */
+       IRule getRuleAt(int offset);
+
+       /**
+        * Returns the list of rules in the order they have been defined in the 
+        * style sheet.
+        * 
+        * @return the list of rules contained by the style sheet
+        */
+       IRule[] getRules();
+
+       void reconcile(IProblemCollector problemCollector)
+               throws LexicalErrorException, SyntaxErrorException;
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/ICssParser.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/ICssParser.java
new file mode 100644 (file)
index 0000000..f3b4117
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * 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
+ * 
+ * $Id: ICssParser.java,v 1.1 2004-09-02 18:07:12 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.parser;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.css.core.model.IDeclaration;
+import net.sourceforge.phpeclipse.css.core.model.IRule;
+import net.sourceforge.phpeclipse.css.core.model.IStyleSheet;
+
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * Interface for classes that implement the parsing of CSS source code into a
+ * syntax tree.
+ * 
+ * TODO Add a way to only parse a specific range of an IDocument
+ */
+public interface ICssParser extends IProblemReporter {
+
+       /**
+        * Parses the given document as a CSS style sheet. If a problem collector
+        * is provided, lexical and syntax errors are reported to it rather than
+        * throwing exceptions.
+        * 
+        * @return a list containing the parsed style rules
+        * @throws LexicalErrorException if a lexical error is reported by the
+        *         lexical scanner
+        * @throws SyntaxErrorException if a syntax error has been encountered from
+        *         which recovery is not possible
+        */
+       IRule[] parseRules(IStyleSheet styleSheet)
+               throws LexicalErrorException, SyntaxErrorException;
+
+       /**
+        * Parses the source at the current position to extract a single rule.
+        * 
+        * @param parentRule the parent of the rule to parse, or <code>null</code>
+        *        if there is no parent
+        * @return the parsed rule
+        * @throws LexicalErrorException if a lexical error is reported by the
+        *         lexical scanner
+        * @throws SyntaxErrorException if a syntax error has been encountered from
+        *         which recovery is not possible
+        */
+       IRule parseRule(IStyleSheet styleSheet, IRule parentRule)
+               throws LexicalErrorException, SyntaxErrorException;
+
+       /**
+        * Parses the source at the current position to extract a selector.
+        * 
+        * @return the parsed selector
+        * @throws LexicalErrorException if a lexical error is reported by the
+        *         lexical scanner
+        * @throws SyntaxErrorException if a syntax error has been encountered from
+        *         which recovery is not possible
+        */
+       ISourceReference parseSelector(IRule rule)
+               throws LexicalErrorException, SyntaxErrorException;
+
+       /**
+        * Parses the source at the current position to extract a single
+        * declaration.
+        * 
+        * @return the parsed declaration
+        * @throws LexicalErrorException if a lexical error is reported by the
+        *         lexical scanner
+        * @throws SyntaxErrorException if a syntax error has been encountered from
+        *         which recovery is not possible
+        */
+       IDeclaration parseDeclaration(IRule rule)
+               throws LexicalErrorException, SyntaxErrorException;
+
+       /**
+        * Sets the document containing the style sheet source to process.
+        * 
+        * @param document the document containing the source
+        */
+       void setSource(IDocument document);
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/ICssScanner.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/ICssScanner.java
new file mode 100644 (file)
index 0000000..368bc52
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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
+ * 
+ * $Id: ICssScanner.java,v 1.1 2004-09-02 18:07:12 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.parser;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+
+/**
+ * Interface for classes that implement the lexical scanning of CSS source code.
+ * 
+ * TODO Add a way to only parse a specific range of an IDocument
+ */
+public interface ICssScanner extends IProblemReporter {
+
+       // Methods -----------------------------------------------------------------
+
+       /**
+        * Returns the starting position of the current token inside the original 
+        * source. This position is zero-based and inclusive. It corresponds to the 
+        * position of the first character which is part of this token.
+        * 
+        * @return the starting position of the current token inside the original
+        *         source
+        */
+       IRegion getTokenRegion();
+
+       /**
+        * Read the next token in the source, and returns the value corresponding
+        * to the symbolic constant corresponding to the token type (as defined by
+        * the constants in this interface), or with read character itself.
+        * 
+        * @return the next token
+        * @throws LexicalErrorException in case a lexical error was detected while 
+        *         trying to retrieve the current token
+        */
+       int getNextToken() throws LexicalErrorException;
+
+       /**
+        * Sets the document that contains the source style sheet.
+        * 
+        * TODO Add parameters for range limitation
+        * 
+        * @param source The document containing the style sheet source
+        */
+       void setSource(IDocument source);
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/ICssTokens.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/ICssTokens.java
new file mode 100644 (file)
index 0000000..9743b12
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * 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
+ * 
+ * $Id: ICssTokens.java,v 1.1 2004-09-02 18:07:12 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.parser;
+
+/**
+ * Symbolic constants for tokens generated by the CSS scanner.
+ */
+public interface ICssTokens {
+
+       // Constants ---------------------------------------------------------------
+
+       int EOF = -1;
+
+       int CDO = 1;
+       int CDC = 2;
+
+       int IDENT = 'i';
+       int NUM = 'n';
+       int STRING = 's';
+
+       int AT = '@';
+       int COLON = ':';
+       int LBRACE = '{';
+       int LBRACKET = '[';
+       int LPAREN = '(';
+       int RBRACE = '}';
+       int RBRACKET = ']';
+       int RPAREN = ')';
+       int SEMICOLON = ';';
+       int EXCLAMATION = '!';
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/IProblem.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/IProblem.java
new file mode 100644 (file)
index 0000000..e05d6a0
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * 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
+ * 
+ * $Id: IProblem.java,v 1.1 2004-09-02 18:07:12 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.parser;
+
+/**
+ * 
+ */
+public interface IProblem {
+
+       /**
+        * Returns the problem identifier.
+        * 
+        * @return the problem id
+        */
+       String getId();
+
+       /**
+        * Returns a localized, human-readable message string which describes the
+        * problem.
+        * 
+        * @return the problem message
+        */
+       String getMessage();
+
+       /**
+        * Returns the file name in which the problem was found.
+        * 
+        * @return the file name in which the problem was found
+        */
+       String getOriginatingFileName();
+       
+       /**
+        * Returns the end position of the problem (inclusive).
+        * 
+        * @return the end position of the problem), or -1 if unknown
+        */
+       int getSourceEnd();
+
+       /**
+        * Returns the line number of the source where the problem begins.
+        * 
+        * @return the line number of the source where the problem begins
+        */
+       int getSourceLineNumber();
+
+       /**
+        * Returns the start position of the problem (inclusive).
+        * 
+        * @return the start position of the problem, or -1 if unknown
+        */
+       int getSourceStart();
+
+       /**
+        * Returns whether the problem is an error.
+        * 
+        * @return <code>true</code> if the problem is an error, <code>false</code>
+        *         otherwise
+        */
+       boolean isError();
+
+       /**
+        * Returns whether the problem is a warning.
+        * 
+        * @return <code>true</code> if the problem is a warning, <code>false</code>
+        *         otherwise
+        */
+       boolean isWarning();
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/IProblemCollector.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/IProblemCollector.java
new file mode 100644 (file)
index 0000000..3212e5a
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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
+ * 
+ * $Id: IProblemCollector.java,v 1.1 2004-09-02 18:07:12 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.parser;
+
+/**
+ * 
+ */
+public interface IProblemCollector {
+
+       /**
+        * Notification of an error or warning.
+        * 
+        * @param problem the discovered problem
+        */ 
+       void addProblem(IProblem problem);
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/IProblemReporter.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/IProblemReporter.java
new file mode 100644 (file)
index 0000000..b5b27d6
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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
+ * 
+ * $Id: IProblemReporter.java,v 1.1 2004-09-02 18:07:12 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.parser;
+
+/**
+ * Basic interface for classes that report errors to a problem collector.
+ */
+public interface IProblemReporter {
+
+       /**
+        * Sets the problem collector that should be used by the reporter.
+        * 
+        * @param problemCollector the problem collector to use
+        */
+       void setProblemCollector(IProblemCollector problemCollector);
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/LexicalErrorException.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/LexicalErrorException.java
new file mode 100644 (file)
index 0000000..502eb2c
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: LexicalErrorException.java,v 1.1 2004-09-02 18:07:12 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.parser;
+
+/**
+ * 
+ */
+public class LexicalErrorException extends Exception {
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        */
+       public LexicalErrorException() {
+               super();
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param s the exception message
+        */
+       public LexicalErrorException(String s) {
+               super(s);
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/SyntaxErrorException.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/parser/SyntaxErrorException.java
new file mode 100644 (file)
index 0000000..5f1153d
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * 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: SyntaxErrorException.java,v 1.1 2004-09-02 18:07:12 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.parser;
+
+/**
+ * 
+ */
+public class SyntaxErrorException extends Exception {
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The line number at which the error was detected in the source.
+        */
+       private int lineNumber;
+
+       /**
+        * The offset into the document.
+        */
+       private int offset;
+
+       /**
+        * The length of the source range affected by the syntax error.
+        */
+       private int length;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        */
+       public SyntaxErrorException() {
+               super();
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param message the exception message
+        */
+       public SyntaxErrorException(String message) {
+               super(message);
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param message the exception message
+        * @param lineNumber the line number
+        * @param offset the offset
+        * @param length the length
+        */
+       public SyntaxErrorException(String message, int lineNumber, int offset,
+               int length) {
+               super(message + " (" + lineNumber + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+               this.lineNumber = lineNumber;
+               this.offset = offset;
+               this.length = length;
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Returns the length of the offending code
+        * 
+        * @return the length of the offending code
+        */
+       public final int getLength() {
+               return this.length;
+       }
+
+       /**
+        * Returns the line number at which the error was detected.
+        * 
+        * @return the line number
+        */
+       public final int getLineNumber() {
+               return this.lineNumber;
+       }
+
+       /**
+        * Returns the offset of the offending code
+        * 
+        * @return the offset of the offending code
+        */
+       public final int getOffset() {
+               return this.offset;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/profiles/AbstractProfile.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/profiles/AbstractProfile.java
new file mode 100644 (file)
index 0000000..eeb4420
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * 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: AbstractProfile.java,v 1.1 2004-09-02 18:07:14 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.profiles;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import net.sourceforge.phpeclipse.css.core.internal.model.PropertyInfo;
+import net.sourceforge.phpeclipse.css.core.model.IPropertyInfo;
+
+/**
+ * Abstract implementation of the <code>IProfile</code> interface.
+ */
+public abstract class AbstractProfile implements IProfile {
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The associated descriptor, as passed into the constructor by the profile
+        * manager when the profile is instantiated.
+        */
+       private IProfileDescriptor descriptor;
+
+       /**
+        * Map of the property names of this profile, containing the 
+        * <code>IPropertyInfo</code> objects keyed by property name.
+        */
+       private Map properties = new HashMap();
+
+       /**
+        * Set of the at rule keywords known to the profile.
+        */
+       private Set atKeywords = new HashSet();
+
+       /**
+        * Set of the at pseudo-classes known to the profile.
+        */
+       private Set pseudoClasses = new HashSet();
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param descriptor the profile descriptor
+        */
+       public AbstractProfile(IProfileDescriptor descriptor) {
+               this.descriptor = descriptor;
+       }
+
+       // IProfile Implementation -------------------------------------------------
+
+       /**
+        * @see net.sourceforge.phpeclipse.css.core.profiles.IProfile#getDescriptor()
+        */
+       public final IProfileDescriptor getDescriptor() {
+               return this.descriptor;
+       }
+
+       /**
+        * @see IProfile#getAtKeywords()
+        */
+       public final Collection getAtKeywords() {
+               return Collections.unmodifiableSet(this.atKeywords);
+       }
+
+       /**
+        * @see IProfile#getProperties()
+        */
+       public final Collection getProperties() {
+               return Collections.unmodifiableSet(this.properties.keySet());
+       }
+
+       /**
+        * @see IProfile#getPropertyInfo(java.lang.String)
+        */
+       public final IPropertyInfo getPropertyInfo(String propertyName) {
+               return (IPropertyInfo) this.properties.get(propertyName);
+       }
+
+       /**
+        * @see IProfile#getPseudoClassNames()
+        */
+       public final Collection getPseudoClassNames() {
+               return Collections.unmodifiableSet(this.pseudoClasses);
+       }
+
+       // Protected Methods -------------------------------------------------------
+
+       protected final void addAtKeyword(String atKeyword) {
+               this.atKeywords.add(atKeyword);
+       }
+
+       protected final void addProperty(String name, String category) {
+               addProperty(new PropertyInfo(name, category));
+       }
+
+       protected final void addProperty(String name, String category,
+               boolean shorthand) {
+               addProperty(new PropertyInfo(name, category, shorthand));
+       }
+
+       protected final void addProperty(IPropertyInfo info) {
+               this.properties.put(info.getName(), info);
+       }
+
+       protected final void addPseudoClass(String pseudoClass) {
+               this.pseudoClasses.add(pseudoClass);
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/profiles/Css1Profile.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/profiles/Css1Profile.java
new file mode 100644 (file)
index 0000000..a7fb0e3
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: Css1Profile.java,v 1.1 2004-09-02 18:07:14 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.profiles;
+
+import net.sourceforge.phpeclipse.css.core.internal.CssCoreMessages;
+
+/**
+ * Implementation of the CSS Level 1 profile
+ * (<a href="http://www.w3.org/TR/CSS1">http://www.w3.org/TR/CSS1</a>).
+ */
+public class Css1Profile extends AbstractProfile {
+
+       // Constants ---------------------------------------------------------------
+
+       protected static final String CATEGORY_BOX =
+               CssCoreMessages.getString("CssProfile.category.box"); //$NON-NLS-1$
+       protected static final String CATEGORY_COLOR_BACKGROUND =
+               CssCoreMessages.getString(
+                       "CssProfile.category.colorAndBackground"); //$NON-NLS-1$
+       protected static final String CATEGORY_FONT =
+               CssCoreMessages.getString("CssProfile.category.font"); //$NON-NLS-1$
+       protected static final String CATEGORY_TEXT =
+               CssCoreMessages.getString("CssProfile.category.text"); //$NON-NLS-1$
+       protected static final String CATEGORY_VISUAL_FORMATTING =
+               CssCoreMessages.getString(
+                       "CssProfile.category.visualFormatting"); //$NON-NLS-1$
+
+       // Constructors ------------------------------------------------------------
+
+       public Css1Profile(IProfileDescriptor descriptor) {
+               super(descriptor);
+               initializeAtKeywords();
+               initializeProperties();
+               initializePseudoClasses();
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private void initializeAtKeywords() {
+               addAtKeyword("import"); //$NON-NLS-1$
+       }
+
+       private void initializeProperties() {
+               addProperty("font", CATEGORY_FONT, true); //$NON-NLS-1$
+               addProperty("font-family", CATEGORY_FONT); //$NON-NLS-1$
+               addProperty("font-size", CATEGORY_FONT); //$NON-NLS-1$
+               addProperty("font-style", CATEGORY_FONT); //$NON-NLS-1$
+               addProperty("font-variant", CATEGORY_FONT); //$NON-NLS-1$
+               addProperty("font-weight", CATEGORY_FONT); //$NON-NLS-1$
+               addProperty("background", //$NON-NLS-1$
+                       CATEGORY_COLOR_BACKGROUND, true);
+               addProperty("background-attachment", //$NON-NLS-1$
+                       CATEGORY_COLOR_BACKGROUND);
+               addProperty("background-color", //$NON-NLS-1$
+                       CATEGORY_COLOR_BACKGROUND);
+               addProperty("background-image", //$NON-NLS-1$
+                       CATEGORY_COLOR_BACKGROUND);
+               addProperty("background-position", //$NON-NLS-1$
+                       CATEGORY_COLOR_BACKGROUND);
+               addProperty("background-repeat", //$NON-NLS-1$
+                       CATEGORY_COLOR_BACKGROUND);
+               addProperty("color", CATEGORY_COLOR_BACKGROUND); //$NON-NLS-1$
+               addProperty("border", CATEGORY_BOX, true); //$NON-NLS-1$
+               addProperty("border-bottom", CATEGORY_BOX, true); //$NON-NLS-1$
+               addProperty("border-bottom-width", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("border-color", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("border-left", CATEGORY_BOX, true); //$NON-NLS-1$
+               addProperty("border-left-width", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("border-right", CATEGORY_BOX, true); //$NON-NLS-1$
+               addProperty("border-right-width", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("border-style", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("border-top", CATEGORY_BOX, true); //$NON-NLS-1$
+               addProperty("border-top-width", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("border-width", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("clear", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("float", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("height", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("margin", CATEGORY_BOX, true); //$NON-NLS-1$
+               addProperty("margin-bottom", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("margin-left", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("margin-right", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("margin-top", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("padding", CATEGORY_BOX, true); //$NON-NLS-1$
+               addProperty("padding-bottom", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("padding-left", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("padding-right", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("padding-top", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("width", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("letter-spacing", CATEGORY_TEXT); //$NON-NLS-1$
+               addProperty("line-height", CATEGORY_TEXT); //$NON-NLS-1$
+               addProperty("text-align", CATEGORY_TEXT); //$NON-NLS-1$
+               addProperty("text-decoration", CATEGORY_TEXT); //$NON-NLS-1$
+               addProperty("text-indent", CATEGORY_TEXT); //$NON-NLS-1$
+               addProperty("text-transform", CATEGORY_TEXT); //$NON-NLS-1$
+               addProperty("vertical-align", CATEGORY_TEXT); //$NON-NLS-1$
+               addProperty("white-space", CATEGORY_TEXT); //$NON-NLS-1$
+               addProperty("word-spacing", CATEGORY_TEXT); //$NON-NLS-1$
+               addProperty("display", //$NON-NLS-1$
+                       CATEGORY_VISUAL_FORMATTING);
+               addProperty("list-style", //$NON-NLS-1$
+                       CATEGORY_VISUAL_FORMATTING, true);
+               addProperty("list-style-image", //$NON-NLS-1$
+                       CATEGORY_VISUAL_FORMATTING);
+               addProperty("list-style-position", //$NON-NLS-1$
+                       CATEGORY_VISUAL_FORMATTING);
+               addProperty("list-style-type", //$NON-NLS-1$
+                       CATEGORY_VISUAL_FORMATTING);
+       }
+
+       private void initializePseudoClasses() {
+               addPseudoClass("active"); //$NON-NLS-1$
+               addPseudoClass("first-letter"); //$NON-NLS-1$
+               addPseudoClass("first-line"); //$NON-NLS-1$
+               addPseudoClass("link"); //$NON-NLS-1$
+               addPseudoClass("visited"); //$NON-NLS-1$
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/profiles/Css2Profile.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/profiles/Css2Profile.java
new file mode 100644 (file)
index 0000000..6dc99d1
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * 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: Css2Profile.java,v 1.1 2004-09-02 18:07:14 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.profiles;
+
+import net.sourceforge.phpeclipse.css.core.internal.CssCoreMessages;
+
+/**
+ * Implementation of the CSS Level 2 profile
+ * (<a href="http://www.w3.org/TR/CSS2">http://www.w3.org/TR/CSS2</a>).
+ */
+public class Css2Profile extends Css1Profile {
+
+       // Constants ---------------------------------------------------------------
+
+       protected static final String CATEGORY_AURAL =
+               CssCoreMessages.getString("CssProfile.category.aural"); //$NON-NLS-1$
+       protected static final String CATEGORY_GENERATED_CONTENT =
+               CssCoreMessages.getString(
+                       "CssProfile.category.generatedContent"); //$NON-NLS-1$
+       protected static final String CATEGORY_PAGED_MEDIA =
+               CssCoreMessages.getString(
+                       "CssProfile.category.pagedMedia"); //$NON-NLS-1$
+       protected static final String CATEGORY_TABLE =
+               CssCoreMessages.getString("CssProfile.category.table"); //$NON-NLS-1$
+       protected static final String CATEGORY_USER_INTERFACE =
+               CssCoreMessages.getString(
+                       "CssProfile.category.userInterface"); //$NON-NLS-1$
+       protected static final String CATEGORY_VISUAL_EFFECTS =
+               CssCoreMessages.getString(
+                       "CssProfile.category.visualEffects"); //$NON-NLS-1$
+
+       // Constructors ------------------------------------------------------------
+
+       public Css2Profile(IProfileDescriptor descriptor) {
+               super(descriptor);
+               initializeAtKeywords();
+               initializeProperties();
+               initializePseudoClasses();
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private void initializeAtKeywords() {
+               addAtKeyword("charset"); //$NON-NLS-1$
+               addAtKeyword("font-face"); //$NON-NLS-1$
+               addAtKeyword("media"); //$NON-NLS-1$
+               addAtKeyword("page"); //$NON-NLS-1$
+       }
+
+       private void initializeProperties() {
+               addProperty("font-stretch", CATEGORY_FONT); //$NON-NLS-1$
+               addProperty("unicode-bidi", CATEGORY_TEXT); //$NON-NLS-1$
+               addProperty("direction", CATEGORY_TEXT); //$NON-NLS-1$
+               addProperty("border-bottom-color", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("border-bottom-style", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("border-collapse", CATEGORY_TABLE); //$NON-NLS-1$
+               addProperty("border-left-color", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("border-left-style", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("border-right-color", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("border-right-style", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("border-top-color", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("border-top-style", CATEGORY_BOX); //$NON-NLS-1$
+               addProperty("border-spacing", CATEGORY_TABLE); //$NON-NLS-1$
+               addProperty("caption-side", CATEGORY_TABLE); //$NON-NLS-1$
+               addProperty("empty-cells", CATEGORY_TABLE); //$NON-NLS-1$
+               addProperty("table-layout", CATEGORY_TABLE); //$NON-NLS-1$
+               addProperty("bottom", CATEGORY_VISUAL_FORMATTING); //$NON-NLS-1$
+               addProperty("clip", CATEGORY_VISUAL_EFFECTS); //$NON-NLS-1$
+               addProperty("content", CATEGORY_GENERATED_CONTENT); //$NON-NLS-1$
+               addProperty("counter-increment", //$NON-NLS-1$
+                       CATEGORY_GENERATED_CONTENT);
+               addProperty("counter-reset", CATEGORY_GENERATED_CONTENT); //$NON-NLS-1$
+               addProperty("azimuth", CATEGORY_AURAL); //$NON-NLS-1$
+               addProperty("cue", CATEGORY_AURAL, true); //$NON-NLS-1$
+               addProperty("cue-after", CATEGORY_AURAL); //$NON-NLS-1$
+               addProperty("cue-before", CATEGORY_AURAL); //$NON-NLS-1$
+               addProperty("cursor", CATEGORY_USER_INTERFACE); //$NON-NLS-1$
+               addProperty("elevation", CATEGORY_AURAL); //$NON-NLS-1$
+               addProperty("left", CATEGORY_VISUAL_FORMATTING); //$NON-NLS-1$
+               addProperty("max-height", CATEGORY_VISUAL_FORMATTING); //$NON-NLS-1$
+               addProperty("max-width", CATEGORY_VISUAL_FORMATTING); //$NON-NLS-1$
+               addProperty("min-height", CATEGORY_VISUAL_FORMATTING); //$NON-NLS-1$
+               addProperty("min-width", CATEGORY_VISUAL_FORMATTING); //$NON-NLS-1$
+               addProperty("orphans", CATEGORY_PAGED_MEDIA); //$NON-NLS-1$
+               addProperty("outline", CATEGORY_USER_INTERFACE); //$NON-NLS-1$
+               addProperty("outline-color", CATEGORY_USER_INTERFACE); //$NON-NLS-1$
+               addProperty("outline-style", CATEGORY_USER_INTERFACE); //$NON-NLS-1$
+               addProperty("outline-width", CATEGORY_USER_INTERFACE); //$NON-NLS-1$
+               addProperty("overflow", CATEGORY_VISUAL_EFFECTS); //$NON-NLS-1$
+               addProperty("page-break-after", CATEGORY_PAGED_MEDIA); //$NON-NLS-1$
+               addProperty("page-break-before", CATEGORY_PAGED_MEDIA); //$NON-NLS-1$
+               addProperty("page-break-inside", CATEGORY_PAGED_MEDIA); //$NON-NLS-1$
+               addProperty("pause", CATEGORY_AURAL, true); //$NON-NLS-1$
+               addProperty("pause-after", CATEGORY_AURAL); //$NON-NLS-1$
+               addProperty("pause-before", CATEGORY_AURAL); //$NON-NLS-1$
+               addProperty("pitch", CATEGORY_AURAL); //$NON-NLS-1$
+               addProperty("pitch-range", CATEGORY_AURAL); //$NON-NLS-1$
+               addProperty("play-during", CATEGORY_AURAL); //$NON-NLS-1$
+               addProperty("position", CATEGORY_VISUAL_FORMATTING); //$NON-NLS-1$
+               addProperty("quotes", CATEGORY_AURAL); //$NON-NLS-1$
+               addProperty("richness", CATEGORY_AURAL); //$NON-NLS-1$
+               addProperty("right", CATEGORY_VISUAL_FORMATTING); //$NON-NLS-1$
+               addProperty("speak", CATEGORY_AURAL, true); //$NON-NLS-1$
+               addProperty("speak-header", CATEGORY_AURAL); //$NON-NLS-1$
+               addProperty("speak-numeral", CATEGORY_AURAL); //$NON-NLS-1$
+               addProperty("speak-punctuation", CATEGORY_AURAL); //$NON-NLS-1$
+               addProperty("speech-rate", CATEGORY_AURAL); //$NON-NLS-1$
+               addProperty("text-shadow", CATEGORY_TEXT); //$NON-NLS-1$
+               addProperty("stress", CATEGORY_AURAL); //$NON-NLS-1$
+               addProperty("top", CATEGORY_VISUAL_FORMATTING); //$NON-NLS-1$
+               addProperty("visibility", CATEGORY_VISUAL_EFFECTS); //$NON-NLS-1$
+               addProperty("voice-family", CATEGORY_AURAL); //$NON-NLS-1$
+               addProperty("volume", CATEGORY_AURAL); //$NON-NLS-1$
+               addProperty("widows", CATEGORY_PAGED_MEDIA); //$NON-NLS-1$
+               addProperty("z-index", CATEGORY_VISUAL_FORMATTING); //$NON-NLS-1$
+       }
+
+       private void initializePseudoClasses() {
+               addPseudoClass("after"); //$NON-NLS-1$
+               addPseudoClass("before"); //$NON-NLS-1$
+               addPseudoClass("first-child"); //$NON-NLS-1$
+               addPseudoClass("focus"); //$NON-NLS-1$
+               addPseudoClass("hover"); //$NON-NLS-1$
+               addPseudoClass("land"); //$NON-NLS-1$
+               addPseudoClass("left"); //$NON-NLS-1$
+               addPseudoClass("right"); //$NON-NLS-1$
+       }
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/profiles/IProfile.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/profiles/IProfile.java
new file mode 100644 (file)
index 0000000..36c22c3
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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
+ * 
+ * $Id: IProfile.java,v 1.1 2004-09-02 18:07:14 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.profiles;
+
+import java.util.Collection;
+
+import net.sourceforge.phpeclipse.css.core.model.IPropertyInfo;
+
+/**
+ * Interface for extensions that provide information about specific CSS
+ * profiles.
+ * 
+ * <b>Note that this interface is very likely to change or even disappear.</b>
+ */
+public interface IProfile {
+
+       IProfileDescriptor getDescriptor();
+
+       Collection getAtKeywords();
+
+       Collection getProperties();
+
+       IPropertyInfo getPropertyInfo(String propertyName);
+
+       Collection getPseudoClassNames();
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/profiles/IProfileDescriptor.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/profiles/IProfileDescriptor.java
new file mode 100644 (file)
index 0000000..d242771
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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
+ * 
+ * $Id: IProfileDescriptor.java,v 1.1 2004-09-02 18:07:14 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.profiles;
+
+
+/**
+ * 
+ */
+public interface IProfileDescriptor {
+
+       // Constants ---------------------------------------------------------------
+
+       /**
+        * Symbolic constant for the profiles extension point ID.
+        */
+       String EXTENSION_POINT_ID =
+               "net.sourceforge.phpeclipse.css.core.profiles"; //$NON-NLS-1$
+
+       // Methods -----------------------------------------------------------------
+
+       /**
+        * @return The ID of the extension
+        */
+       String getId();
+
+       /**
+        * @return The display name of the profile
+        */
+       String getName();
+
+       /**
+        * @return A description of the profile
+        */
+       String getDescription();
+
+       /**
+        * @return The name of the class implementing the profile
+        */
+       String getClassName();
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/profiles/IProfileManager.java b/archive/net.sourceforge.phpeclipse.css.core/src/net/sourceforge/phpeclipse/css/core/profiles/IProfileManager.java
new file mode 100644 (file)
index 0000000..b4400de
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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
+ * 
+ * $Id: IProfileManager.java,v 1.1 2004-09-02 18:07:14 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.core.profiles;
+
+import org.eclipse.core.resources.IResource;
+
+/**
+ * Manages the CSS profiles.
+ */
+public interface IProfileManager {
+
+       /**
+        * Returns the list of available profiles.
+        * 
+        * @return an array containing the descriptors of all available profiles
+        */
+       IProfileDescriptor[] getProfileDescriptors();
+
+       /**
+        * Returns the profile that is selected for the specified resource or 
+        * project.
+        * 
+        * @param resource the resource for which the profile should be retrieved,
+        *        or <code>null</code> to retrieve the default profile as specified 
+        *        in the plugin preferences
+        * @return the profile
+        */
+       IProfile getProfile(IResource resource);
+
+       /**
+        * Sets the profile that should be used for the specified resource. If the 
+        * resource is an <code>IProject</code>, the profile will be used as the
+        * default profile for all resources in the project. Otherwise, it will be
+        * used only for the resource. If the resource is <code>null</code>, the 
+        * profile will be selected as the global default profile.
+        * 
+        * @param resource
+        * @param profileId The ID of the profile
+        */
+       void setProfile(IResource resource, String profileId);
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/.classpath b/archive/net.sourceforge.phpeclipse.css.ui/.classpath
new file mode 100644 (file)
index 0000000..065ac06
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/.cvsignore b/archive/net.sourceforge.phpeclipse.css.ui/.cvsignore
new file mode 100644 (file)
index 0000000..67b544a
--- /dev/null
@@ -0,0 +1,3 @@
+bin
+build
+dist
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/.project b/archive/net.sourceforge.phpeclipse.css.ui/.project
new file mode 100644 (file)
index 0000000..de21ed9
--- /dev/null
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>net.sourceforge.phpeclipse.css.ui</name>
+       <comment></comment>
+       <projects>
+               <project>net.sf.wdte.core</project>
+               <project>net.sf.wdte.css.core</project>
+               <project>net.sf.wdte.ui</project>
+               <project>org.eclipse.compare</project>
+               <project>org.eclipse.core.resources</project>
+               <project>org.eclipse.core.runtime.compatibility</project>
+               <project>org.eclipse.help</project>
+               <project>org.eclipse.jface.text</project>
+               <project>org.eclipse.osgi</project>
+               <project>org.eclipse.ui</project>
+               <project>org.eclipse.ui.editors</project>
+               <project>org.eclipse.ui.ide</project>
+               <project>org.eclipse.ui.views</project>
+               <project>org.eclipse.ui.workbench.texteditor</project>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.pde.PluginNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/build.properties b/archive/net.sourceforge.phpeclipse.css.ui/build.properties
new file mode 100644 (file)
index 0000000..b7c152d
--- /dev/null
@@ -0,0 +1,15 @@
+bin.includes = plugin.xml,\
+               plugin*.properties,\
+               cssui.jar,\
+               icons/,\
+               plugin.properties
+src.includes = schema/,\
+               .classpath,\
+               .project,\
+               build.properties,\
+               plugin.properties,\
+               plugin.xml,\
+               icons/,\
+               src/
+source.cssui.jar = src
+bin.excludes = icons/.cvsignore
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/icons/at_rule_obj.gif b/archive/net.sourceforge.phpeclipse.css.ui/icons/at_rule_obj.gif
new file mode 100644 (file)
index 0000000..4e343b9
Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.css.ui/icons/at_rule_obj.gif differ
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/icons/class_obj.gif b/archive/net.sourceforge.phpeclipse.css.ui/icons/class_obj.gif
new file mode 100644 (file)
index 0000000..15cfc6d
Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.css.ui/icons/class_obj.gif differ
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/icons/full/ovr16/error_co.gif b/archive/net.sourceforge.phpeclipse.css.ui/icons/full/ovr16/error_co.gif
new file mode 100644 (file)
index 0000000..8612eaf
Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.css.ui/icons/full/ovr16/error_co.gif differ
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/icons/full/ovr16/warning_co.gif b/archive/net.sourceforge.phpeclipse.css.ui/icons/full/ovr16/warning_co.gif
new file mode 100644 (file)
index 0000000..3af228c
Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.css.ui/icons/full/ovr16/warning_co.gif differ
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/icons/important_obj.gif b/archive/net.sourceforge.phpeclipse.css.ui/icons/important_obj.gif
new file mode 100644 (file)
index 0000000..424ae7c
Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.css.ui/icons/important_obj.gif differ
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/icons/int_obj.gif b/archive/net.sourceforge.phpeclipse.css.ui/icons/int_obj.gif
new file mode 100644 (file)
index 0000000..13c9570
Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.css.ui/icons/int_obj.gif differ
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/icons/property_obj.gif b/archive/net.sourceforge.phpeclipse.css.ui/icons/property_obj.gif
new file mode 100644 (file)
index 0000000..630b286
Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.css.ui/icons/property_obj.gif differ
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/icons/pseudo_class_obj.gif b/archive/net.sourceforge.phpeclipse.css.ui/icons/pseudo_class_obj.gif
new file mode 100644 (file)
index 0000000..17d6e66
Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.css.ui/icons/pseudo_class_obj.gif differ
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/icons/shorthand_obj.gif b/archive/net.sourceforge.phpeclipse.css.ui/icons/shorthand_obj.gif
new file mode 100644 (file)
index 0000000..e7271d3
Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.css.ui/icons/shorthand_obj.gif differ
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/icons/style_rule_obj.gif b/archive/net.sourceforge.phpeclipse.css.ui/icons/style_rule_obj.gif
new file mode 100644 (file)
index 0000000..1544189
Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.css.ui/icons/style_rule_obj.gif differ
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/icons/style_sheet_obj.gif b/archive/net.sourceforge.phpeclipse.css.ui/icons/style_sheet_obj.gif
new file mode 100644 (file)
index 0000000..83de817
Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.css.ui/icons/style_sheet_obj.gif differ
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/plugin.properties b/archive/net.sourceforge.phpeclipse.css.ui/plugin.properties
new file mode 100644 (file)
index 0000000..550a4ad
--- /dev/null
@@ -0,0 +1,38 @@
+#
+# 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 english resources
+# 
+# $Id: plugin.properties,v 1.1 2004-09-02 18:11:51 jsurfer Exp $
+#
+
+pluginName = Web Development Tools CSS UI
+providerName= WDTE Project
+
+editorName = CSS Editor
+
+editorFontDefinition.label = CSS Editor Text Font
+editorFontDefinition.description = \
+ The CSS editor text font is used by CSS editors.
+compareFontDefinition.label = CSS Compare Text Font
+compareFontDefinition.description = \
+ The CSS compare text font is used by CSS compare/merge editors.
+
+preferencePage.name = CSS
+editorPreferencePage.name = Editor
+
+propertyPage.name = CSS
+
+authoringActions.label = CSS Authoring
+sourceCategory.label = Source
+sourceCategory.description = CSS Source Actions
+sourceMenu.label = &Source
+commentAction.label = Co&mment
+uncommentAction.label = &Uncomment
+shiftLeftAction.label = S&hift Left
+shiftRightAction.label = Sh&ift Right
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/plugin.xml b/archive/net.sourceforge.phpeclipse.css.ui/plugin.xml
new file mode 100644 (file)
index 0000000..ad01d4c
--- /dev/null
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin
+   id="net.sourceforge.phpeclipse.css.ui"
+   name="%pluginName"
+   version="0.0.1"
+   provider-name="%providerName"
+   class="net.sourceforge.phpeclipse.css.ui.CssUI">
+
+   <runtime>
+      <library name="cssui.jar"/>
+   </runtime>
+   <requires>
+      <import plugin="net.sourceforge.phpeclipse.core"/>
+      <import plugin="net.sourceforge.phpeclipse.css.core"/>
+      <import plugin="net.sourceforge.phpeclipse.ui"/>
+      <import plugin="org.eclipse.compare"/>
+      <import plugin="org.eclipse.core.runtime"/>
+      <import plugin="org.eclipse.core.filebuffers"/>
+      <import plugin="org.eclipse.core.resources"/>
+      <import plugin="org.eclipse.help"/>
+      <import plugin="org.eclipse.jface.text"/>
+      <import plugin="org.eclipse.osgi"/>
+      <import plugin="org.eclipse.ui"/>
+      <import plugin="org.eclipse.ui.editors"/>
+      <import plugin="org.eclipse.ui.ide"/>
+      <import plugin="org.eclipse.ui.views"/>
+      <import plugin="org.eclipse.ui.workbench.texteditor"/>
+   </requires>
+
+
+   <extension
+         point="org.eclipse.core.runtime.adapters">
+      <factory
+            class="net.sourceforge.phpeclipse.css.ui.internal.properties.CssPropertiesAdapterFactory"
+            adaptableType="net.sourceforge.phpeclipse.css.core.model.IRule">
+         <adapter type="org.eclipse.ui.views.properties.IPropertySource"/>
+      </factory>
+   </extension>
+   <extension
+         point="org.eclipse.ui.editors">
+      <editor
+            name="%editorName"
+            icon="icons/style_sheet_obj.gif"
+            extensions="css"
+            contributorClass="net.sourceforge.phpeclipse.css.ui.internal.editor.CssEditorActionContributor"
+            class="net.sourceforge.phpeclipse.css.ui.internal.editor.CssEditor"
+            id="net.sourceforge.phpeclipse.css.ui.editor">
+      </editor>
+   </extension>
+   <extension
+         point="org.eclipse.core.filebuffers.documentSetup">
+      <participant
+            extensions="css"
+            class="net.sourceforge.phpeclipse.css.ui.internal.CssDocumentSetupParticipant">
+      </participant>
+   </extension>
+   <extension
+         point="org.eclipse.ui.editors.documentProviders">
+      <provider
+            extensions="css"
+            class="net.sourceforge.phpeclipse.css.ui.internal.CssDocumentProvider"
+            id="net.sourceforge.phpeclipse.css.ui.documentProvider">
+      </provider>
+   </extension>
+   <extension
+         point="org.eclipse.ui.fontDefinitions">
+      <fontDefinition
+            label="%editorFontDefinition.label"
+            defaultsTo="org.eclipse.jface.textfont"
+            id="net.sourceforge.phpeclipse.css.ui.editorfont">
+         <description>
+            %editorFontDefinition.description
+         </description>
+      </fontDefinition>
+      <fontDefinition
+            label="%compareFontDefinition.label"
+            defaultsTo="org.eclipse.compare.contentmergeviewer.TextMergeViewer"
+            id="net.sourceforge.phpeclipse.css.ui.internal.compare.CssMergeViewer">
+         <description>
+            %compareFontDefinition.description
+         </description>
+      </fontDefinition>
+   </extension>
+   <extension
+         point="org.eclipse.ui.preferencePages">
+      <page
+            name="%preferencePage.name"
+            category="net.sourceforge.phpeclipse.ui.preferencePage"
+            class="net.sourceforge.phpeclipse.css.ui.internal.preferences.CssPreferencePage"
+            id="net.sourceforge.phpeclipse.css.ui.preferencePage">
+      </page>
+      <page
+            name="%editorPreferencePage.name"
+            category="net.sourceforge.phpeclipse.css.ui.preferencePage"
+            class="net.sourceforge.phpeclipse.css.ui.internal.preferences.CssEditorPreferencePage"
+            id="net.sourceforge.phpeclipse.css.ui.editor.preferencePage">
+      </page>
+   </extension>
+   <extension
+         point="org.eclipse.ui.propertyPages">
+<!-- TODO: Only enable the following property page for projects with a
+           future "Web" nature -->
+      <page
+            objectClass="org.eclipse.core.resources.IProject"
+            name="%propertyPage.name"
+            class="net.sourceforge.phpeclipse.css.ui.internal.properties.CssPropertyPage"
+            id="net.sourceforge.phpeclipse.css.ui.propertyPage">
+      </page>
+      <page
+            objectClass="org.eclipse.core.resources.IResource"
+            name="%propertyPage.name"
+            nameFilter="*.css"
+            class="net.sourceforge.phpeclipse.css.ui.internal.properties.CssPropertyPage"
+            id="net.sourceforge.phpeclipse.css.ui.propertyPage">
+      </page>
+   </extension>
+   <extension
+         point="org.eclipse.ui.commands">
+      <category
+            name="%sourceCategory.label"
+            description="%sourceMenu.description"
+            id="net.sourceforge.phpeclipse.css.ui.sourceCategory">
+      </category>
+      <command
+            name="%commentAction.label"
+            description="%commentAction.description"
+            category="org.eclipse.jdt.ui.category.source"
+            id="net.sourceforge.phpeclipse.css.ui.commentAction">
+      </command>
+      <keyBinding
+            string="Ctrl+/"
+            command="net.sourceforge.phpeclipse.css.ui.commentAction"
+            configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+      </keyBinding>
+      <keyBinding
+            platform="carbon"
+            string="Ctrl+/"
+            command="net.sourceforge.phpeclipse.css.ui.commentAction"
+            configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+      </keyBinding>
+      <keyBinding
+            platform="carbon"
+            string="Command+/"
+            command="net.sourceforge.phpeclipse.css.ui.commentAction"
+            configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+      </keyBinding>
+      <command
+            name="%uncommentAction.label"
+            description="%uncommentAction.description"
+            category="org.eclipse.jdt.ui.category.source"
+            id="net.sourceforge.phpeclipse.css.ui.uncommentAction">
+      </command>
+      <keyBinding
+            string="Ctrl+\"
+            command="net.sourceforge.phpeclipse.css.ui.uncommentAction"
+            configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+      </keyBinding>
+      <keyBinding
+            platform="carbon"
+            string="Ctrl+\"
+            command="net.sourceforge.phpeclipse.css.ui.uncommentAction"
+            configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+      </keyBinding>
+      <keyBinding
+            platform="carbon"
+            string="Command+\"
+            command="net.sourceforge.phpeclipse.css.ui.uncommentAction"
+            configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+      </keyBinding>
+   </extension>
+   <extension
+         point="org.eclipse.ui.actionSets">
+      <actionSet
+            label="%authoringActions.label"
+            id="net.sourceforge.phpeclipse.css.ui.authoringActions">
+         <menu
+               label="%sourceMenu.label"
+               path="edit"
+               id="net.sourceforge.phpeclipse.css.ui.sourceMenu">
+            <separator
+                  name="editGroup">
+            </separator>
+         </menu>
+         <action
+               label="%shiftLeftAction.label"
+               retarget="true"
+               menubarPath="net.sourceforge.phpeclipse.css.ui.sourceMenu/editGroup"
+               id="org.eclipse.ui.edit.text.shiftLeft">
+         </action>
+         <action
+               label="%shiftRightAction.label"
+               retarget="true"
+               menubarPath="net.sourceforge.phpeclipse.css.ui.sourceMenu/editGroup"
+               id="org.eclipse.ui.edit.text.shiftRight">
+         </action>
+         <action
+               definitionId="net.sourceforge.phpeclipse.css.ui.uncommentAction"
+               label="%uncommentAction.label"
+               retarget="true"
+               menubarPath="net.sourceforge.phpeclipse.css.ui.sourceMenu/editGroup"
+               id="net.sourceforge.phpeclipse.css.ui.uncommentAction">
+         </action>
+         <action
+               definitionId="net.sourceforge.phpeclipse.css.ui.commentAction"
+               label="%commentAction.label"
+               retarget="true"
+               menubarPath="net.sourceforge.phpeclipse.css.ui.sourceMenu/editGroup"
+               id="net.sourceforge.phpeclipse.css.ui.commentAction">
+         </action>
+      </actionSet>
+   </extension>
+   <extension
+         point="org.eclipse.ui.actionSetPartAssociations">
+      <actionSetPartAssociation
+            targetID="net.sourceforge.phpeclipse.css.ui.authoringActions">
+         <part
+               id="net.sourceforge.phpeclipse.css.ui.editor">
+         </part>
+      </actionSetPartAssociation>
+      <actionSetPartAssociation
+            targetID="org.eclipse.ui.edit.text.actionSet.presentation">
+         <part
+               id="net.sourceforge.phpeclipse.css.ui.editor">
+         </part>
+      </actionSetPartAssociation>
+   </extension>
+   <extension
+         point="org.eclipse.compare.contentMergeViewers">
+      <viewer
+            extensions="css"
+            class="net.sourceforge.phpeclipse.css.ui.internal.compare.CssMergeViewerCreator"
+            id="net.sourceforge.phpeclipse.css.ui.compare.contentMergeViewer">
+      </viewer>
+   </extension>
+   <extension
+         point="org.eclipse.compare.structureCreators">
+      <structureCreator
+            extensions="css"
+            class="net.sourceforge.phpeclipse.css.ui.internal.compare.CssStructureCreator"
+            id="net.sourceforge.phpeclipse.css.ui.compare.structureCreator">
+      </structureCreator>
+   </extension>
+
+</plugin>
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/CssUI.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/CssUI.java
new file mode 100644 (file)
index 0000000..46d5617
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * 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: CssUI.java,v 1.1 2004-09-02 18:11:51 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui;
+
+import java.net.URL;
+
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIPreferences;
+import net.sourceforge.phpeclipse.css.ui.internal.properties.CssPropertiesAdapterFactory;
+import net.sourceforge.phpeclipse.css.ui.text.CssTextTools;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.ui.editors.text.TextEditorPreferenceConstants;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The main plugin class.
+ */
+public final class CssUI extends AbstractUIPlugin  {
+
+       // Constants ---------------------------------------------------------------
+
+       public static final String ICON_STYLE_SHEET =
+               "style_sheet_obj.gif"; //$NON-NLS-1$
+       public static final String ICON_AT_RULE =
+               "at_rule_obj.gif"; //$NON-NLS-1$
+       public static final String ICON_STYLE_RULE =
+               "style_rule_obj.gif"; //$NON-NLS-1$
+       public static final String ICON_PROPERTY =
+               "property_obj.gif"; //$NON-NLS-1$
+       public static final String ICON_SHORTHAND =
+               "shorthand_obj.gif"; //$NON-NLS-1$
+       public static final String ICON_PSEUDO_CLASS =
+               "pseudo_class_obj.gif"; //$NON-NLS-1$
+       public static final String ICON_IMPORTANT =
+               "important_obj.gif"; //$NON-NLS-1$
+       public static final String ICON_OVERLAY_ERROR =
+               "full/ovr16/error_co.gif"; //$NON-NLS-1$
+       public static final String ICON_OVERLAY_WARNING =
+               "full/ovr16/warning_co.gif"; //$NON-NLS-1$
+
+       // Class Variables ---------------------------------------------------------
+
+       /**
+        * Singleton instance of the plugin.
+        */
+       private static CssUI plugin;
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The text tools collection.
+        */
+       private CssTextTools textTools;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param descriptor the plugin descriptor.
+        */
+       public CssUI() {
+               plugin = this;
+       }
+
+       // Static Methods ----------------------------------------------------------
+
+       /**
+        * Returns the singleton instance of the plugin.
+        * 
+        * @return the plugin instance
+        */
+       public static CssUI getDefault() {
+               return plugin;
+       }
+
+       /**
+        * Returns the plugin ID.
+        * 
+        * @return the plugin ID
+        */
+       public static String getPluginId() {
+               return getDefault().getBundle().getSymbolicName();
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Returns the CSS text tools that are used primarily for partitioning and
+        * syntax highlighting of CSS source.
+        * 
+        * @return the CSS text tools
+        */
+       public synchronized CssTextTools getTextTools() {
+               if (textTools == null) {
+                       textTools = new CssTextTools(getPreferenceStore());
+               }
+               return textTools;
+       }
+
+       /**
+        * Returns an image descriptor for the image corresponding to the specified
+        * key (which is the name of the image file).
+        * 
+        * @param key The key of the image
+        * @return The descriptor for the requested image, or <code>null</code> if 
+        *         the image could not be found
+        */
+       public ImageDescriptor getImageDescriptor(String key) {
+               try {
+                       URL url = getBundle().getEntry("/icons/" + key); //$NON-NLS-1$
+                       return ImageDescriptor.createFromURL(url);
+               } catch (IllegalStateException e) {
+                       return null;
+               }
+       }
+
+       /**
+        * Writes a status message and the associated exception stack trace (if
+        * provided) to the error log.
+        * 
+        * @param status the status to log
+        */
+       public static void log(IStatus status) {
+               getDefault().getLog().log(status);
+               if (status.getException() != null) {
+                       status.getException().printStackTrace(System.err);
+               }
+       }
+
+       /**
+        * Writes the specified error message and exception stack trace to the error
+        * log.
+        * 
+        * @param message the error message
+        * @param e the exception that caused the error, or <tt>null</tt> to omit
+        *        the stack trace in the log
+        */
+       public static void log(String message, Throwable e) {
+               IStatus status = new Status(IStatus.ERROR, getPluginId(), IStatus.ERROR,
+                       message, e); 
+               log(status);
+       }
+
+       /**
+        * Writes the specified error message to the error log.
+        * 
+        * @param message the error message
+        */
+       public static void log(String message) {
+               IStatus status = new Status(IStatus.ERROR, getPluginId(), IStatus.ERROR,
+                       message, null); 
+               log(status);
+       }
+
+       /**
+        * Writes the stack trace of the given exception to the error log.
+        * 
+        * @param e the exception that caused the error
+        */
+       public static void log(Throwable e) {
+               log(e.getMessage(), e);
+       }
+
+       // AbstractUIPlugin Implementation -----------------------------------------
+
+       /*
+        * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+        */
+       public void start(BundleContext context) throws Exception {
+               super.start(context);
+               CssPropertiesAdapterFactory.register(Platform.getAdapterManager());
+       }
+
+       /*
+        * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+        */
+       public void stop(BundleContext context) throws Exception {
+               try {
+                       if (textTools != null) {
+                               textTools.dispose();
+                               textTools = null;
+                       }
+               } finally {
+                       super.stop(context);
+               }
+       }
+
+       /*
+        * @see AbstractUIPlugin#initializeDefaultPreferences(IPreferenceStore)
+        */
+       protected void initializeDefaultPreferences(IPreferenceStore store) {
+               TextEditorPreferenceConstants.initializeDefaultValues(store);
+               CssUIPreferences.initializeDefaultValues(store);
+       }
+
+       /*
+        * @see AbstractUIPlugin#initializeImageRegistry(ImageRegistry)
+        */
+       protected void initializeImageRegistry(ImageRegistry reg) {
+               reg.put(ICON_AT_RULE, getImageDescriptor(ICON_AT_RULE));
+               reg.put(ICON_STYLE_RULE, getImageDescriptor(ICON_STYLE_RULE));
+               reg.put(ICON_STYLE_SHEET, getImageDescriptor(ICON_STYLE_SHEET));
+               reg.put(ICON_PROPERTY, getImageDescriptor(ICON_PROPERTY));
+               reg.put(ICON_SHORTHAND, getImageDescriptor(ICON_SHORTHAND));
+               reg.put(ICON_PSEUDO_CLASS, getImageDescriptor(ICON_PSEUDO_CLASS));
+               reg.put(ICON_IMPORTANT, getImageDescriptor(ICON_IMPORTANT));
+               reg.put(ICON_OVERLAY_ERROR, getImageDescriptor(ICON_OVERLAY_ERROR));
+               reg.put(ICON_OVERLAY_WARNING, getImageDescriptor(ICON_OVERLAY_WARNING));
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/CssDocumentProvider.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/CssDocumentProvider.java
new file mode 100644 (file)
index 0000000..d43169f
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * 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: CssDocumentProvider.java,v 1.1 2004-09-02 18:11:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal;
+
+import net.sourceforge.phpeclipse.css.core.internal.model.StyleSheet;
+import net.sourceforge.phpeclipse.css.core.model.IStyleSheet;
+
+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;
+
+/**
+ * Document provider for CSS files.
+ * 
+ * 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 CssDocumentProvider extends TextFileDocumentProvider {
+
+       // Inner Classes -----------------------------------------------------------
+
+       private class StyleSheetInfo extends FileInfo {
+               private IStyleSheet styleSheet;
+       }
+
+       // TestFileDocumentProvider Implementation ---------------------------------
+
+       /*
+        * @see TextFileDocumentProvider#createEmptyFileInfo()
+        */
+       protected FileInfo createEmptyFileInfo() {
+               return new StyleSheetInfo();
+       }
+
+       /*
+        * @see TextFileDocumentProvider#createFileInfo(Object)
+        */
+       protected FileInfo createFileInfo(Object element) throws CoreException {
+               FileInfo fileInfo = super.createFileInfo(element);
+               if (!(fileInfo instanceof StyleSheetInfo)) {
+                       return null;
+               }
+
+               IDocument document = fileInfo.fTextFileBuffer.getDocument();
+               IStyleSheet styleSheet = createStyleSheet(document);
+               if (styleSheet instanceof IDocumentListener) {
+                       document.addDocumentListener((IDocumentListener) styleSheet);
+               }
+               StyleSheetInfo styleSheetInfo = (StyleSheetInfo) fileInfo;
+               styleSheetInfo.styleSheet = styleSheet;
+
+               return styleSheetInfo;
+       }
+
+       /*
+        * @see TextFileDocumentProvider#disposeFileInfo(Object, TextFileDocumentProvider.FileInfo)
+        */
+       protected void disposeFileInfo(Object element, FileInfo info) {
+               if (info instanceof StyleSheetInfo) {
+                       IDocument document = getDocument(element);
+                       // TODO Check whether this is really necessary, as the document is
+                       //      always null here
+                       if (document != null) {
+                               IStyleSheet styleSheet = ((StyleSheetInfo) info).styleSheet;
+                               if (styleSheet instanceof IDocumentListener) {
+                                       document.removeDocumentListener((IDocumentListener)
+                                                       styleSheet);
+                               }
+                       }
+               }
+               super.disposeFileInfo(element, info);
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Creates the parsed style sheet object corresponding to the specified 
+        * document.
+        * 
+        * @param document the document to parse
+        * @return the parsed style sheet
+        */
+       public IStyleSheet createStyleSheet(IDocument document) {
+               return new StyleSheet(document);
+       }
+
+       /**
+        * Returns the style sheet associated with the specified element.
+        * 
+        * @param element the element
+        * @return the style sheet associated with the element
+        */
+       public IStyleSheet getStyleSheet(Object element) {
+               FileInfo info = getFileInfo(element);
+               if (info instanceof StyleSheetInfo) {
+                       StyleSheetInfo styleSheetInfo = (StyleSheetInfo) info;
+                       return styleSheetInfo.styleSheet;
+               }
+               return null;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/CssDocumentSetupParticipant.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/CssDocumentSetupParticipant.java
new file mode 100644 (file)
index 0000000..a0aae6d
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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: CssDocumentSetupParticipant.java,v 1.1 2004-09-02 18:11:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal;
+
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+import net.sourceforge.phpeclipse.css.ui.text.CssTextTools;
+
+import org.eclipse.core.filebuffers.IDocumentSetupParticipant;
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * Document setup participant that sets up the CSS specific partitioning.
+ */
+public class CssDocumentSetupParticipant implements IDocumentSetupParticipant {
+
+       /* 
+        * @see IDocumentSetupParticipant#setup(IDocument)
+        */
+       public void setup(IDocument document) {
+               if (document != null) {
+                       CssTextTools tools = CssUI.getDefault().getTextTools();
+                       tools.setupDocument(document);
+               }
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/CssUIMessages.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/CssUIMessages.java
new file mode 100644 (file)
index 0000000..206b604
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * 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: CssUIMessages.java,v 1.1 2004-09-02 18:11:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Utility class that provides easy access to externalized strings.
+ */
+public final class CssUIMessages {
+
+       // Constants ---------------------------------------------------------------
+
+       /**
+        * Qualified name of the resource bundle containing the localized messages.
+        */
+       private static final String RESOURCE_BUNDLE =
+               "net.sourceforge.phpeclipse.css.ui.internal.CssUIMessages"; //$NON-NLS-1$
+
+       // Class Variables ---------------------------------------------------------
+
+       /**
+        * The resource bundle.
+        */
+       private static ResourceBundle fgResourceBundle =
+               ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Hidden constructor.
+        */
+       private CssUIMessages() {
+               // Hidden
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Returns the resource bundle.
+        * 
+        * @return the resource bundle
+        */
+       public static ResourceBundle getResourceBundle() {
+               return fgResourceBundle;
+       }
+
+       /**
+        * Returns the message identified by the specified key.
+        * 
+        * @param key the message key
+        * @return the localized message, or the key enclosed by exclamation marks
+        *         if no message was found for the key
+        */
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!"; //$NON-NLS-2$ //$NON-NLS-1$
+               }
+       }
+
+       /**
+        * Returns the message identified by the specified key, replacing a single
+        * parameter with the provided value.
+        * 
+        * @param key the message key
+        * @param arg the parameter value
+        * @return the formatted string, or the key enclosed by exclamation marks
+        *         if no message was found for the key
+        */
+       public static String getString(String key, String arg) {
+               return getString(key, new String[] { arg });
+       }
+
+       /**
+        * Returns the message identified by the specified key, replacing all
+        * parameters with the provided values.
+        * 
+        * @param key the message key
+        * @param args the parameter values
+        * @return the formatted string, or the key enclosed by exclamation marks
+        *         if no message was found for the key
+        */
+       public static String getString(String key, String[] args) {
+               return MessageFormat.format(getString(key), args);      
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/CssUIMessages.properties b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/CssUIMessages.properties
new file mode 100644 (file)
index 0000000..85c692f
--- /dev/null
@@ -0,0 +1,123 @@
+#
+# 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 english resources
+# 
+# $Id: CssUIMessages.properties,v 1.1 2004-09-02 18:11:49 jsurfer Exp $
+#
+
+# Outline Page -----------------------------------------------------------------
+
+CssOutlinePage.sort.image = sort_alpha.gif
+CssOutlinePage.sort.label = Sort
+CssOutlinePage.sort.tooltip = Sort rules alpabetically
+CssOutlinePage.sort.description = Sort rules alpabetically
+CssOutlinePage.linkWithEditor.image = link_editor.gif
+CssOutlinePage.linkWithEditor.label = Link with editor
+CssOutlinePage.linkWithEditor.tooltip = Link with editor
+CssOutlinePage.linkWithEditor.description = Link with editor
+
+# Editor -----------------------------------------------------------------------
+
+CssEditor.comment.label = Comment
+CssEditor.comment.tooltip = Comment Selected Code
+CssEditor.comment.description = Comment Selected Code
+CssEditor.uncomment.label = Uncomment
+CssEditor.uncomment.tooltip = Uncomment Selected Code
+CssEditor.uncomment.description = Uncomment Selected Code
+CssEditor.contentAssist.label = Content Assist@Ctrl+Space
+CssEditor.contentAssist.tooltip = Content Assist
+CssEditor.contentAssist.description = Content Assist
+CssEditor.showSelectedElementOnly.label = Show Source of Selected Rule Only
+CssEditor.showSelectedElementOnly.tooltip = Show Source of Selected Rule Only
+CssEditor.showSelectedElementOnly.description = Show Source of Selected Rule Only
+
+# Compare ----------------------------------------------------------------------
+
+CssMergeViewer.title = CSS Source Compare
+CssStructureViewer.title = CSS Structure Compare
+CssStructureViewer.styleSheet = Stylesheet
+
+# Preference Pages -------------------------------------------------------------
+
+CssPreferencePage.description = CSS settings:
+CssPreferencePage.profile = CSS profile:
+
+CssEditorPreferencePage.description = CSS editor settings:
+CssEditorPreferencePage.empty_input = Empty input
+CssEditorPreferencePage.invalid_input = ''{0}'' is not a valid input.
+
+CssEditorPreferencePage.appearance = Appeara&nce
+CssEditorPreferencePage.appearance.displayedTabWidth = Displayed &tab width:
+CssEditorPreferencePage.appearance.printMarginColumn = Print margin col&umn:
+CssEditorPreferencePage.appearance.showOverviewRuler = Show overview &ruler
+CssEditorPreferencePage.appearance.showLineNumbers = Show lin&e numbers
+CssEditorPreferencePage.appearance.highlightMatchingBrackets = Highlight &matching brackets
+CssEditorPreferencePage.appearance.highlightCurrentLine =Hi&ghlight current line
+CssEditorPreferencePage.appearance.showPrintMargin = Sho&w print margin
+CssEditorPreferencePage.appearance.color = C&olor:
+CssEditorPreferencePage.appearance.colorOptions = Appearance co&lor options:
+CssEditorPreferencePage.appearance.lineNumberForegroundColor = Line number foreground
+CssEditorPreferencePage.appearance.matchingBracketsHighlightColor = Matching brackets highlight
+CssEditorPreferencePage.appearance.currentLineHighlighColor = Current line highlight
+CssEditorPreferencePage.appearance.printMarginColor = Print margin
+
+CssEditorPreferencePage.annotations = Annotation&s
+CssEditorPreferencePage.annotations.analyzeWhileTyping = Analyze annotations &while typing
+CssEditorPreferencePage.annotations.presentationOptions = Annotation &presentation:
+CssEditorPreferencePage.annotations.bookmarks = Bookmarks
+CssEditorPreferencePage.annotations.searchResults = Search Results
+CssEditorPreferencePage.annotations.errors = Errors
+CssEditorPreferencePage.annotations.warnings = Warnings
+CssEditorPreferencePage.annotations.infos = Infos
+CssEditorPreferencePage.annotations.tasks = Tasks
+CssEditorPreferencePage.annotations.others = Others
+CssEditorPreferencePage.annotations.showInText = Show in &text
+CssEditorPreferencePage.annotations.showInOverviewRuler = Show in overview &ruler
+CssEditorPreferencePage.annotations.color = C&olor:
+
+CssEditorPreferencePage.syntax = Synta&x
+CssEditorPreferencePage.syntax.backgroundColor = Background color
+CssEditorPreferencePage.syntax.backgroundColorSystemDefault = System default
+CssEditorPreferencePage.syntax.backgroundColorCustom = Custom:
+CssEditorPreferencePage.syntax.foregroundColor = Foreground:
+CssEditorPreferencePage.syntax.commentColor = Comments
+CssEditorPreferencePage.syntax.propertyNameColor = Property names
+CssEditorPreferencePage.syntax.atKeywordColor = At-keywords
+CssEditorPreferencePage.syntax.pseudoClassColor = Pseudo classes and elements
+CssEditorPreferencePage.syntax.stringColor = Strings
+CssEditorPreferencePage.syntax.defaultColor = Others
+CssEditorPreferencePage.syntax.color = C&olor
+CssEditorPreferencePage.syntax.bold = &Bold
+
+CssEditorPreferencePage.contentAssist = &Content Assist
+CssEditorPreferencePage.contentAssist.insertSingleProposalsAutomatically = Insert single &proposals automatically
+CssEditorPreferencePage.contentAssist.presentProposalsInAlphabeticalOrder = Present proposals in &alphabetical order
+CssEditorPreferencePage.contentAssist.enableAutoActivation = &Enable auto activation
+CssEditorPreferencePage.contentAssist.autoActivationDelay = Auto activation dela&y:
+CssEditorPreferencePage.contentAssist.autoActivationTriggers = Auto activation &triggers:
+CssEditorPreferencePage.contentAssist.colorOptions = Content assist colo&r options:
+CssEditorPreferencePage.contentAssist.color = C&olor:
+CssEditorPreferencePage.contentAssist.backgroundForCompletionProposals = Completion proposal background
+CssEditorPreferencePage.contentAssist.foregroundForCompletionProposals = Completion proposal foreground
+
+CssEditorPreferencePage.typing = T&yping
+CssEditorPreferencePage.typing.insertSpaceForTabs = Ins&ert space for tabs
+CssEditorPreferencePage.typing.closeStrings = Close strin&gs
+CssEditorPreferencePage.typing.closeBracketsAndParens = Close &brackets and parenthesis
+CssEditorPreferencePage.typing.closeBraces = Cl&ose braces
+
+TextStyleFieldsEditor.color = C&olor
+TextStyleFieldsEditor.bold = &Bold
+
+# Property Pages ---------------------------------------------------------------
+
+CssPropertyPage.useWorkspaceSettings = Use &workspace settings
+CssPropertyPage.useProjectSettings = Use project or &workspace settings
+CssPropertyPage.useCustomSettings = Use c&ustom settings
+CssPropertyPage.profile = CSS profile:
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/CssUIPreferences.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/CssUIPreferences.java
new file mode 100644 (file)
index 0000000..70cf898
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * 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: CssUIPreferences.java,v 1.1 2004-09-02 18:11:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
+import org.eclipse.ui.texteditor.AbstractTextEditor;
+
+/**
+ * 
+ */
+public final class CssUIPreferences {
+
+       // Constants ---------------------------------------------------------------
+
+       // Inherited constants
+
+       public static final String EDITOR_CURRENT_LINE =
+               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_CURRENT_LINE;
+
+       public static final String EDITOR_CURRENT_LINE_COLOR =
+               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_CURRENT_LINE_COLOR;
+
+       public static final String EDITOR_TAB_WIDTH =
+               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH;
+
+       public static final String EDITOR_LINE_NUMBER_RULER =
+               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_LINE_NUMBER_RULER;
+
+       public static final String EDITOR_LINE_NUMBER_RULER_COLOR =
+               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_LINE_NUMBER_RULER_COLOR;
+
+       public static final String EDITOR_PRINT_MARGIN =
+               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_PRINT_MARGIN;
+
+       public static final String EDITOR_PRINT_MARGIN_COLOR =
+               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_PRINT_MARGIN_COLOR;
+
+       public static final String EDITOR_PRINT_MARGIN_COLUMN =
+               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN;
+
+       public static final String EDITOR_OVERVIEW_RULER =
+               AbstractDecoratedTextEditorPreferenceConstants.EDITOR_OVERVIEW_RULER;
+
+       public static final String EDITOR_BACKGROUND_DEFAULT_COLOR =
+               AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT;
+
+       public static final String EDITOR_BACKGROUND_COLOR =
+               AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND;
+
+       public static final String EDITOR_FOREGROUND_COLOR =
+               AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND;
+
+       public static final String EDITOR_FOREGROUND_DEFAULT_COLOR =
+               AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT;
+
+       // Custom constants
+
+       public static final String EDITOR_MATCHING_BRACKETS =
+               "matchingBrackets"; //$NON-NLS-1$
+
+       public static final String EDITOR_MATCHING_BRACKETS_COLOR =
+               "matchingBracketsColor"; //$NON-NLS-1$
+
+       public static final String EDITOR_COMMENT_COLOR =
+               "commentColor"; //$NON-NLS-1$
+
+       public static final String EDITOR_COMMENT_BOLD =
+               "commentBold"; //$NON-NLS-1$
+
+       public static final String EDITOR_PROPERTY_COLOR =
+               "propertyColor"; //$NON-NLS-1$
+
+       public static final String EDITOR_PROPERTY_BOLD =
+               "propertyBold"; //$NON-NLS-1$
+
+       public static final String EDITOR_AT_KEYWORD_COLOR =
+               "atKeywordColor"; //$NON-NLS-1$
+
+       public static final String EDITOR_AT_KEYWORD_BOLD =
+               "atKeywordBold"; //$NON-NLS-1$
+
+       public static final String EDITOR_PSEUDO_CLASS_COLOR =
+               "pseudoClassColor"; //$NON-NLS-1$
+
+       public static final String EDITOR_PSEUDO_CLASS_BOLD =
+               "pseudoClassBold"; //$NON-NLS-1$
+
+       public static final String EDITOR_STRING_COLOR =
+               "stringColor"; //$NON-NLS-1$
+
+       public static final String EDITOR_STRING_BOLD =
+               "stringBold"; //$NON-NLS-1$
+
+       public static final String EDITOR_DEFAULT_COLOR =
+               "defaultColor"; //$NON-NLS-1$
+
+       public static final String EDITOR_DEFAULT_BOLD =
+               "defaultBold"; //$NON-NLS-1$
+
+       public static final String EDITOR_SPACES_FOR_TABS =
+               "spacesForTabs"; //$NON-NLS-1$
+
+       public static final String EDITOR_CLOSE_STRINGS =
+               "closeStrings"; //$NON-NLS-1$
+
+       public static final String EDITOR_CLOSE_BRACKETS_AND_PARENS =
+               "closeBracketsAndParens"; //$NON-NLS-1$
+
+       public static final String EDITOR_CLOSE_BRACES =
+               "closeBraces"; //$NON-NLS-1$
+
+       public static final String EDITOR_SHOW_SELECTED_ELEMENT_ONLY =
+               "showSelectedElementOnly"; //$NON-NLS-1$
+
+       public static final String OUTLINE_LINK_WITH_EDITOR =
+               "linkOutlineWithEditor"; //$NON-NLS-1$
+
+       public static final String OUTLINE_SORT_LEXICALLY =
+               "sortOutlineLexically"; //$NON-NLS-1$
+
+       public static final String CONTENTASSIST_AUTOACTIVATION =
+               "contentAssistAutoActivation"; //$NON-NLS-1$
+
+       public static final String CONTENTASSIST_AUTOACTIVATION_DELAY =
+               "contentAssistAutoActivationDelay"; //$NON-NLS-1$
+
+       public static final String CONTENTASSIST_AUTOACTIVATION_TRIGGERS =
+               "contentAssistAutoActivationTriggers"; //$NON-NLS-1$
+
+       public static final String CONTENTASSIST_AUTOINSERT =
+               "contentAssistAutoInsert"; //$NON-NLS-1$
+
+       public static final String CONTENTASSIST_ORDER_PROPOSALS =
+               "contentAssistOrderProposals"; //$NON-NLS-1$
+
+       public static final String CONTENTASSIST_PROPOSALS_BACKGROUND =
+               "contentAssistProposalsBackground"; //$NON-NLS-1$
+
+       public static final String CONTENTASSIST_PROPOSALS_FOREGROUND =
+               "contentAssistProposalsForeground"; //$NON-NLS-1$
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Hidden constructor.
+        */
+       private CssUIPreferences() {
+               // Hidden
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Initializes the preference store with the default values.
+        * 
+        * @param store The preference store to initialize
+        */
+       public static final void initializeDefaultValues(IPreferenceStore store) {
+
+               // Appearance
+               store.setDefault(EDITOR_TAB_WIDTH, 4);
+               store.setDefault(EDITOR_MATCHING_BRACKETS, true);
+               PreferenceConverter.setDefault(store, EDITOR_MATCHING_BRACKETS_COLOR,
+                       new RGB(192, 192, 192));
+
+               // Syntax
+               store.setDefault(EDITOR_FOREGROUND_DEFAULT_COLOR, true);
+               store.setDefault(EDITOR_BACKGROUND_DEFAULT_COLOR, true);
+               PreferenceConverter.setDefault(store, EDITOR_COMMENT_COLOR,
+                       new RGB(63, 127, 95));
+               store.setDefault(EDITOR_COMMENT_BOLD, false);
+               PreferenceConverter.setDefault(store, EDITOR_PROPERTY_COLOR,
+                       new RGB(127, 0, 85));
+               store.setDefault(EDITOR_PROPERTY_BOLD, true);
+               PreferenceConverter.setDefault(store, EDITOR_AT_KEYWORD_COLOR,
+                       new RGB(127, 0, 85));
+               store.setDefault(EDITOR_AT_KEYWORD_BOLD, true);
+               PreferenceConverter.setDefault(store, EDITOR_PSEUDO_CLASS_COLOR,
+                       new RGB(0, 0, 0));
+               store.setDefault(EDITOR_PSEUDO_CLASS_BOLD, false);
+               PreferenceConverter.setDefault(store, EDITOR_STRING_COLOR,
+                       new RGB(42, 0, 255));
+               store.setDefault(EDITOR_STRING_BOLD, false);
+               PreferenceConverter.setDefault(store, EDITOR_DEFAULT_COLOR,
+                       new RGB(0, 0, 0));
+               store.setDefault(EDITOR_DEFAULT_BOLD, false);
+
+               // Content assist
+               store.setDefault(CONTENTASSIST_AUTOINSERT, false);
+               store.setDefault(CONTENTASSIST_ORDER_PROPOSALS, false);
+               store.setDefault(CONTENTASSIST_AUTOACTIVATION, true);
+               store.setDefault(CONTENTASSIST_AUTOACTIVATION_DELAY, 500);
+               store.setDefault(CONTENTASSIST_AUTOACTIVATION_TRIGGERS,
+                       "-@:"); //$NON-NLS-1$
+               PreferenceConverter.setDefault(store,
+                       CONTENTASSIST_PROPOSALS_BACKGROUND, new RGB(254, 241, 233));
+               PreferenceConverter.setDefault(store,
+                       CONTENTASSIST_PROPOSALS_FOREGROUND, new RGB(0, 0, 0));
+
+               // Typing
+               store.setDefault(EDITOR_TAB_WIDTH, 4);
+               store.setDefault(EDITOR_SPACES_FOR_TABS, false);
+               store.setDefault(EDITOR_CLOSE_STRINGS, true);
+               store.setDefault(EDITOR_CLOSE_BRACKETS_AND_PARENS, true);
+               store.setDefault(EDITOR_CLOSE_BRACES, true);
+
+               // Outline
+               store.setDefault(OUTLINE_SORT_LEXICALLY, false);
+               store.setDefault(OUTLINE_LINK_WITH_EDITOR, false);
+       }
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/ICssUIHelpContextIds.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/ICssUIHelpContextIds.java
new file mode 100644 (file)
index 0000000..693a1a2
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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: ICssUIHelpContextIds.java,v 1.1 2004-09-02 18:11:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal;
+
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+
+/**
+ * Symbolic constants for the help context IDs.
+ */
+public interface ICssUIHelpContextIds {
+
+       /** 
+        * The string with which all other defined ids are prefixed to construct
+        * help context ids. 
+        */
+       String PREFIX = CssUI.getPluginId() + "."; //$NON-NLS-1$
+
+       /**
+        * Help context ID for the CSS editor.
+        * Value: <code>"net.sourceforge.phpeclipse.css.ui.editor_context"</code>.
+        */
+       String EDITOR = PREFIX + "css_editor_context"; //$NON-NLS-1$
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/compare/CssMergeViewer.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/compare/CssMergeViewer.java
new file mode 100644 (file)
index 0000000..ba08f3c
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * 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: CssMergeViewer.java,v 1.1 2004-09-02 18:11:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.compare;
+
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIMessages;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIPreferences;
+import net.sourceforge.phpeclipse.css.ui.internal.text.CssSourceViewerConfiguration;
+import net.sourceforge.phpeclipse.css.ui.text.CssTextTools;
+
+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;
+
+/**
+ * Merge viewer for CSS files.
+ */
+public class CssMergeViewer extends TextMergeViewer {
+
+       // Constants ---------------------------------------------------------------
+
+       /**
+        * Alias for the preference constant <code>EDITOR_BACKGROUND_COLOR</code>.
+        */
+       private static final String PREFERENCE_BACKGROUND_COLOR =
+               CssUIPreferences.EDITOR_BACKGROUND_COLOR;
+
+       /**
+        * Alias for the preference constant
+        * <code>EDITOR_BACKGROUND_DEFAULT_COLOR</code>.
+        */
+       private static final String PREFERENCE_BACKGROUND_DEFAULT_COLOR =
+               CssUIPreferences.EDITOR_BACKGROUND_DEFAULT_COLOR;
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The preference store.
+        */
+       private IPreferenceStore preferenceStore;
+
+       /**
+        * The listener for changes to the preference store. 
+        */
+       private IPropertyChangeListener propertyChangeListener;
+
+       /**
+        * The CSS text tools.
+        */
+       private CssTextTools textTools;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param parent the parent control
+        * @param style SWT style bits for top level composite of this viewer
+        * @param configuration the configuration object
+        */
+       public CssMergeViewer(Composite parent, int style,
+               CompareConfiguration configuration) {
+               super(parent, style, configuration);
+       }
+
+       // TextMergeViewer Implementation ------------------------------------------
+
+       /*
+        * @see TextMergeViewer#configureTextViewer()
+        */
+       protected void configureTextViewer(TextViewer textViewer) {
+
+               CssUI plugin = CssUI.getDefault();
+
+               this.preferenceStore = plugin.getPreferenceStore();
+               if (preferenceStore != null) {
+                        propertyChangeListener = new IPropertyChangeListener() {
+                               public void propertyChange(PropertyChangeEvent event) {
+                                       handlePreferenceStoreChanged(event);
+                               }
+                       };
+                       preferenceStore.addPropertyChangeListener(propertyChangeListener);
+               }
+
+               textTools = plugin.getTextTools();
+               if (textViewer instanceof SourceViewer) {
+                       SourceViewer sourceViewer = (SourceViewer) textViewer;
+                       sourceViewer.configure(new CssSourceViewerConfiguration(
+                               textTools, preferenceStore));
+               }
+
+               updateBackgroundColor();
+       }
+
+       /*
+        * @see TextMergeViewer#getDocumentPartitioner()
+        */
+       protected IDocumentPartitioner getDocumentPartitioner() {
+               return textTools.createDocumentPartitioner();
+       }
+
+       /*
+        * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#getTitle()
+        */
+       public String getTitle() {
+               return CssUIMessages.getString(
+                       "CssMergeViewer.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);
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       /**
+        * Called when the preference store notifies us about a change.
+        * 
+        * @param event the change event
+        */
+       protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
+               String p = event.getProperty();
+               if (PREFERENCE_BACKGROUND_COLOR.equals(p)
+                || PREFERENCE_BACKGROUND_DEFAULT_COLOR.equals(p)) {
+                       updateBackgroundColor();
+               } else if (textTools.affectsPresentation(event)) {
+                       invalidateTextPresentation();
+               }
+       }
+
+       /**
+        * Updates the background color of the merge viewer to the value set in the
+        * preferences.
+        */
+       private void updateBackgroundColor() {
+               boolean defaultBackgroundColor = preferenceStore.getBoolean(
+                       PREFERENCE_BACKGROUND_DEFAULT_COLOR);
+               if (defaultBackgroundColor) {
+                       setBackgroundColor(null);
+               } else {
+                       RGB backgroundColor = PreferenceConverter.getColor(
+                               preferenceStore, CssUIPreferences.EDITOR_BACKGROUND_COLOR);
+                       setBackgroundColor(backgroundColor);
+               }
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/compare/CssMergeViewerCreator.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/compare/CssMergeViewerCreator.java
new file mode 100644 (file)
index 0000000..d35786a
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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: CssMergeViewerCreator.java,v 1.1 2004-09-02 18:11:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.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;
+
+/**
+ * Factory for creating a CSS merge viewer.
+ */
+public class CssMergeViewerCreator implements IViewerCreator {
+
+       /*
+        * @see IViewerCreator#createViewer(Composite, CompareConfiguration)
+        */
+       public Viewer createViewer(Composite parent, CompareConfiguration config) {
+               return new CssMergeViewer(parent, SWT.NULL, config);
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/compare/CssNode.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/compare/CssNode.java
new file mode 100644 (file)
index 0000000..5786149
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * 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: CssNode.java,v 1.1 2004-09-02 18:11:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.compare;
+
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIMessages;
+
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.structuremergeviewer.DocumentRangeNode;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * 
+ */
+public class CssNode extends DocumentRangeNode implements ITypedElement {
+
+       // Constants ---------------------------------------------------------------
+
+       /**
+        * Type code for the top-level style sheet.
+        */
+       public static final int STYLE_SHEET = 0;
+
+       /**
+        * Type code for at rules.
+        */
+       public static final int AT_RULE = 1;
+
+       /**
+        * Type code for style rules.
+        */
+       public static final int STYLE_RULE = 2;
+
+       /**
+        * Type code for declarations (property-value assignment).
+        */
+       public static final int DECLARATION = 3;
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The display name of the node.
+        */
+       private String name;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor for the top-level style sheet node.
+        * 
+        * @param document The document
+        */
+       public CssNode(IDocument document) {
+               super(STYLE_SHEET, "root", document, 0, //$NON-NLS-1$
+                       document.getLength());
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param parent 
+        * @param typeCode
+        * @param id
+        * @param name
+        * @param start
+        * @param length
+        */
+       public CssNode(CssNode parent, int typeCode, String id, String name,
+               int start, int length) {
+               super(typeCode, parent.getId() + Integer.toString(typeCode) + id,
+                       parent.getDocument(), start, length);
+               this.name = name;
+       }
+
+       /**
+        * @see org.eclipse.compare.ITypedElement#getName()
+        */
+       public String getName() {
+               if (getTypeCode() == STYLE_SHEET) {
+                       return CssUIMessages.getString(
+                               "CssStructureViewer.styleSheet"); //$NON-NLS-1$
+               }
+               return name;
+       }
+
+       /**
+        * @see org.eclipse.compare.ITypedElement#getImage()
+        */
+       public Image getImage() {
+               String key = null;
+               switch (getTypeCode()) {
+                       case STYLE_SHEET: {
+                               key = CssUI.ICON_STYLE_SHEET;
+                               break;
+                       }
+                       case AT_RULE: {
+                               key = CssUI.ICON_AT_RULE;
+                               break;
+                       }
+                       case STYLE_RULE: {
+                               key = CssUI.ICON_STYLE_RULE;
+                               break;
+                       }
+                       case DECLARATION: {
+                               key = CssUI.ICON_PROPERTY;
+                               break;
+                       }
+                       default: {
+                               // we'll just return null
+                       }
+               }
+               return CssUI.getDefault().getImageRegistry().get(key);
+       }
+
+       /**
+        * @see org.eclipse.compare.ITypedElement#getType()
+        */
+       public String getType() {
+               return "css"; //$NON-NLS-1$
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/compare/CssStructureCreator.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/compare/CssStructureCreator.java
new file mode 100644 (file)
index 0000000..c9dcd14
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * 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: CssStructureCreator.java,v 1.1 2004-09-02 18:11:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.compare;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.css.core.internal.parser.DefaultCssParser;
+import net.sourceforge.phpeclipse.css.core.internal.text.CssTextUtils;
+import net.sourceforge.phpeclipse.css.core.model.IAtRule;
+import net.sourceforge.phpeclipse.css.core.model.IDeclaration;
+import net.sourceforge.phpeclipse.css.core.model.IRule;
+import net.sourceforge.phpeclipse.css.core.model.IStyleRule;
+import net.sourceforge.phpeclipse.css.core.parser.ICssParser;
+import net.sourceforge.phpeclipse.css.core.parser.LexicalErrorException;
+import net.sourceforge.phpeclipse.css.core.parser.SyntaxErrorException;
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIMessages;
+import net.sourceforge.phpeclipse.css.ui.text.CssTextTools;
+
+import org.eclipse.compare.IStreamContentAccessor;
+import org.eclipse.compare.internal.DocumentManager;
+import org.eclipse.compare.structuremergeviewer.IStructureComparator;
+import org.eclipse.compare.structuremergeviewer.IStructureCreator;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+
+/**
+ * TODO Check why the root node is not being displayed
+ */
+public class CssStructureCreator implements IStructureCreator {
+
+       // IStructureCreator Implementation ----------------------------------------
+
+       /*
+        * @see IStructureCreator#getName()
+        */
+       public String getName() {
+               return CssUIMessages.getString(
+                       "CssStructureViewer.title"); //$NON-NLS-1$
+       }
+
+       /*
+        * @see IStructureCreator#getStructure(Object)
+        */
+       public IStructureComparator getStructure(final Object input) {
+               IDocument doc = DocumentManager.get(input);
+               if (doc == null) {
+                       if (input instanceof IStreamContentAccessor) {
+                               doc = createDocument((IStreamContentAccessor) input);
+                       }
+               }
+               if (doc != null) {
+                       CssNode node = new CssNode(doc);
+                       ICssParser parser = new DefaultCssParser();
+                       parser.setSource(doc);
+                       try {
+                               IRule[] rules = parser.parseRules(null);
+                               for (int i = 0; i < rules.length; i++) {
+                                       node.addChild(createNode(node, rules[i], new HashMap()));
+                               }
+                       } catch (LexicalErrorException e) {
+                               // just return null
+                       } catch (SyntaxErrorException e) {
+                               // just return null
+                       }
+                       return node;
+               }
+               return null;
+       }
+
+       /*
+        * @see IStructureCreator#locate(Object, Object)
+        */
+       public IStructureComparator locate(Object path, Object input) {
+               // TODO Find out what locate() is about and implement the functionality
+               return null;
+       }
+
+       /*
+        * @see IStructureCreator#getContents(Object, boolean)
+        */
+       public String getContents(Object node, boolean ignoreWhitespace) {
+               if (node instanceof CssNode) {
+                       CssNode cssNode = (CssNode) node;
+                       int ch;
+                       InputStream in = null;
+                       try {
+                               StringBuffer buf = new StringBuffer();
+                               in = cssNode.getContents();
+                               while ((ch = in.read()) != -1) {
+                                       if (!ignoreWhitespace
+                                        || !CssTextUtils.isCssWhitespace((char) ch)) {
+                                               buf.append((char) ch);
+                                       }
+                               }
+                               return buf.toString();
+                       } catch (IOException e) {
+                               // just return an empty string
+                       } finally {
+                               if (in != null) {
+                                       try {
+                                               in.close();
+                                       } catch (IOException e1) {
+                                               // ignore
+                                       }
+                               }
+                       }
+               }
+               return ""; //$NON-NLS-1$
+       }
+
+       /*
+        * @see IStructureCreator#save(IStructureComparator, Object)
+        */
+       public void save(IStructureComparator node, Object input) {
+               // TODO Find out what save() is about and implement the functionality
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private IDocument createDocument(IStreamContentAccessor content) {
+               IDocument document = null;
+               InputStreamReader in = null;
+               try {
+                       in = new InputStreamReader(content.getContents());
+                       StringBuffer buf = new StringBuffer();
+                       int ch;
+                       while ((ch = in.read()) != -1) {
+                               buf.append((char) ch);
+                       }
+                       document = new Document(buf.toString());
+                       DocumentManager.put(content, document);
+                       CssTextTools tools = CssUI.getDefault().getTextTools();
+                       tools.setupDocument(document);
+               } catch (CoreException e) {
+                       CssUI.log(e);
+               } catch (IOException e) {
+                       CssUI.log(e);
+               } finally {
+                       if (in != null) {
+                               try {
+                                       in.close();
+                               } catch (IOException e) {
+                                       // ignore
+                               }
+                       }
+               }
+               return document;
+       }
+
+       private CssNode createNode(CssNode parent, IRule rule, Map names) {
+               int typeCode = -1;
+               String name = ""; //$NON-NLS-1$
+               if (rule instanceof IAtRule) {
+                       IAtRule atRule = (IAtRule) rule;
+                       typeCode = CssNode.AT_RULE;
+                       ISourceReference atKeyword = atRule.getName();
+                       if (atKeyword != null) {
+                               name = atKeyword.getSource();
+                       }
+               } else if (rule instanceof IStyleRule) {
+                       IStyleRule styleRule = (IStyleRule) rule;
+                       typeCode = CssNode.STYLE_RULE;
+                       ISourceReference selector = styleRule.getSelector();
+                       if (selector != null) {
+                               name = selector.getSource();
+                       }
+               }
+               String id = name;
+               if (names.containsKey(name)) {
+                       Integer count = (Integer) names.get(name);
+                       id += count.toString();
+                       names.put(name, new Integer(count.intValue() + 1));
+               } else {
+                       names.put(name, new Integer(0));
+               }
+               IRegion region = rule.getSourceRegion();
+               CssNode node = new CssNode(parent, typeCode, id, name,
+                       region.getOffset(), region.getLength());
+               IRule[] children = rule.getChildren();
+               if (children.length > 0) {
+                       Map ruleNames = new HashMap();
+                       for (int i = 0; i < children.length; i++) {
+                               node.addChild(createNode(node, children[i], ruleNames));
+                       }
+               }
+               IDeclaration[] properties = rule.getDeclarations();
+               if (properties.length > 0) {
+                       Map propertyNames = new HashMap();
+                       for (int i = 0; i < properties.length; i++) {
+                               node.addChild(createNode(node, properties[i], propertyNames));
+                       }
+               }
+               return node;
+       }
+
+       private CssNode createNode(CssNode parent, IDeclaration declaration,
+               Map names) {
+               String name = ""; //$NON-NLS-1$
+               ISourceReference property = declaration.getProperty();
+               if (property != null) {
+                       name = property.getSource();
+               }
+               String id = name;
+               if (names.containsKey(name)) {
+                       Integer count = (Integer) names.get(name);
+                       id += count.toString();
+                       names.put(name, new Integer(count.intValue() + 1));
+               } else {
+                       names.put(name, new Integer(0));
+               }
+               IRegion region = declaration.getSourceRegion();
+               return new CssNode(parent, CssNode.DECLARATION, id, name,
+                       region.getOffset(), region.getLength());
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/CommentAction.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/CommentAction.java
new file mode 100644 (file)
index 0000000..b92b1ee
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * 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: CommentAction.java,v 1.1 2004-09-02 18:11:50 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.editor;
+
+import java.util.ResourceBundle;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRewriteTarget;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ITextEditorExtension2;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+/**
+ * (Heavily inspired by the AddBlockComment class in JDT-UI)
+ */
+public class CommentAction extends TextEditorAction {
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param bundle the resource bundle
+        * @param prefix a prefix to be prepended to the various resource keys
+        *        (described in <code>ResourceAction</code> constructor), or 
+        *        <code>null</code> if none
+        * @param editor the text editor
+        */
+       public CommentAction(ResourceBundle bundle, String prefix,
+               ITextEditor editor) {
+               super(bundle, prefix, editor);
+       }
+       
+       // TextEditorAction Implementation -----------------------------------------
+
+       /**
+        * @see org.eclipse.jface.action.Action#run()
+        */
+       public void run() {
+               if (!isEnabled()) {
+                       return;
+               }
+               ITextEditor editor = getTextEditor();
+               if ((editor == null) || !ensureEditable(editor)) {
+                       return;
+               }
+               ITextSelection selection = getCurrentSelection();
+               if (!validSelection(selection)) {
+                       return;
+               }
+               IDocumentProvider docProvider = editor.getDocumentProvider();
+               IEditorInput input = editor.getEditorInput();
+               if (docProvider == null || input == null) {
+                       return;
+               }
+               IDocument document = docProvider.getDocument(input);
+               if (document == null) {
+                       return;
+               }
+               IRewriteTarget target = (IRewriteTarget) 
+                       editor.getAdapter(IRewriteTarget.class);
+               if (target != null) {
+                       target.beginCompoundChange();
+               }
+               try {
+                       int offset = selection.getOffset();
+                       String start = "/*"; //$NON-NLS-1$
+                       document.replace(offset, 0, start);
+                       document.replace(offset + selection.getLength() + start.length(), 0,
+                               "*/"); //$NON-NLS-1$
+               } catch (BadLocationException e) {
+                       // ignore
+               } finally {
+                       if (target != null) {
+                               target.endCompoundChange();
+                       }
+               }
+       }
+       
+       /**
+        * @see org.eclipse.ui.texteditor.TextEditorAction#update()
+        */
+       public void update() {
+               super.update();
+               if (isEnabled()) {
+                       if (!validSelection(getCurrentSelection())) {
+                               setEnabled(false);
+                       }
+               }
+       }
+       
+       // Private Methods ---------------------------------------------------------
+
+       /**
+        * Ensures that the editor is modifyable. If the editor is an instance of
+        * <code>ITextEditorExtension2</code>, its 
+        * <code>validateEditorInputState</code> method is called, otherwise, the 
+        * result of <code>isEditable</code> is returned.
+        * 
+        * @param editor the editor to be checked
+        * @return <code>true</code> if the editor is editable, <code>false</code> 
+        *         otherwise
+        */
+       private boolean ensureEditable(ITextEditor editor) {
+               if (editor instanceof ITextEditorExtension2) {
+                       ITextEditorExtension2 extension = (ITextEditorExtension2) editor;
+                       return extension.validateEditorInputState();
+               }
+               return editor.isEditable();
+       }
+
+       /**
+        * Returns the editor's selection, or <code>null</code> if no selection can 
+        * be obtained or the editor is <code>null</code>.
+        * 
+        * @return the selection of the action's editor, or <code>null</code>
+        */
+       private ITextSelection getCurrentSelection() {
+               ITextEditor editor = getTextEditor();
+               if (editor != null) {
+                       ISelectionProvider provider = editor.getSelectionProvider();
+                       if (provider != null) {
+                               ISelection selection = provider.getSelection();
+                               if (selection instanceof ITextSelection) {
+                                       return (ITextSelection) selection;
+                               }
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Checks whether <code>selection</code> is valid, i.e. neither 
+        * <code>null</code> or empty.
+        * 
+        * @param selection the selection to check
+        * @return <code>true</code> if the selection is valid, <code>false</code> 
+        *         otherwise
+        */
+       private boolean validSelection(ITextSelection selection) {
+               if (selection != null) {
+                       return (!selection.isEmpty() && (selection.getLength() > 0));
+               }
+               return false;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/CssEditor.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/CssEditor.java
new file mode 100644 (file)
index 0000000..41b8129
--- /dev/null
@@ -0,0 +1,367 @@
+/*
+ * 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: CssEditor.java,v 1.1 2004-09-02 18:11:50 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.editor;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.css.core.model.IAtRule;
+import net.sourceforge.phpeclipse.css.core.model.IRule;
+import net.sourceforge.phpeclipse.css.core.model.IStyleRule;
+import net.sourceforge.phpeclipse.css.core.model.IStyleSheet;
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+import net.sourceforge.phpeclipse.css.ui.internal.CssDocumentProvider;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIMessages;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIPreferences;
+import net.sourceforge.phpeclipse.css.ui.internal.ICssUIHelpContextIds;
+import net.sourceforge.phpeclipse.css.ui.internal.outline.CssOutlinePage;
+import net.sourceforge.phpeclipse.css.ui.internal.text.CssPairMatcher;
+import net.sourceforge.phpeclipse.css.ui.internal.text.CssSourceViewerConfiguration;
+import net.sourceforge.phpeclipse.css.ui.internal.text.IReconcilingParticipant;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.source.ISourceViewer;
+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.custom.StyledText;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.editors.text.TextEditor;
+import org.eclipse.ui.texteditor.ContentAssistAction;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+
+/**
+ * Implementation of a CSS editor based on the text editor infrastructure
+ * provided by the platform.
+ * 
+ * TODO Reacting to every caret move seems rather expensive. Ideally, we'd
+ *      collect the caret position changes and react after a specific delay.
+ */
+public class CssEditor extends TextEditor implements IReconcilingParticipant {
+
+       // Inner Classes -----------------------------------------------------------
+
+       /**
+        * 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);
+
+                               IRegion selectedRegion = null;
+                               if (element instanceof IAtRule) {
+                                       IAtRule atRule = (IAtRule) element;
+                                       selectedRegion = atRule.getValue().getSourceRegion();
+                               } else if (element instanceof IStyleRule) {
+                                       IStyleRule styleRule = (IStyleRule) element;
+                                       selectedRegion = styleRule.getSelector().getSourceRegion();
+                               }
+
+                               if (selectedRegion != null) {
+                                       selectAndReveal(selectedRegion.getOffset(),
+                                       selectedRegion.getLength());
+                               }
+                       }
+               }
+       }
+
+       // Constants ---------------------------------------------------------------
+
+       /**
+        * Alias for the preference constant <code>OUTLINE_LINK_WITH_EDITOR</code>.
+        */
+       private static final String LINK_WITH_OUTLINE =
+               CssUIPreferences.OUTLINE_LINK_WITH_EDITOR;
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The associated outline page.
+        */
+       CssOutlinePage outlinePage;
+
+       /**
+        * Listens to changes in the outline page's selection to update the editor
+        * selection and highlight range.
+        */
+       private ISelectionChangedListener outlineSelectionChangedListener;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Default constructor.
+        */
+       public CssEditor() {
+               setSourceViewerConfiguration(
+                       new CssSourceViewerConfiguration(
+                                       CssUI.getDefault().getTextTools(),
+                                       getPreferenceStore(), this));
+       }
+
+       // AbstractTextEditor Implementation ---------------------------------------
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractTextEditor#affectsTextPresentation(PropertyChangeEvent)
+        */
+       protected boolean affectsTextPresentation(PropertyChangeEvent event) {
+               String p = event.getProperty();
+               if (CssUIPreferences.EDITOR_DEFAULT_COLOR.equals(p) ||
+                       CssUIPreferences.EDITOR_DEFAULT_BOLD.equals(p) ||
+                       CssUIPreferences.EDITOR_COMMENT_COLOR.equals(p) ||
+                       CssUIPreferences.EDITOR_COMMENT_BOLD.equals(p) ||
+                       CssUIPreferences.EDITOR_STRING_COLOR.equals(p) ||
+                       CssUIPreferences.EDITOR_STRING_BOLD.equals(p) ||
+                       CssUIPreferences.EDITOR_PROPERTY_COLOR.equals(p) ||
+                       CssUIPreferences.EDITOR_PROPERTY_BOLD.equals(p) ||
+                       CssUIPreferences.EDITOR_AT_KEYWORD_COLOR.equals(p) ||
+                       CssUIPreferences.EDITOR_AT_KEYWORD_BOLD.equals(p) ||
+                       CssUIPreferences.EDITOR_PSEUDO_CLASS_COLOR.equals(p) ||
+                       CssUIPreferences.EDITOR_PSEUDO_CLASS_BOLD.equals(p)
+               ) {
+                       return true;
+               }
+
+               return super.affectsTextPresentation(event);
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractTextEditor#createActions()
+        */
+       protected void createActions() {
+               super.createActions();
+
+               IAction action;
+
+               action = new ContentAssistAction(
+                       CssUIMessages.getResourceBundle(),
+                       "CssEditor.contentAssist.", this); //$NON-NLS-1$
+               action.setActionDefinitionId(
+                       ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+               setAction(ICssEditorActionConstants.CONTENT_ASSIST, action);
+
+               action = new CommentAction(
+                       CssUIMessages.getResourceBundle(),
+                       "CssEditor.comment.", this); //$NON-NLS-1$
+               action.setActionDefinitionId(ICssEditorActionDefinitionIds.COMMENT);
+               setAction(ICssEditorActionConstants.COMMENT, action);
+               markAsStateDependentAction(ICssEditorActionConstants.COMMENT, true);
+               markAsSelectionDependentAction(ICssEditorActionConstants.COMMENT, true);
+
+               action = new UncommentAction(
+                       CssUIMessages.getResourceBundle(),
+                       "CssEditor.uncomment.", this); //$NON-NLS-1$
+               action.setActionDefinitionId(ICssEditorActionDefinitionIds.UNCOMMENT);
+               setAction(ICssEditorActionConstants.UNCOMMENT, action);
+               markAsStateDependentAction(ICssEditorActionConstants.UNCOMMENT, true);
+               markAsSelectionDependentAction(ICssEditorActionConstants.UNCOMMENT,
+                       true);
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.ExtendedTextEditor#configureSourceViewerDecorationSupport(SourceViewerDecorationSupport)
+        */
+       protected void configureSourceViewerDecorationSupport(
+               SourceViewerDecorationSupport support
+       ) {
+               super.configureSourceViewerDecorationSupport(support);
+
+               support.setCharacterPairMatcher(new CssPairMatcher());
+               support.setMatchingCharacterPainterPreferenceKeys(
+                       CssUIPreferences.EDITOR_MATCHING_BRACKETS,
+                       CssUIPreferences.EDITOR_MATCHING_BRACKETS_COLOR);
+               support.setSymbolicFontName(getFontPropertyPreferenceKey());
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractTextEditor#getAdapter(Class)
+        */
+       public Object getAdapter(Class adapter) {
+               if (IContentOutlinePage.class.equals(adapter)) {
+                       if (outlinePage == null) {
+                               outlinePage = new CssOutlinePage(this);
+                               outlineSelectionChangedListener =
+                                       new OutlineSelectionChangedListener();
+                               outlinePage.addSelectionChangedListener(
+                                       outlineSelectionChangedListener);
+                       }
+
+                       return outlinePage;
+               }
+
+               return super.getAdapter(adapter);
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractTextEditor#handleCursorPositionChanged()
+        */
+       protected void handleCursorPositionChanged() {
+               super.handleCursorPositionChanged();
+
+               highlightElement(computeHighlightRangeSourceReference(), false);
+               synchronizeOutlinePageSelection();
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.ExtendedTextEditor#initializeEditor()
+        */
+       protected void initializeEditor() {
+               super.initializeEditor();
+
+               setHelpContextId(ICssUIHelpContextIds.EDITOR);
+               setPreferenceStore(CssUI.getDefault().getPreferenceStore());
+               configureInsertMode(SMART_INSERT, true);
+               setInsertMode(SMART_INSERT);
+       }
+
+       // IReconcilingParticipant Implementation ----------------------------------
+
+       /* 
+        * @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();
+                                       }
+                                       synchronizeOutlinePageSelection();
+                               }
+                       });
+               }
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Computes and returns the source reference that includes the caret and
+        * serves as provider for the outline page selection and the editor range
+        * indication.
+        * 
+        * @return the computed source reference
+        */
+       public ISourceReference computeHighlightRangeSourceReference() {
+               ISourceViewer sourceViewer = getSourceViewer();
+               if (sourceViewer == null) {
+                       return null;
+               }
+
+               StyledText styledText = sourceViewer.getTextWidget();
+               if ((styledText == null) || styledText.isDisposed()) {
+                       return null;
+               }
+
+               int offset = sourceViewer.getVisibleRegion().getOffset();
+               int caret = offset + styledText.getCaretOffset();
+
+               return getRuleAt(caret);
+       }
+
+       /**
+        * Informs the editor that its outliner has been closed.
+        * 
+        * TODO There must be a more elegant way to get notified when the outline 
+        *      page was closed. Otherwise move this method into an interface
+        */
+       public void outlinePageClosed() {
+               if (outlinePage != null) {
+                       outlinePage.removeSelectionChangedListener(
+                                       outlineSelectionChangedListener);
+                       outlinePage = null;
+                       resetHighlightRange();
+               }
+       }
+
+       /**
+        * Synchronizes the outliner selection with the given element position in 
+        * the editor.
+        * 
+        * @param element the java element to select
+        */
+       public void synchronizeOutlinePage(ISourceReference element) {
+               if (outlinePage != null) {
+                       outlinePage.removeSelectionChangedListener(
+                               outlineSelectionChangedListener);
+                       outlinePage.select(element);
+                       outlinePage.addSelectionChangedListener(
+                               outlineSelectionChangedListener);
+               }
+       }
+
+       /**
+        * Synchronizes the outliner selection with the currently highlighted source
+        * reference.
+        */
+       public void synchronizeOutlinePage() {
+               ISourceReference element = computeHighlightRangeSourceReference();
+               synchronizeOutlinePage(element);
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private IRule getRuleAt(int offset) {
+               IStyleSheet styleSheet = getStyleSheet();
+               if (styleSheet == null) {
+                       return null;
+               }
+
+               return styleSheet.getRuleAt(offset);
+       }
+
+       private IStyleSheet getStyleSheet() {
+               if (getDocumentProvider() instanceof CssDocumentProvider) {
+                       CssDocumentProvider p = (CssDocumentProvider) getDocumentProvider();
+                       return p.getStyleSheet(getEditorInput());
+               }
+
+               return null;
+       }
+
+       void highlightElement(ISourceReference element, boolean moveCursor) {
+               if (element != null) {
+                       IRegion highlightRegion = element.getSourceRegion();
+                       setHighlightRange(highlightRegion.getOffset(),
+                               highlightRegion.getLength(), moveCursor);
+               } else {
+                       resetHighlightRange();
+               }
+       }
+
+       void synchronizeOutlinePageSelection() {
+               IPreferenceStore store = getPreferenceStore();
+               if (store != null) {
+                       boolean linkWithEditor = store.getBoolean(LINK_WITH_OUTLINE);
+                       if (linkWithEditor) {
+                               synchronizeOutlinePage(computeHighlightRangeSourceReference());
+                       }
+               }
+       }
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/CssEditorActionContributor.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/CssEditorActionContributor.java
new file mode 100644 (file)
index 0000000..5107b71
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * 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: CssEditorActionContributor.java,v 1.1 2004-09-02 18:11:50 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.editor;
+
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIMessages;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.texteditor.BasicTextEditorActionContributor;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.texteditor.RetargetTextEditorAction;
+
+/**
+ * 
+ */
+public class CssEditorActionContributor
+       extends BasicTextEditorActionContributor {
+
+       // Instance Variables ------------------------------------------------------
+
+       private RetargetTextEditorAction contentAssistAction =
+               new RetargetTextEditorAction(CssUIMessages.getResourceBundle(),
+                       "CssEditor.contentAssistProposal."); //$NON-NLS-1$
+
+       private ShowSelectedElementOnlyAction showSelectedElementOnlyAction = 
+               new ShowSelectedElementOnlyAction(); //$NON-NLS-1$
+
+       // IEditorActionBarContributor Implementation ------------------------------
+
+       /**
+        * @see org.eclipse.ui.part.EditorActionBarContributor#contributeToMenu(IMenuManager)
+        */
+       public void contributeToMenu(IMenuManager menu) {
+               super.contributeToMenu(menu);
+               IMenuManager editMenu = menu.findMenuUsingPath(
+                       IWorkbenchActionConstants.M_EDIT);
+               if (editMenu != null) {
+                       editMenu.add(new Separator());
+                       editMenu.add(this.contentAssistAction);
+               }
+       }
+
+       /**
+        * @see org.eclipse.ui.part.EditorActionBarContributor#contributeToToolBar(IToolBarManager)
+        */
+       public void contributeToToolBar(IToolBarManager toolBarManager) {
+               super.contributeToToolBar(toolBarManager);
+               if (toolBarManager != null) {
+                       toolBarManager.add(new Separator());
+               }
+       }
+
+       /**
+        * @see org.eclipse.ui.IEditorActionBarContributor#dispose()
+        */
+       public void dispose() {
+               doSetActiveEditor(null);
+               super.dispose();
+       }
+
+       /**
+        * @see org.eclipse.ui.IEditorActionBarContributor#setActiveEditor(IEditorPart)
+        */
+       public void setActiveEditor(IEditorPart part) {
+               super.setActiveEditor(part);
+               doSetActiveEditor(part);
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private void doSetActiveEditor(IEditorPart part) {
+               ITextEditor editor = null;
+               if (part instanceof ITextEditor) {
+                       editor = (ITextEditor) part;
+               }
+
+               contentAssistAction.setAction(
+                       getAction(editor, ICssEditorActionConstants.CONTENT_ASSIST));
+
+               showSelectedElementOnlyAction.setEditor(editor);
+               showSelectedElementOnlyAction.update();
+
+               IActionBars bars = getActionBars();      
+               bars.setGlobalActionHandler(
+                       ITextEditorActionDefinitionIds.TOGGLE_SHOW_SELECTED_ELEMENT_ONLY,
+                       showSelectedElementOnlyAction);
+               bars.setGlobalActionHandler(
+                       ICssEditorActionDefinitionIds.COMMENT,
+                       getAction(editor, ICssEditorActionConstants.COMMENT));
+               bars.setGlobalActionHandler(
+                       ICssEditorActionDefinitionIds.UNCOMMENT,
+                       getAction(editor, ICssEditorActionConstants.UNCOMMENT));
+               bars.setGlobalActionHandler(
+                       ITextEditorActionDefinitionIds.SHIFT_LEFT,
+                       getAction(editor, ITextEditorActionConstants.SHIFT_LEFT));
+               bars.setGlobalActionHandler(
+                       ITextEditorActionDefinitionIds.SHIFT_RIGHT,
+                       getAction(editor, ITextEditorActionConstants.SHIFT_RIGHT));
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/ICssEditorActionConstants.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/ICssEditorActionConstants.java
new file mode 100644 (file)
index 0000000..9c231f4
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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: ICssEditorActionConstants.java,v 1.1 2004-09-02 18:11:50 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.editor;
+
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+
+/**
+ * 
+ */
+public interface ICssEditorActionConstants
+       extends ITextEditorActionConstants {
+
+       /**
+        * Edit menu: name of the standard global action "Content Assist"
+        * (value <code>"ContentAssist"</code>).
+        */
+       String CONTENT_ASSIST = "ContentAssist";  //$NON-NLS-1$
+
+       /**
+        * Source menu: name of standard global action "Comment"
+        * (value <code>"Comment"</code>).
+        */
+       String COMMENT = "Comment"; //$NON-NLS-1$
+
+       /**
+        * Source menu: name of standard global action "Uncomment"
+        * (value <code>"Uncomment"</code>).
+        */
+       String UNCOMMENT = "Uncomment"; //$NON-NLS-1$
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/ICssEditorActionDefinitionIds.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/ICssEditorActionDefinitionIds.java
new file mode 100644 (file)
index 0000000..da4ad4a
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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: ICssEditorActionDefinitionIds.java,v 1.1 2004-09-02 18:11:50 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.editor;
+
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+
+/**
+ * Action definition IDs used by the CSS editor.
+ */
+public interface ICssEditorActionDefinitionIds
+       extends ITextEditorActionDefinitionIds {
+
+       /**
+        * Action definition ID of the "Source &gt; Comment" action
+        * (value <code>"net.sourceforge.phpeclipse.css.ui.commentAction"</code>).
+        */
+       String COMMENT = "net.sourceforge.phpeclipse.css.ui.commentAction"; //$NON-NLS-1$
+
+       /**
+        * Action definition ID of the "Source &gt; Uncomment" action
+        * (value <code>"net.sourceforge.phpeclipse.css.ui.uncommentAction"</code>).
+        */
+       String UNCOMMENT = "net.sourceforge.phpeclipse.css.ui.uncommentAction"; //$NON-NLS-1$
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/ShowSelectedElementOnlyAction.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/ShowSelectedElementOnlyAction.java
new file mode 100644 (file)
index 0000000..ab1e80f
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * 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: ShowSelectedElementOnlyAction.java,v 1.1 2004-09-02 18:11:50 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.editor;
+
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIMessages;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIPreferences;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+/**
+ * A toolbar action which toggles the presentation model of the connected text 
+ * editor. The editor shows either the highlight range only or always the whole 
+ * document.
+ * 
+ * <p>
+ *  This class is an implementation for the retargetable action 
+ *  <code>TOGGLE_SHOW_SELECTED_ELEMENT_ONLY</code> provided by the platform.
+ * </p>
+ * 
+ * @see org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds#TOGGLE_SHOW_SELECTED_ELEMENT_ONLY
+ */
+public class ShowSelectedElementOnlyAction extends TextEditorAction
+       implements IPropertyChangeListener {
+
+       // Instance Variables ------------------------------------------------------
+
+       private IPreferenceStore store;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        */
+       public ShowSelectedElementOnlyAction() {
+               super(CssUIMessages.getResourceBundle(),
+                       "CssEditor.showSelectedElementOnly.", null); //$NON-NLS-1$
+               store = CssUI.getDefault().getPreferenceStore();
+               update();
+       }
+
+       // TextEditor Implementation -----------------------------------------------
+
+       /*
+        * @see org.eclipse.jface.action.IAction#run()
+        */
+       public void run() {
+               ITextEditor editor = getTextEditor();
+               if (editor != null) {
+                       IRegion highlightRange = editor.getHighlightRange();
+                       editor.resetHighlightRange();
+                       boolean show = !editor.showsHighlightRangeOnly();
+                       setChecked(show);
+                       editor.showHighlightRangeOnly(show);
+                       if (highlightRange != null) {
+                               editor.setHighlightRange(highlightRange.getOffset(),
+                                       highlightRange.getLength(), true);
+                       }
+                       store.removePropertyChangeListener(this);
+                       store.setValue(
+                               CssUIPreferences.EDITOR_SHOW_SELECTED_ELEMENT_ONLY, show);
+                       store.addPropertyChangeListener(this);
+               }
+       }
+
+       /*
+        * @see TextEditorAction#setEditor(ITextEditor)
+        */
+       public void setEditor(ITextEditor editor) {
+               super.setEditor(editor);
+               if (editor != null) {
+                       if (store == null) {
+                               store = CssUI.getDefault().getPreferenceStore();
+                               store.addPropertyChangeListener(this);
+                       }
+                       synchronizeWithPreference(editor);
+               } else if (store != null) {
+                       store.removePropertyChangeListener(this);
+                       store = null;
+               }
+               update();
+       }
+       
+       /*
+        * @see org.eclipse.ui.texteditor.IUpdate#update()
+        */
+       public void update() {
+               ITextEditor editor = getTextEditor();
+               if (editor != null) {
+                       setChecked(getTextEditor().showsHighlightRangeOnly());
+                       setEnabled(true);
+               } else {
+                       setEnabled(false);
+               }
+       }
+
+       // IPropertyChangeListener Implementation ----------------------------------
+
+       /*
+        * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+        */
+       public void propertyChange(PropertyChangeEvent event) {
+               String p = event.getProperty();
+               if (CssUIPreferences.EDITOR_SHOW_SELECTED_ELEMENT_ONLY.equals(p)) {
+                       synchronizeWithPreference(getTextEditor());
+               }
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       /**
+        * Synchronizes the appearance of the editor with what the preference store
+        * contains.
+        * 
+        * @param editor the editor to synchronize
+        */
+       private void synchronizeWithPreference(ITextEditor editor) {
+               if (editor != null) {
+                       boolean show = this.store.getBoolean(
+                               CssUIPreferences.EDITOR_SHOW_SELECTED_ELEMENT_ONLY);
+                       setChecked(show);
+                       if (show != editor.showsHighlightRangeOnly()) {
+                               IRegion highlightRange = editor.getHighlightRange();
+                               editor.resetHighlightRange();
+                               editor.showHighlightRangeOnly(show);
+                               if (highlightRange != null) {
+                                       editor.setHighlightRange(highlightRange.getOffset(),
+                                               highlightRange.getLength(), true);
+                               }
+                       }
+               }
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/UncommentAction.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/editor/UncommentAction.java
new file mode 100644 (file)
index 0000000..010d4dc
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * 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: UncommentAction.java,v 1.1 2004-09-02 18:11:50 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.editor;
+
+import java.util.ResourceBundle;
+
+import net.sourceforge.phpeclipse.css.ui.internal.text.CssPartitionScanner;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRewriteTarget;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ITextEditorExtension2;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+/**
+ * (Heavily inspired by the RemoveBlockComment class in JDT-UI)
+ */
+public class UncommentAction extends TextEditorAction {
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Creates a new instance.
+        * 
+        * @param bundle the resource bundle
+        * @param prefix a prefix to be prepended to the various resource keys
+        *        (described in <code>ResourceAction</code> constructor), or 
+        *        <code>null</code> if none
+        * @param editor the text editor
+        */
+       public UncommentAction(ResourceBundle bundle, String prefix,
+               ITextEditor editor) {
+               super(bundle, prefix, editor);
+       }
+       
+       // TextEditorAction Implementation -----------------------------------------
+
+       /**
+        * @see org.eclipse.jface.action.Action#run()
+        */
+       public void run() {
+               if (!isEnabled()) {
+                       return;
+               }
+               ITextEditor editor = getTextEditor();
+               if ((editor == null) || !ensureEditable(editor)) {
+                       return;
+               }
+               ITextSelection selection = getCurrentSelection();
+               if (!isValidSelection(selection)) {
+                       return;
+               }
+               IDocumentProvider docProvider = editor.getDocumentProvider();
+               IEditorInput input = editor.getEditorInput();
+               if (docProvider == null || input == null) {
+                       return;
+               }
+               IDocument document = docProvider.getDocument(input);
+               if (document == null) {
+                       return;
+               }
+               IRewriteTarget target = (IRewriteTarget)
+                       editor.getAdapter(IRewriteTarget.class);
+               if (target != null) {
+                       target.beginCompoundChange();
+               }
+               try {
+                       ITypedRegion region = getBlockCommentRegion(document, selection);
+                       if (region != null) {
+                               int offset = region.getOffset();
+                               document.replace(offset, 2, ""); //$NON-NLS-1$
+                               document.replace(offset + region.getLength() - 4, 2,
+                                       ""); //$NON-NLS-1$
+                       }
+               } catch (BadLocationException e) {
+                       // ignore
+               } finally {
+                       if (target != null) {
+                               target.endCompoundChange();
+                       }
+               }
+       }
+       
+       // Private Methods ---------------------------------------------------------
+
+       /**
+        * Ensures that the editor is modifyable. If the editor is an instance of
+        * <code>ITextEditorExtension2</code>, its 
+        * <code>validateEditorInputState</code> method is called, otherwise, the 
+        * result of <code>isEditable</code> is returned.
+        * 
+        * @param editor the editor to be checked
+        * @return <code>true</code> if the editor is editable, <code>false</code> 
+        *         otherwise
+        */
+       private boolean ensureEditable(ITextEditor editor) {
+               if (editor instanceof ITextEditorExtension2) {
+                       ITextEditorExtension2 extension = (ITextEditorExtension2) editor;
+                       return extension.validateEditorInputState();
+               }
+               return editor.isEditable();
+       }
+
+       /**
+        * Returns the block comment typed region enclosing the position at the end 
+        * of <code>selection</code> or <code>null</code> if there is no block 
+        * comment at this position.
+        * 
+        * @param selection the caret position (the end of the selection is taken as
+        *        the position)
+        * @return the block comment region at the selection's end, or 
+        *         <code>null</code>
+        */
+       private ITypedRegion getBlockCommentRegion(IDocument document,
+               ITextSelection selection) {
+               try {
+                       ITypedRegion region = document.getPartition(
+                               selection.getOffset() + selection.getLength());
+                       if (CssPartitionScanner.CSS_COMMENT.equals(region.getType())) {
+                               return region;
+                       }
+               } catch (BadLocationException e) {
+                       // ignore
+               }
+               return null;
+       }
+
+       /**
+        * Returns the editor's selection, or <code>null</code> if no selection can 
+        * be obtained or the editor is <code>null</code>.
+        * 
+        * @return the selection of the action's editor, or <code>null</code>
+        */
+       private ITextSelection getCurrentSelection() {
+               ITextEditor editor = getTextEditor();
+               if (editor != null) {
+                       ISelectionProvider provider = editor.getSelectionProvider();
+                       if (provider != null) {
+                               ISelection selection = provider.getSelection();
+                               if (selection instanceof ITextSelection) {
+                                       return (ITextSelection) selection;
+                               }
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Checks whether given selection is valid, i.e. neither <code>null</code> 
+        * or empty.
+        * 
+        * @param selection the selection to check
+        * @return <code>true</code> if the selection is valid, <code>false</code> 
+        *         otherwise
+        */
+       private boolean isValidSelection(ITextSelection selection) {
+               if (selection != null) {
+                       return (!selection.isEmpty() && (selection.getLength() > 0));
+               }
+               return false;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/CssOutlineContentProvider.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/CssOutlineContentProvider.java
new file mode 100644 (file)
index 0000000..1bd8b24
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * 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: CssOutlineContentProvider.java,v 1.1 2004-09-02 18:11:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.outline;
+
+import net.sourceforge.phpeclipse.css.core.model.IRule;
+import net.sourceforge.phpeclipse.css.core.model.IStyleSheet;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Content provider for the CSS outline page.
+ */
+public class CssOutlineContentProvider implements ITreeContentProvider {
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The parsed style sheet.
+        */
+       private IStyleSheet styleSheet;
+
+       // ITreeContentProvider Implementation -------------------------------------
+
+       /*
+        * ITreeContentProvider#getChildren(Object)
+        */
+       public Object[] getChildren(Object parentElement) {
+               if (parentElement instanceof IRule) {
+                       return ((IRule) parentElement).getChildren();
+               }
+               return new Object[0];
+       }
+
+       /*
+        * @see ITreeContentProvider#getParent(Object)
+        */
+       public Object getParent(Object element) {
+               if (element instanceof IRule) {
+                       return ((IRule) 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 (styleSheet != null) {
+                       return styleSheet.getRules();
+               }
+               return new Object[0];
+       }
+
+       /*
+        * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+        */
+       public void dispose() {
+               styleSheet = 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 IStyleSheet) {
+                               styleSheet = null;
+                       }
+                       if (newInput instanceof IStyleSheet) {
+                               IStyleSheet newStyleSheet = (IStyleSheet) newInput;
+                               styleSheet = newStyleSheet;
+                       }          
+               }
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/CssOutlineDoubleClickListener.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/CssOutlineDoubleClickListener.java
new file mode 100644 (file)
index 0000000..3a599e5
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * 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: CssOutlineDoubleClickListener.java,v 1.1 2004-09-02 18:11:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.outline;
+
+import net.sourceforge.phpeclipse.css.core.model.IStyleRule;
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
+
+/**
+ * A double click listener that is intended to be attached to an outline page
+ * displaying CSS elements. If a style rule is double clicked, it will attempt
+ * to show the standard properties view.
+ */
+public class CssOutlineDoubleClickListener implements IDoubleClickListener {
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The associated content outline page.
+        */
+       private ContentOutlinePage outlinePage;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param outlinePage the associated outline page
+        */
+       public CssOutlineDoubleClickListener(ContentOutlinePage outlinePage) {
+               this.outlinePage = outlinePage;
+       }
+
+       // IDoubleClickListener Implementation -------------------------------------
+
+       /*
+        * @see IDoubleClickListener#doubleClick(DoubleClickEvent)
+        */
+       public void doubleClick(DoubleClickEvent event) {
+               Object selectedElement = getSelectedElement(event.getSelection());
+               if (selectedElement instanceof IStyleRule) {
+                       showPropertiesView();
+               }
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       /**
+        * Shows the properties view in the current workbench window.
+        */
+       private void showPropertiesView() {
+               IWorkbenchPage workbenchPage = outlinePage.getSite().getPage();
+               try {
+                       workbenchPage.showView(IPageLayout.ID_PROP_SHEET);
+               } catch (PartInitException e) {
+                       CssUI.log(
+                               "Could not show properties view", e); //$NON-NLS-1$
+               }
+       }
+
+       /**
+        * Finds the element that is selected. As this is a double click listener,
+        * only a single element can be selected at once.
+        * 
+        * @param selection the selection
+        * @return the selected element
+        */
+       private Object getSelectedElement(ISelection selection) {
+               Object element = null;
+               if (selection instanceof IStructuredSelection) {
+                       element = ((IStructuredSelection) selection).getFirstElement();
+               }
+               return element;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/CssOutlineLabelProvider.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/CssOutlineLabelProvider.java
new file mode 100644 (file)
index 0000000..a66c266
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * 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: CssOutlineLabelProvider.java,v 1.1 2004-09-02 18:11:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.outline;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.css.core.model.IAtRule;
+import net.sourceforge.phpeclipse.css.core.model.IStyleRule;
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Label provider for the CSS outline page.
+ */
+public class CssOutlineLabelProvider extends LabelProvider {
+
+       // LabelProvider Implementation --------------------------------------------
+
+       /**
+        * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
+        */
+       public Image getImage(Object element) {
+               if (element instanceof IStyleRule) {
+                       return CssUI.getDefault().getImageRegistry().get(
+                               CssUI.ICON_STYLE_RULE);
+               } else if (element instanceof IAtRule) {
+                       return CssUI.getDefault().getImageRegistry().get(
+                               CssUI.ICON_AT_RULE);
+               }
+               return null;
+       }
+
+       /**
+        * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
+        */
+       public String getText(Object element) {
+               StringBuffer text = new StringBuffer();
+               if (element instanceof IStyleRule) {
+                       IStyleRule rule = (IStyleRule) element;
+                       ISourceReference selector = rule.getSelector();
+                       if (selector != null) {
+                               text.append(selector.getSource());
+                       }
+               } else if (element instanceof IAtRule) {
+                       IAtRule rule = (IAtRule) element;
+                       ISourceReference name = rule.getName();
+                       ISourceReference value = rule.getValue();
+                       if (name != null) {
+                               text.append(name.getSource());
+                               if (value != null) {
+                                       text.append(' ');
+                               }
+                       }
+                       if (value != null) {
+                               text.append(value.getSource());
+                       }
+               }
+               return normalizeWhitespace(text.toString());
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       /**
+        * Replaces all whitespace characters by regular spaces, and trims excessive
+        * whitespace down to at most one whitespace between non-whitespace
+        * characters.
+        * 
+        * @param text The text to normalize
+        * @return The normalized text
+        */
+       public String normalizeWhitespace(String text) {
+               StringBuffer buf = new StringBuffer();
+               boolean previousWasWhitespace = false;
+               for (int i = 0; i < text.length(); i++) {
+                       char c = text.charAt(i);
+                       if ((c == 9) || (c == 10) || (c == 13)) { // Tab
+                               c = ' ';
+                       }
+                       if ((c != ' ') || !previousWasWhitespace) {
+                               buf.append(c);
+                       }
+                       previousWasWhitespace = (c == ' ');
+               }
+               return buf.toString();
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/CssOutlinePage.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/CssOutlinePage.java
new file mode 100644 (file)
index 0000000..7db8459
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+ * 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: CssOutlinePage.java,v 1.1 2004-09-02 18:11:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.outline;
+
+import java.util.List;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.css.core.model.IAtRule;
+import net.sourceforge.phpeclipse.css.core.model.IStyleSheet;
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+import net.sourceforge.phpeclipse.css.ui.internal.CssDocumentProvider;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIMessages;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIPreferences;
+import net.sourceforge.phpeclipse.css.ui.internal.editor.CssEditor;
+import net.sourceforge.phpeclipse.css.ui.internal.editor.ShowSelectedElementOnlyAction;
+import net.sourceforge.phpeclipse.ui.views.outline.ProblemsLabelDecorator;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.action.IToolBarManager;
+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.jface.viewers.ViewerSorter;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.part.IPageSite;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.texteditor.ResourceAction;
+import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
+
+/**
+ * Implements the outline page associated with the CSS editor.
+ */
+public class CssOutlinePage extends ContentOutlinePage {
+
+       // Inner Classes -----------------------------------------------------------
+
+       /**
+        * Action that activates or deactivates the lexical sorting of elements in
+        * the outline tree viewer.
+        */
+       private class ToggleLexicalSortingAction extends ResourceAction {
+
+               // Constants -----------------------------------------------------------
+
+               private static final int CATEGORY_AT_RULE = 0;
+               private static final int CATEGORY_STYLE_RULE = 1;
+
+               // Instance Variables --------------------------------------------------
+
+               /**
+                * The viewer sorter. At-rules are displayed before style rules,
+                * otherwise the default lexical sorting applies.
+                */
+               private final ViewerSorter sorter = new ViewerSorter() {
+                       public int category(Object element) {
+                               if (element instanceof IAtRule) {
+                                       return CATEGORY_AT_RULE;
+                               } else {
+                                       return CATEGORY_STYLE_RULE;
+                               }
+                       }
+               };
+
+               // Constructors --------------------------------------------------------
+
+               /**
+                * Constructor.
+                */
+               public ToggleLexicalSortingAction() {
+                       super(CssUIMessages.getResourceBundle(),
+                               "CssOutlinePage.sort."); //$NON-NLS-1$
+                       CssUI plugin = CssUI.getDefault();
+                       boolean checked = plugin.getPreferenceStore().getBoolean(
+                               CssUIPreferences.OUTLINE_SORT_LEXICALLY); //$NON-NLS-1$
+                       valueChanged(checked, false);
+               }
+
+               // Action Implementation -----------------------------------------------
+
+               /*
+                * @see org.eclipse.jface.action.Action#run()
+                */
+               public void run() {
+                       valueChanged(isChecked(), true);
+               }
+
+               // Private Methods -----------------------------------------------------
+
+               /**
+                * Updates the sorting of the outline.
+                * 
+                * @param checked Whether lexical sorting is enabled
+                * @param store Whether the new state should be written back as a 
+                *        preference
+                */
+               private void valueChanged(final boolean checked, boolean store) {
+                       setChecked(checked);
+                       BusyIndicator.showWhile(getTreeViewer().getControl().getDisplay(),
+                               new Runnable() {
+                                       public void run() {
+                                               getTreeViewer().setSorter(checked ? sorter : null);
+                                       }
+                               });
+                       if (store) {
+                               CssUI plugin = CssUI.getDefault();
+                               plugin.getPreferenceStore().setValue(
+                                       CssUIPreferences.OUTLINE_SORT_LEXICALLY, checked);
+                       }
+               }
+
+       }
+
+       /**
+        * This action toggles whether this Java Outline page links its selection
+        * to the active editor.
+        */
+       private class ToggleLinkingAction extends ResourceAction {
+               
+               /**
+                * Constructs a new action.
+                */
+               public ToggleLinkingAction() {
+                       super(CssUIMessages.getResourceBundle(),
+                               "CssOutlinePage.linkWithEditor."); //$NON-NLS-1$
+                       CssUI plugin = CssUI.getDefault();
+                       boolean checked = plugin.getPreferenceStore().getBoolean(
+                               CssUIPreferences.OUTLINE_LINK_WITH_EDITOR); //$NON-NLS-1$
+                       valueChanged(checked, false);
+               }
+
+               /*
+                * @see org.eclipse.jface.action.Action#run()
+                */
+               public void run() {
+                       valueChanged(isChecked(), true);
+               }
+       
+               // Private Methods -----------------------------------------------------
+
+               /**
+                * Updates the sorting of the outline.
+                * 
+                * @param checked Whether lexical sorting is enabled
+                * @param store Whether the new state should be written back as a 
+                *        preference
+                */
+               private void valueChanged(final boolean checked, boolean store) {
+                       setChecked(checked);
+                       BusyIndicator.showWhile(getTreeViewer().getControl().getDisplay(),
+                               new Runnable() {
+                                       public void run() {
+                                               editor.synchronizeOutlinePage();
+                                       }
+                               });
+                       if (store) {
+                               CssUI plugin = CssUI.getDefault();
+                               plugin.getPreferenceStore().setValue(
+                                       CssUIPreferences.OUTLINE_LINK_WITH_EDITOR, checked);
+                       }
+               }
+
+       }
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The associated editor.
+        */
+       private CssEditor editor;
+
+       /**
+        * Toolbar action for showing only the selected element in the editor.
+        */
+       private ShowSelectedElementOnlyAction showSelectedElementOnlyAction = 
+               new ShowSelectedElementOnlyAction(); //$NON-NLS-1$
+               
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param editor The associated text editor
+        */
+       public CssOutlinePage(CssEditor 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.addDoubleClickListener(new CssOutlineDoubleClickListener(this));
+               viewer.setContentProvider(new CssOutlineContentProvider());
+               viewer.setLabelProvider(new DecoratingLabelProvider(
+                               new CssOutlineLabelProvider(),
+                               new ProblemsLabelDecorator(editor)));
+               viewer.setInput(getStyleSheet());
+       }
+
+       /*
+        * @see org.eclipse.ui.part.IPage#dispose()
+        */
+       public void dispose() {
+               if (editor != null) {
+                       editor.outlinePageClosed();
+                       editor = null;
+               }
+               super.dispose();
+       }
+
+       /*
+        * @see org.eclipse.ui.part.IPageBookViewPage#init(org.eclipse.ui.part.IPageSite)
+        */
+       public void init(IPageSite pageSite) {
+               super.init(pageSite);
+               IActionBars bars = pageSite.getActionBars();      
+               bars.setGlobalActionHandler(
+                       ITextEditorActionDefinitionIds.TOGGLE_SHOW_SELECTED_ELEMENT_ONLY,
+                       showSelectedElementOnlyAction);
+               showSelectedElementOnlyAction.setEditor(editor);
+               showSelectedElementOnlyAction.update();
+       }
+
+       /*
+        * @see org.eclipse.ui.part.Page#makeContributions(IMenuManager, IToolBarManager, IStatusLineManager)
+        */
+       public void makeContributions(IMenuManager menuManager,
+               IToolBarManager toolBarManager, IStatusLineManager statusLineManager) {
+               if (toolBarManager != null) {   
+                       toolBarManager.add(new ToggleLexicalSortingAction());
+                       toolBarManager.add(new ToggleLinkingAction());
+               }
+               super.makeContributions(menuManager, toolBarManager, statusLineManager);
+       }
+
+       // 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() {
+               IStyleSheet styleSheet = getStyleSheet();
+               if (styleSheet != null) {
+                       TreeViewer viewer = getTreeViewer();
+                       if (viewer != null) {
+                               Control control = viewer.getControl();
+                               if ((control != null) && !control.isDisposed()) {
+                                       control.setRedraw(false);
+                                       viewer.setInput(styleSheet);
+                                       viewer.expandAll();
+                                       control.setRedraw(true);
+                               }
+                       }
+               }
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       /**
+        * Returns the parsed model of the style sheet that is loaded into the 
+        * associated editor.
+        * 
+        * @return the parsed style sheet
+        */
+       private IStyleSheet getStyleSheet() {
+               IDocumentProvider provider = editor.getDocumentProvider();
+               if (provider instanceof CssDocumentProvider) {
+                       CssDocumentProvider cssProvider = (CssDocumentProvider) provider;
+                       return cssProvider.getStyleSheet(editor.getEditorInput());
+               }
+               return null;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/link_editor.gif b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/link_editor.gif
new file mode 100644 (file)
index 0000000..f865f3a
Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/link_editor.gif differ
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/sort_alpha.gif b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/sort_alpha.gif
new file mode 100644 (file)
index 0000000..6d77244
Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/outline/sort_alpha.gif differ
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/AbstractConfigurationBlock.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/AbstractConfigurationBlock.java
new file mode 100644 (file)
index 0000000..ec72daf
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * 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: AbstractConfigurationBlock.java,v 1.1 2004-09-02 18:11:50 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.preferences;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * 
+ */
+abstract class AbstractConfigurationBlock {
+
+       // Instance Variables ------------------------------------------------------
+
+       private IPreferenceStore fPreferenceStore;
+
+       private Map fCheckBoxes = new HashMap();
+       private SelectionListener fCheckBoxListener = new SelectionListener() {
+               public void widgetDefaultSelected(SelectionEvent e) {
+               }
+               public void widgetSelected(SelectionEvent e) {
+                       Button button = (Button) e.widget;
+                       getPreferenceStore().setValue((String) fCheckBoxes.get(button),
+                               button.getSelection());
+               }
+       };
+
+       private Map fTextFields = new HashMap();
+       private ModifyListener fTextFieldListener = new ModifyListener() {
+               public void modifyText(ModifyEvent e) {
+                       Text text = (Text) e.widget;
+                       getPreferenceStore().setValue((String) fTextFields.get(text),
+                               text.getText());
+               }
+       };
+
+       private List fNumberFields = new ArrayList();
+       private ModifyListener fNumberFieldListener = new ModifyListener() {
+               public void modifyText(ModifyEvent e) {
+                       //numberFieldChanged((Text) e.widget);
+               }
+       };
+
+       private Map fLabels = new HashMap();
+
+       // Constructors ------------------------------------------------------------
+
+       public AbstractConfigurationBlock(IPreferenceStore store) {
+               this.fPreferenceStore = store;    
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       public void initializeFields() {
+               for (Iterator i = fCheckBoxes.keySet().iterator(); i.hasNext(); ) {
+                       Button button = (Button) i.next();
+                       String key = (String) fCheckBoxes.get(button);
+                       button.setSelection(getPreferenceStore().getBoolean(key));
+               }
+               for (Iterator i = fTextFields.keySet().iterator(); i.hasNext(); ) {
+                       Text text = (Text) i.next();
+                       String key = (String) fTextFields.get(text);
+                       text.setText(getPreferenceStore().getString(key));
+               }
+       }
+
+       // Protected Methods -------------------------------------------------------
+
+       protected final Button addBooleanField(Composite parent, String label,
+               String key, int indentation) {
+
+               Button checkBox = new Button(parent, SWT.CHECK);
+               checkBox.setText(label);
+
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+               gd.horizontalIndent = indentation;
+               gd.horizontalSpan = 2;
+               checkBox.setLayoutData(gd);
+               checkBox.addSelectionListener(fCheckBoxListener);
+
+               fCheckBoxes.put(checkBox, key);
+
+               return checkBox;
+       }
+
+       protected final Control addIntegerField(Composite composite, String label,
+               String key, int textLimit, int indentation) {
+
+               Text textControl =
+                       addStringField(composite, label, textLimit, indentation);
+               fTextFields.put(textControl, key);
+               fNumberFields.add(textControl);
+               textControl.addModifyListener(fNumberFieldListener);
+
+               return textControl;
+       }
+
+       protected final Control addTextField(Composite composite, String label,
+               String key, int textLimit, int indentation) {
+
+               Text textControl =
+                       addStringField(composite, label, textLimit, indentation);
+               fTextFields.put(textControl, key);
+               textControl.addModifyListener(fTextFieldListener);
+
+               return textControl;
+       }
+
+       protected final int convertHeightInCharsToPixels(Control control,
+               int chars) {
+               GC gc = new GC(control);
+               gc.setFont(control.getFont());
+               FontMetrics fontMetrics = gc.getFontMetrics();
+               gc.dispose();
+               if (fontMetrics == null) {
+                       return 0;
+               }
+               return Dialog.convertHeightInCharsToPixels(fontMetrics, chars);
+       }
+
+       protected final int convertWidthInCharsToPixels(Control control,
+               int chars) {
+               GC gc = new GC(control);
+               gc.setFont(control.getFont());
+               FontMetrics fontMetrics = gc.getFontMetrics();
+               gc.dispose();
+               if (fontMetrics == null) {
+                       return 0;
+               }
+               return Dialog.convertWidthInCharsToPixels(fontMetrics, chars);
+       }
+
+       protected final Control getLabel(Control field) {
+               return (Control) fLabels.get(field);
+       }
+
+       protected final IPreferenceStore getPreferenceStore() {
+               return fPreferenceStore;
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private Text addStringField(Composite composite, String label,
+               int textLimit, int indentation) {
+
+               Label labelControl = new Label(composite, SWT.NONE);
+               labelControl.setText(label);
+               GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+               gd.horizontalIndent = indentation;
+               labelControl.setLayoutData(gd);
+
+               Text textControl = new Text(composite, SWT.BORDER | SWT.SINGLE);
+               gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+               gd.widthHint = convertWidthInCharsToPixels(textControl, textLimit + 1);
+               textControl.setLayoutData(gd);
+               textControl.setTextLimit(textLimit);
+
+               fLabels.put(textControl, labelControl);
+
+               return textControl;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssEditorAnnotationsConfigurationBlock.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssEditorAnnotationsConfigurationBlock.java
new file mode 100644 (file)
index 0000000..37e7e6a
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * 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: CssEditorAnnotationsConfigurationBlock.java,v 1.1 2004-09-02 18:11:50 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.preferences;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIMessages;
+
+import org.eclipse.jface.preference.ColorSelector;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.ui.texteditor.AnnotationPreference;
+import org.eclipse.ui.texteditor.MarkerAnnotationPreferences;
+
+/**
+ * 
+ */
+final class CssEditorAnnotationsConfigurationBlock
+       extends AbstractConfigurationBlock {
+
+       // Instance Variables ------------------------------------------------------
+
+       private List fColorList;
+       private String[][] fColorListModel;
+       private ColorSelector fColorSelector;
+       private Button fShowInTextCheckBox;
+       private Button fShowInOverviewRulerCheckBox;
+
+       // Constructors ------------------------------------------------------------
+
+       public CssEditorAnnotationsConfigurationBlock(IPreferenceStore store) {
+               super(store);
+               MarkerAnnotationPreferences preferences =
+                       new MarkerAnnotationPreferences();
+               fColorListModel = createAnnotationTypeListModel(preferences);
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       public Control createControl(Composite parent) {
+
+               Composite composite = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 2;
+               composite.setLayout(layout);
+
+               Label label = new Label(composite, SWT.LEFT);
+               label.setText(getString("presentationOptions")); //$NON-NLS-1$
+               GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+               gridData.horizontalSpan = 2;
+               label.setLayoutData(gridData);
+
+               Composite editorComposite = new Composite(composite, SWT.NONE);
+               layout = new GridLayout();
+               layout.numColumns = 2;
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               editorComposite.setLayout(layout);
+               gridData = new GridData(
+                       GridData.HORIZONTAL_ALIGN_FILL | GridData.FILL_VERTICAL);
+               gridData.horizontalSpan = 2;
+               editorComposite.setLayoutData(gridData);          
+
+               fColorList = new List(editorComposite,
+                       SWT.SINGLE | SWT.V_SCROLL | SWT.BORDER);
+               gridData = new GridData(
+                       GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
+               gridData.heightHint = convertHeightInCharsToPixels(composite, 8);
+               fColorList.setLayoutData(gridData);
+               fColorList.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) { }
+                       public void widgetSelected(SelectionEvent e) {
+                               handleAnnotationColorListSelection();
+                       }
+               });
+
+               Composite optionsComposite = new Composite(editorComposite, SWT.NONE);
+               layout = new GridLayout();
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               layout.numColumns = 2;
+               optionsComposite.setLayout(layout);
+               optionsComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+               
+               fShowInTextCheckBox = new Button(optionsComposite, SWT.CHECK);
+               fShowInTextCheckBox.setText(getString(
+                       "showInText")); //$NON-NLS-1$
+               gridData = new GridData(GridData.FILL_HORIZONTAL);
+               gridData.horizontalAlignment = GridData.BEGINNING;
+               gridData.horizontalSpan = 2;
+               fShowInTextCheckBox.setLayoutData(gridData);
+               fShowInTextCheckBox.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) { }
+                       public void widgetSelected(SelectionEvent e) {
+                               int i = fColorList.getSelectionIndex();
+                               String key = fColorListModel[i][2];
+                               getPreferenceStore().setValue(key,
+                                       fShowInTextCheckBox.getSelection());
+                       }
+               });
+               
+               fShowInOverviewRulerCheckBox = new Button(optionsComposite, SWT.CHECK);
+               fShowInOverviewRulerCheckBox.setText(getString(
+                       "showInOverviewRuler")); //$NON-NLS-1$
+               gridData = new GridData(GridData.FILL_HORIZONTAL);
+               gridData.horizontalAlignment = GridData.BEGINNING;
+               gridData.horizontalSpan = 2;
+               fShowInOverviewRulerCheckBox.setLayoutData(gridData);
+               fShowInOverviewRulerCheckBox.addSelectionListener(
+                       new SelectionListener() {
+                               public void widgetDefaultSelected(SelectionEvent e) { }
+                               public void widgetSelected(SelectionEvent e) {
+                                       int i = fColorList.getSelectionIndex();
+                                       String key = fColorListModel[i][3];
+                                       getPreferenceStore().setValue(key,
+                                               fShowInOverviewRulerCheckBox.getSelection());
+                               }
+                       });
+               
+               label = new Label(optionsComposite, SWT.LEFT);
+               label.setText(getString("color")); //$NON-NLS-1$
+               gridData = new GridData();
+               gridData.horizontalAlignment = GridData.BEGINNING;
+               label.setLayoutData(gridData);
+
+               fColorSelector = new ColorSelector(optionsComposite);
+               Button foregroundColorButton = fColorSelector.getButton();
+               gridData = new GridData(GridData.FILL_HORIZONTAL);
+               gridData.horizontalAlignment = GridData.BEGINNING;
+               foregroundColorButton.setLayoutData(gridData);
+               foregroundColorButton.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) { }
+                       public void widgetSelected(SelectionEvent e) {
+                               int i = fColorList.getSelectionIndex();
+                               String key = fColorListModel[i][1];
+                               PreferenceConverter.setValue(getPreferenceStore(), key,
+                                       fColorSelector.getColorValue());
+                       }
+               });
+
+               initialize();
+
+               return composite;
+       }
+
+       // Event Handlers ----------------------------------------------------------
+
+       void handleAnnotationColorListSelection() {
+               int i = fColorList.getSelectionIndex();
+               String key = fColorListModel[i][1];
+               RGB rgb = PreferenceConverter.getColor(getPreferenceStore(), key);
+               fColorSelector.setColorValue(rgb);
+               key = fColorListModel[i][2];
+               fShowInTextCheckBox.setSelection(getPreferenceStore().getBoolean(key));
+               key = fColorListModel[i][3];
+               fShowInOverviewRulerCheckBox.setSelection(
+                       getPreferenceStore().getBoolean(key));                           
+       }
+       
+       // Private Methods ---------------------------------------------------------
+
+       private String[][] createAnnotationTypeListModel(
+               MarkerAnnotationPreferences preferences) {
+               
+               ArrayList listModelItems = new ArrayList();
+               Iterator i = preferences.getAnnotationPreferences().iterator();
+               while (i.hasNext()) {
+                       AnnotationPreference info = (AnnotationPreference) i.next();
+                       listModelItems.add(new String[] {
+                               info.getPreferenceLabel(),
+                               info.getColorPreferenceKey(),
+                               info.getTextPreferenceKey(),
+                               info.getOverviewRulerPreferenceKey()
+                       });
+               }
+
+               String[][] listModel = new String[listModelItems.size()][];
+               listModelItems.toArray(listModel);
+               return listModel;
+       }
+
+       private static String getString(String key) {
+               return CssUIMessages.getString(
+                       "CssEditorPreferencePage.annotations." + key); //$NON-NLS-1$
+       }
+
+       private void initialize() {
+               for (int i = 0; i < fColorListModel.length; i++) {
+                       fColorList.add(fColorListModel[i][0]);
+               }
+               fColorList.getDisplay().asyncExec(new Runnable() {
+                       public void run() {
+                               if ((fColorList != null)
+                                && !fColorList.isDisposed()) {
+                                       fColorList.select(0);
+                                       handleAnnotationColorListSelection();
+                               }
+                       }
+               });
+               initializeFields();
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssEditorAppearanceConfigurationBlock.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssEditorAppearanceConfigurationBlock.java
new file mode 100644 (file)
index 0000000..c1fcbf0
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * 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: CssEditorAppearanceConfigurationBlock.java,v 1.1 2004-09-02 18:11:51 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.preferences;
+
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIMessages;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIPreferences;
+
+import org.eclipse.jface.preference.ColorSelector;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+
+/**
+ * 
+ */
+final class CssEditorAppearanceConfigurationBlock
+       extends AbstractConfigurationBlock {
+
+       // Instance Variables ------------------------------------------------------
+
+       private List fColorList;
+       private final String[][] fColorListModel = new String[][] {
+               { getString("lineNumberForegroundColor"), //$NON-NLS-1$
+                 CssUIPreferences.EDITOR_LINE_NUMBER_RULER_COLOR },
+               { getString("matchingBracketsHighlightColor"), //$NON-NLS-1$
+                 CssUIPreferences.EDITOR_MATCHING_BRACKETS_COLOR },
+               { getString("currentLineHighlighColor"), //$NON-NLS-1$
+                 CssUIPreferences.EDITOR_CURRENT_LINE_COLOR },
+               { getString("printMarginColor"), //$NON-NLS-1$
+                 CssUIPreferences.EDITOR_PRINT_MARGIN_COLOR },
+       };
+       private ColorSelector fColorSelector;
+
+       // Constructors ------------------------------------------------------------
+
+       public CssEditorAppearanceConfigurationBlock(IPreferenceStore store) {
+               super(store);
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       public Control createControl(Composite parent) {
+
+               Composite control = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 2;
+               control.setLayout(layout);
+
+               addTextField(control, getString("displayedTabWidth"), //$NON-NLS-1$
+                       CssUIPreferences.EDITOR_TAB_WIDTH, 3, 0);
+               addTextField(control, getString("printMarginColumn"), //$NON-NLS-1$
+                       CssUIPreferences.EDITOR_PRINT_MARGIN_COLUMN, 3,
+                       0);
+               addBooleanField(control, getString("showOverviewRuler"), //$NON-NLS-1$
+                       CssUIPreferences.EDITOR_OVERVIEW_RULER, 0);
+               addBooleanField(control, getString("showLineNumbers"), //$NON-NLS-1$
+                       CssUIPreferences.EDITOR_LINE_NUMBER_RULER, 0);
+               addBooleanField(control,
+                       getString("highlightMatchingBrackets"), //$NON-NLS-1$
+                       CssUIPreferences.EDITOR_MATCHING_BRACKETS, 0);
+               addBooleanField(control,
+                       getString("highlightCurrentLine"), //$NON-NLS-1$
+                       CssUIPreferences.EDITOR_CURRENT_LINE, 0);
+               addBooleanField(control, getString("showPrintMargin"), //$NON-NLS-1$
+                       CssUIPreferences.EDITOR_PRINT_MARGIN, 0);
+
+               Label label = new Label(control, SWT.LEFT);
+               GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+               gridData.horizontalSpan = 2;
+               gridData.heightHint = convertHeightInCharsToPixels(control, 1) / 2;
+               label.setLayoutData(gridData);
+
+               label = new Label(control, SWT.LEFT);
+               label.setText(getString("colorOptions")); //$NON-NLS-1$
+               gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+               gridData.horizontalSpan = 2;
+               label.setLayoutData(gridData);
+
+               Composite editorComposite = new Composite(control, SWT.NONE);
+               layout = new GridLayout();
+               layout.numColumns = 2;
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               editorComposite.setLayout(layout);
+               gridData = new GridData(
+                       GridData.HORIZONTAL_ALIGN_FILL | GridData.FILL_VERTICAL);
+               gridData.horizontalSpan = 2;
+               editorComposite.setLayoutData(gridData);
+
+               fColorList = new List(editorComposite,
+                       SWT.SINGLE | SWT.V_SCROLL | SWT.BORDER);
+               gridData = new GridData(
+                       GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
+               gridData.heightHint = convertHeightInCharsToPixels(control, 8);
+               fColorList.setLayoutData(gridData);
+               fColorList.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                               // do nothing
+                       }
+                       public void widgetSelected(SelectionEvent e) {
+                               handleColorListSelection();
+                       }
+               });
+
+               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(getString("color")); //$NON-NLS-1$
+               gridData = new GridData();
+               gridData.horizontalAlignment = GridData.BEGINNING;
+               label.setLayoutData(gridData);
+
+               fColorSelector = new ColorSelector(stylesComposite);
+               Button foregroundColorButton = fColorSelector.getButton();
+               gridData = new GridData(GridData.FILL_HORIZONTAL);
+               gridData.horizontalAlignment = GridData.BEGINNING;
+               foregroundColorButton.setLayoutData(gridData);
+               foregroundColorButton.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                               // do nothing
+                       }
+                       public void widgetSelected(SelectionEvent e) {
+                               int i = fColorList.getSelectionIndex();
+                               String key = fColorListModel[i][1];
+                               PreferenceConverter.setValue(getPreferenceStore(), key,
+                                       fColorSelector.getColorValue());
+                       }
+               });
+
+               initialize();
+
+               return control;
+       }
+
+       // Event Handlers ----------------------------------------------------------
+
+       void handleColorListSelection() {
+               int i = fColorList.getSelectionIndex();
+               String key = fColorListModel[i][1];
+               RGB rgb = PreferenceConverter.getColor(getPreferenceStore(), key);
+               fColorSelector.setColorValue(rgb);
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private static String getString(String key) {
+               return CssUIMessages.getString(
+                       "CssEditorPreferencePage.appearance." + key); //$NON-NLS-1$
+       }
+
+       private void initialize() {
+               for (int i = 0; i < fColorListModel.length; i++) {
+                       fColorList.add(fColorListModel[i][0]);
+               }
+               fColorList.getDisplay().asyncExec(new Runnable() {
+                       public void run() {
+                               if ((fColorList != null)
+                                && !fColorList.isDisposed()) {
+                                       fColorList.select(0);
+                                       handleColorListSelection();
+                               }
+                       }
+               });
+               initializeFields();
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssEditorContentAssistConfigurationBlock.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssEditorContentAssistConfigurationBlock.java
new file mode 100644 (file)
index 0000000..34f2381
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * 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: CssEditorContentAssistConfigurationBlock.java,v 1.1 2004-09-02 18:11:50 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.preferences;
+
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIMessages;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIPreferences;
+
+import org.eclipse.jface.preference.ColorSelector;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+
+/**
+ * Configuration block for setting the preferences related to content assist.
+ */
+final class CssEditorContentAssistConfigurationBlock
+       extends AbstractConfigurationBlock {
+
+       // Instance Variables ------------------------------------------------------
+
+       private List fColorList;
+       private final String[][] fColorListModel = new String[][] {
+               { getString("backgroundForCompletionProposals"), //$NON-NLS-1$
+                 CssUIPreferences.CONTENTASSIST_PROPOSALS_BACKGROUND },
+               { getString("foregroundForCompletionProposals"), //$NON-NLS-1$
+                 CssUIPreferences.CONTENTASSIST_PROPOSALS_FOREGROUND },
+       };
+       private ColorSelector fColorSelector;
+       private Control fAutoActivationDelayField;
+       private Control fAutoActivationTriggersField;
+
+       // Constructors ------------------------------------------------------------
+
+       public CssEditorContentAssistConfigurationBlock(IPreferenceStore store) {
+               super(store);
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       public Control createControl(Composite parent) {
+
+               Composite composite = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 2;
+               composite.setLayout(layout);
+
+               //addCompletionRadioButtons(contentAssistComposite);
+
+               addBooleanField(composite,
+                       getString("insertSingleProposalsAutomatically"), //$NON-NLS-1$
+                       CssUIPreferences.CONTENTASSIST_AUTOINSERT, 0);
+               addBooleanField(composite,
+                       getString("presentProposalsInAlphabeticalOrder"), //$NON-NLS-1$
+                       CssUIPreferences.CONTENTASSIST_ORDER_PROPOSALS, 0);
+               addBooleanField(composite,
+                       getString("enableAutoActivation"), //$NON-NLS-1$
+                       CssUIPreferences.CONTENTASSIST_AUTOACTIVATION,
+                       0).addSelectionListener(new SelectionAdapter() {
+                               public void widgetSelected(SelectionEvent e) {
+                                       updateAutoactivationControls();
+                               }
+                       });
+               fAutoActivationDelayField = addIntegerField(composite,
+                       getString("autoActivationDelay"), //$NON-NLS-1$
+                       CssUIPreferences.CONTENTASSIST_AUTOACTIVATION_DELAY, 4, 0);
+               fAutoActivationTriggersField = addTextField(composite,
+                       getString("autoActivationTriggers"), //$NON-NLS-1$
+                       CssUIPreferences.CONTENTASSIST_AUTOACTIVATION_TRIGGERS, 4, 0);
+
+               Label label = new Label(composite, SWT.LEFT);
+               label.setText(getString("colorOptions")); //$NON-NLS-1$
+               GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+               gridData.horizontalSpan = 2;
+               label.setLayoutData(gridData);
+
+               Composite editorComposite = new Composite(composite, SWT.NONE);
+               layout = new GridLayout();
+               layout.numColumns = 2;
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               editorComposite.setLayout(layout);
+               gridData = new GridData(
+                       GridData.HORIZONTAL_ALIGN_FILL | GridData.FILL_VERTICAL);
+               gridData.horizontalSpan = 2;
+               editorComposite.setLayoutData(gridData);
+
+               fColorList = new List(editorComposite,
+                       SWT.SINGLE | SWT.V_SCROLL | SWT.BORDER);
+               gridData = new GridData(
+                       GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
+               gridData.heightHint = convertHeightInCharsToPixels(composite, 8);
+               fColorList.setLayoutData(gridData);
+               fColorList.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                               // do nothing
+                       }
+                       public void widgetSelected(SelectionEvent e) {
+                               handleColorListSelection();
+                       }
+               });
+
+               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(getString("color")); //$NON-NLS-1$
+               gridData = new GridData();
+               gridData.horizontalAlignment = GridData.BEGINNING;
+               label.setLayoutData(gridData);
+
+               fColorSelector = new ColorSelector(stylesComposite);
+               Button colorButton = fColorSelector.getButton();
+               gridData = new GridData(GridData.FILL_HORIZONTAL);
+               gridData.horizontalAlignment = GridData.BEGINNING;
+               colorButton.setLayoutData(gridData);
+               colorButton.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                               // do nothing
+                       }
+                       public void widgetSelected(SelectionEvent e) {
+                               int i = fColorList.getSelectionIndex();
+                               String key = fColorListModel[i][1];
+                               PreferenceConverter.setValue(getPreferenceStore(), key,
+                                       fColorSelector.getColorValue());
+                       }
+               });
+
+               initialize();
+
+               return composite;
+       }
+
+       // Event Handlers ----------------------------------------------------------
+
+       void handleColorListSelection() {
+               int i = fColorList.getSelectionIndex();
+               String key = fColorListModel[i][1];
+               RGB rgb = PreferenceConverter.getColor(getPreferenceStore(), key);
+               fColorSelector.setColorValue(rgb);
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private static String getString(String key) {
+               return CssUIMessages.getString(
+                       "CssEditorPreferencePage.contentAssist." + key); //$NON-NLS-1$
+       }
+
+       private void initialize() {
+               for (int i = 0; i < fColorListModel.length; i++) {
+                       fColorList.add(fColorListModel[i][0]);
+               }
+               fColorList.getDisplay().asyncExec(new Runnable() {
+                       public void run() {
+                               if ((fColorList != null)
+                                && !fColorList.isDisposed()) {
+                                       fColorList.select(0);
+                                       handleColorListSelection();
+                               }
+                       }
+               });
+               initializeFields();
+       }
+
+       private void updateAutoactivationControls() {
+               boolean enabled = getPreferenceStore().getBoolean(
+                       CssUIPreferences.CONTENTASSIST_AUTOACTIVATION);
+               fAutoActivationDelayField.setEnabled(enabled);
+               getLabel(fAutoActivationDelayField).setEnabled(enabled);
+               fAutoActivationTriggersField.setEnabled(enabled);
+               getLabel(fAutoActivationTriggersField).setEnabled(enabled);
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssEditorPreferencePage.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssEditorPreferencePage.java
new file mode 100644 (file)
index 0000000..8b5ae6d
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * 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: CssEditorPreferencePage.java,v 1.1 2004-09-02 18:11:50 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.preferences;
+
+import java.util.Iterator;
+
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIMessages;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIPreferences;
+
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.texteditor.AnnotationPreference;
+import org.eclipse.ui.texteditor.MarkerAnnotationPreferences;
+
+/**
+ * Implements the CSS editor preference page.
+ */
+public class CssEditorPreferencePage extends PreferencePage
+       implements IWorkbenchPreferencePage {
+
+       // Instance Variables ------------------------------------------------------
+
+       private OverlayPreferenceStore overlayStore;
+
+       private CssEditorAppearanceConfigurationBlock appearanceBlock;
+       private CssEditorSyntaxConfigurationBlock syntaxBlock;
+       private CssEditorContentAssistConfigurationBlock contentAssistBlock;
+       private CssEditorAnnotationsConfigurationBlock annotationsBlock;
+       private CssEditorTypingConfigurationBlock typingBlock;
+
+       // PreferencePage Implementation -------------------------------------------
+
+       /**
+        * @see PreferencePage#createContents(Composite)
+        */
+       protected Control createContents(Composite parent) {
+
+               TabFolder folder = new TabFolder(parent, SWT.NONE);
+               TabItem item;
+
+               item = new TabItem(folder, SWT.NONE);
+               item.setText(getString("appearance")); //$NON-NLS-1$
+               item.setControl(createAppearancePage(folder));
+
+               item = new TabItem(folder, SWT.NONE);
+               item.setText(getString("syntax")); //$NON-NLS-1$
+               item.setControl(createSyntaxPage(folder));
+
+               item = new TabItem(folder, SWT.NONE);
+               item.setText(getString("contentAssist")); //$NON-NLS-1$
+               item.setControl(createCodeAssistPage(folder));
+
+               item = new TabItem(folder, SWT.NONE);
+               item.setText(getString("annotations")); //$NON-NLS-1$
+               item.setControl(createAnnotationsPage(folder));
+
+               item = new TabItem(folder, SWT.NONE);
+               item.setText(getString("typing")); //$NON-NLS-1$
+               item.setControl(createTypingPage(folder));
+
+               return folder;
+       }
+
+       /**
+        * @see PreferencePage#dispose()
+        */
+       public void dispose() {
+               if (overlayStore != null) {
+                       overlayStore.stopListening();
+                       overlayStore = null;
+               }
+               super.dispose();
+       }
+
+       /**
+        * @see PreferencePage#performOk()
+        */
+       public boolean performOk() {
+               overlayStore.propagate();
+               CssUI.getDefault().savePluginPreferences();
+               return true;
+       }
+
+       /**
+        * @see PreferencePage#performDefaults()
+        */
+       protected void performDefaults() {
+               overlayStore.loadDefaults();
+               super.performDefaults();
+       }
+       
+       // IWorkbenchPreferencePage Implementation ---------------------------------
+
+       /**
+        * @see IWorkbenchPreferencePage#init(IWorkbench)
+        */
+       public void init(IWorkbench workbench) {
+               setDescription(getString("description")); //$NON-NLS-1$
+               setPreferenceStore(CssUI.getDefault().getPreferenceStore());
+
+               MarkerAnnotationPreferences preferences =
+                       new MarkerAnnotationPreferences();
+               overlayStore = createOverlayStore(preferences);
+               overlayStore.load();
+               overlayStore.startListening();
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private OverlayPreferenceStore createOverlayStore(
+               MarkerAnnotationPreferences preferences) {
+
+               OverlayPreferenceStore store = 
+                       new OverlayPreferenceStore(getPreferenceStore());
+
+               Iterator e = preferences.getAnnotationPreferences().iterator();
+               while (e.hasNext()) {
+                       AnnotationPreference info = (AnnotationPreference) e.next();
+                       store.addStringKey(info.getColorPreferenceKey());
+                       store.addBooleanKey(info.getTextPreferenceKey());
+                       store.addBooleanKey(info.getOverviewRulerPreferenceKey());
+               }
+
+               // Appearance
+               store.addIntKey(CssUIPreferences.EDITOR_TAB_WIDTH);
+               store.addBooleanKey(CssUIPreferences.EDITOR_CURRENT_LINE);
+               store.addStringKey(CssUIPreferences.EDITOR_CURRENT_LINE_COLOR);
+               store.addBooleanKey(CssUIPreferences.EDITOR_MATCHING_BRACKETS);
+               store.addStringKey(CssUIPreferences.EDITOR_MATCHING_BRACKETS_COLOR);
+               store.addBooleanKey(CssUIPreferences.EDITOR_PRINT_MARGIN);
+               store.addStringKey(CssUIPreferences.EDITOR_PRINT_MARGIN_COLOR);
+               store.addIntKey(CssUIPreferences.EDITOR_PRINT_MARGIN_COLUMN);
+               store.addBooleanKey(CssUIPreferences.EDITOR_OVERVIEW_RULER);
+               store.addStringKey(CssUIPreferences.EDITOR_LINE_NUMBER_RULER_COLOR);
+               store.addBooleanKey(CssUIPreferences.EDITOR_LINE_NUMBER_RULER);
+
+               // Syntax coloring
+               store.addStringKey(CssUIPreferences.EDITOR_FOREGROUND_COLOR);
+               store.addBooleanKey(
+                       CssUIPreferences.EDITOR_FOREGROUND_DEFAULT_COLOR);
+               store.addStringKey(CssUIPreferences.EDITOR_BACKGROUND_COLOR);
+               store.addBooleanKey(
+                       CssUIPreferences.EDITOR_BACKGROUND_DEFAULT_COLOR);
+               store.addStringKey(CssUIPreferences.EDITOR_COMMENT_COLOR);
+               store.addBooleanKey(CssUIPreferences.EDITOR_COMMENT_BOLD);
+               store.addStringKey(CssUIPreferences.EDITOR_STRING_COLOR);
+               store.addBooleanKey(CssUIPreferences.EDITOR_STRING_BOLD);
+               store.addStringKey(CssUIPreferences.EDITOR_PROPERTY_COLOR);
+               store.addBooleanKey(CssUIPreferences.EDITOR_PROPERTY_BOLD);
+               store.addStringKey(CssUIPreferences.EDITOR_AT_KEYWORD_COLOR);
+               store.addBooleanKey(CssUIPreferences.EDITOR_AT_KEYWORD_BOLD);
+               store.addStringKey(CssUIPreferences.EDITOR_PSEUDO_CLASS_COLOR);
+               store.addBooleanKey(CssUIPreferences.EDITOR_PSEUDO_CLASS_BOLD);
+               store.addStringKey(CssUIPreferences.EDITOR_DEFAULT_COLOR);
+               store.addBooleanKey(CssUIPreferences.EDITOR_DEFAULT_BOLD);
+
+               // Content assist
+               store.addBooleanKey(CssUIPreferences.CONTENTASSIST_AUTOINSERT);
+               store.addBooleanKey(CssUIPreferences.CONTENTASSIST_ORDER_PROPOSALS);
+               store.addBooleanKey(CssUIPreferences.CONTENTASSIST_AUTOACTIVATION);
+               store.addIntKey(
+                       CssUIPreferences.CONTENTASSIST_AUTOACTIVATION_DELAY);
+               store.addStringKey(
+                       CssUIPreferences.CONTENTASSIST_AUTOACTIVATION_TRIGGERS);
+               store.addStringKey(
+                       CssUIPreferences.CONTENTASSIST_PROPOSALS_BACKGROUND);
+               store.addStringKey(
+                       CssUIPreferences.CONTENTASSIST_PROPOSALS_FOREGROUND);
+
+               // Typing
+               store.addBooleanKey(CssUIPreferences.EDITOR_SPACES_FOR_TABS);
+               store.addBooleanKey(CssUIPreferences.EDITOR_CLOSE_STRINGS);
+               store.addBooleanKey(
+                       CssUIPreferences.EDITOR_CLOSE_BRACKETS_AND_PARENS);
+               store.addBooleanKey(CssUIPreferences.EDITOR_CLOSE_BRACES);
+
+               return store;
+       }
+       
+       private Control createAppearancePage(Composite parent) {
+               appearanceBlock =
+                       new CssEditorAppearanceConfigurationBlock(overlayStore); 
+               return appearanceBlock.createControl(parent);
+       }
+
+       private Control createSyntaxPage(Composite parent) {
+               syntaxBlock = new CssEditorSyntaxConfigurationBlock(overlayStore); 
+               return syntaxBlock.createControl(parent);
+       }
+
+       private Control createCodeAssistPage(Composite parent) {
+               contentAssistBlock =
+                       new CssEditorContentAssistConfigurationBlock(overlayStore);
+               return contentAssistBlock.createControl(parent);
+       }
+
+       private Control createAnnotationsPage(Composite parent) {
+               annotationsBlock =
+                       new CssEditorAnnotationsConfigurationBlock(overlayStore); 
+               return annotationsBlock.createControl(parent);
+       }
+
+       private Control createTypingPage(Composite parent) {
+               typingBlock = new CssEditorTypingConfigurationBlock(overlayStore); 
+               return typingBlock.createControl(parent);
+       }
+
+       private static String getString(String key) {
+               return CssUIMessages.getString(
+                       "CssEditorPreferencePage." + key); //$NON-NLS-1$
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssEditorSyntaxConfigurationBlock.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssEditorSyntaxConfigurationBlock.java
new file mode 100644 (file)
index 0000000..fb1e101
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * 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: CssEditorSyntaxConfigurationBlock.java,v 1.1 2004-09-02 18:11:50 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.preferences;
+
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIMessages;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIPreferences;
+
+import org.eclipse.jface.preference.ColorSelector;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+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.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+
+/**
+ * 
+ */
+final class CssEditorSyntaxConfigurationBlock
+       extends AbstractConfigurationBlock {
+
+       // Instance Variables ------------------------------------------------------
+
+       private Button fBackgroundDefaultRadioButton;
+       private Button fBackgroundCustomRadioButton;
+       private ColorSelector fBackgroundColorSelector;
+       private List fColorList;
+       private final String[][] fColorListModel = new String[][] {
+               { getString("commentColor"), //$NON-NLS-1$
+                 CssUIPreferences.EDITOR_COMMENT_COLOR,
+                 CssUIPreferences.EDITOR_COMMENT_BOLD },
+               { getString("stringColor"), //$NON-NLS-1$
+                 CssUIPreferences.EDITOR_STRING_COLOR,
+                 CssUIPreferences.EDITOR_STRING_BOLD },
+               { getString("propertyNameColor"), //$NON-NLS-1$
+                 CssUIPreferences.EDITOR_PROPERTY_COLOR,
+                 CssUIPreferences.EDITOR_PROPERTY_BOLD },
+               { getString("atKeywordColor"), //$NON-NLS-1$
+                 CssUIPreferences.EDITOR_AT_KEYWORD_COLOR,
+                 CssUIPreferences.EDITOR_AT_KEYWORD_BOLD },
+               { getString("pseudoClassColor"), //$NON-NLS-1$
+                 CssUIPreferences.EDITOR_PSEUDO_CLASS_COLOR,
+                 CssUIPreferences.EDITOR_PSEUDO_CLASS_BOLD },
+               { getString("defaultColor"), //$NON-NLS-1$
+                 CssUIPreferences.EDITOR_DEFAULT_COLOR,
+                 CssUIPreferences.EDITOR_DEFAULT_BOLD },
+       };
+       private ColorSelector fColorSelector;
+       private Button fBoldCheckbox;
+
+       // Constructors ------------------------------------------------------------
+
+       public CssEditorSyntaxConfigurationBlock(IPreferenceStore store) {
+               super(store);
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       public Control createControl(Composite parent) {
+
+               Composite composite = new Composite(parent, SWT.NONE);
+               composite.setLayout(new GridLayout());
+
+               Group backgroundComposite = new Group(composite, SWT.SHADOW_ETCHED_IN);
+               backgroundComposite.setLayout(new RowLayout());
+               backgroundComposite.setText(getString("backgroundColor")); //$NON-NLS-1$
+               SelectionListener backgroundSelectionListener =
+                       new SelectionListener() {
+                               public void widgetSelected(SelectionEvent e) {                          
+                                       boolean custom =
+                                               fBackgroundCustomRadioButton.getSelection();
+                                       fBackgroundColorSelector.setEnabled(custom);
+                                       getPreferenceStore().setValue(
+                                               CssUIPreferences.EDITOR_BACKGROUND_DEFAULT_COLOR,
+                                               !custom);
+                               }
+                               public void widgetDefaultSelected(SelectionEvent e) { }
+                       };
+               fBackgroundDefaultRadioButton = new Button(backgroundComposite,
+                       SWT.RADIO | SWT.LEFT);
+               fBackgroundDefaultRadioButton.setText(getString(
+                       "backgroundColorSystemDefault")); //$NON-NLS-1$
+               fBackgroundDefaultRadioButton.addSelectionListener(
+                       backgroundSelectionListener);
+               fBackgroundCustomRadioButton = new Button(backgroundComposite,
+                       SWT.RADIO | SWT.LEFT);
+               fBackgroundCustomRadioButton.setText(getString(
+                       "backgroundColorCustom")); //$NON-NLS-1$
+               fBackgroundCustomRadioButton.addSelectionListener(
+                       backgroundSelectionListener);
+
+               fBackgroundColorSelector = new ColorSelector(backgroundComposite);
+               Button backgroundColorButton = fBackgroundColorSelector.getButton();
+               backgroundColorButton.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) { }
+                       public void widgetSelected(SelectionEvent e) {
+                               PreferenceConverter.setValue(getPreferenceStore(),
+                                       CssUIPreferences.EDITOR_BACKGROUND_COLOR,
+                                       fBackgroundColorSelector.getColorValue());
+                       }
+               });
+
+               Label label = new Label(composite, SWT.LEFT);
+               label.setText(getString("foregroundColor")); //$NON-NLS-1$
+               label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+               Composite editorComposite = new Composite(composite, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 2;
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               editorComposite.setLayout(layout);
+               GridData gridData = new GridData(GridData.FILL_BOTH);
+               editorComposite.setLayoutData(gridData);          
+
+               fColorList = new List(editorComposite,
+                       SWT.SINGLE | SWT.V_SCROLL | SWT.BORDER);
+               gridData = new GridData(GridData.FILL_BOTH);
+               gridData.heightHint = convertHeightInCharsToPixels(composite, 5);
+               fColorList.setLayoutData(gridData);
+               fColorList.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+                       public void widgetSelected(SelectionEvent e) {
+                               handleSyntaxColorListSelection();
+                       }
+               });
+
+               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(getString("color")); //$NON-NLS-1$
+               gridData = new GridData();
+               gridData.horizontalAlignment = GridData.BEGINNING;
+               label.setLayoutData(gridData);
+
+               fColorSelector = new ColorSelector(stylesComposite);
+               Button foregroundColorButton = fColorSelector.getButton();
+               gridData = new GridData(GridData.FILL_HORIZONTAL);
+               gridData.horizontalAlignment = GridData.BEGINNING;
+               foregroundColorButton.setLayoutData(gridData);
+               foregroundColorButton.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) { }
+                       public void widgetSelected(SelectionEvent e) {
+                               int i = fColorList.getSelectionIndex();
+                               String key = fColorListModel[i][1];
+                               PreferenceConverter.setValue(getPreferenceStore(), key,
+                                       fColorSelector.getColorValue());
+                       }
+               });
+               
+               fBoldCheckbox = new Button(stylesComposite, SWT.CHECK);
+               fBoldCheckbox.setText(getString("bold")); //$NON-NLS-1$
+               gridData = new GridData(GridData.FILL_HORIZONTAL);
+               gridData.horizontalAlignment = GridData.BEGINNING;
+               gridData.horizontalSpan = 2;
+               fBoldCheckbox.setLayoutData(gridData);
+               fBoldCheckbox.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) { }
+                       public void widgetSelected(SelectionEvent e) {
+                               int i = fColorList.getSelectionIndex();
+                               String key = fColorListModel[i][2];
+                               getPreferenceStore().setValue(key,
+                                       fBoldCheckbox.getSelection());
+                       }
+               });
+
+               Control previewer =
+                       new SyntaxPreviewer(composite, getPreferenceStore()).getControl();
+               gridData = new GridData(GridData.FILL_BOTH);
+               gridData.widthHint = convertWidthInCharsToPixels(composite, 20);
+               gridData.heightHint = convertHeightInCharsToPixels(composite, 5);
+               previewer.setLayoutData(gridData);
+
+               initialize();
+
+               return composite;
+       }
+
+       /**
+        * @see AbstractConfigurationBlock#initializeFields()
+        */
+       public void initializeFields() {
+               super.initializeFields();
+               RGB rgb = PreferenceConverter.getColor(getPreferenceStore(),
+                       CssUIPreferences.EDITOR_BACKGROUND_COLOR);
+               fBackgroundColorSelector.setColorValue(rgb);
+               boolean defaultBackgroud = getPreferenceStore().getBoolean(
+                       CssUIPreferences.EDITOR_BACKGROUND_DEFAULT_COLOR);
+               fBackgroundDefaultRadioButton.setSelection(defaultBackgroud);
+               fBackgroundCustomRadioButton.setSelection(!defaultBackgroud);
+               fBackgroundColorSelector.setEnabled(!defaultBackgroud);
+       }
+
+       // Event Handlers ----------------------------------------------------------
+
+       void handleSyntaxColorListSelection() {
+               int i = fColorList.getSelectionIndex();
+               String key = fColorListModel[i][1];
+               RGB rgb = PreferenceConverter.getColor(getPreferenceStore(), key);
+               fColorSelector.setColorValue(rgb);
+               key = fColorListModel[i][2];
+               fBoldCheckbox.setSelection(getPreferenceStore().getBoolean(key));
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private static String getString(String key) {
+               return CssUIMessages.getString(
+                       "CssEditorPreferencePage.syntax." + key); //$NON-NLS-1$
+       }
+
+       private void initialize() {
+               for (int i = 0; i < fColorListModel.length; i++) {
+                       fColorList.add(fColorListModel[i][0]);
+               }
+               fColorList.getDisplay().asyncExec(new Runnable() {
+                       public void run() {
+                               if ((fColorList != null)
+                                && !fColorList.isDisposed()) {
+                                       fColorList.select(0);
+                                       handleSyntaxColorListSelection();
+                               }
+                       }
+               });
+               initializeFields();
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssEditorTypingConfigurationBlock.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssEditorTypingConfigurationBlock.java
new file mode 100644 (file)
index 0000000..e4a9cd4
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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: CssEditorTypingConfigurationBlock.java,v 1.1 2004-09-02 18:11:50 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.preferences;
+
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIMessages;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIPreferences;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * 
+ */
+final class CssEditorTypingConfigurationBlock
+       extends AbstractConfigurationBlock {
+
+       // Constructors ------------------------------------------------------------
+
+       public CssEditorTypingConfigurationBlock(IPreferenceStore store) {
+               super(store);
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       public Control createControl(Composite parent) {
+
+               Composite composite = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 2;
+               composite.setLayout(layout);
+
+               addBooleanField(composite,
+                       getString("insertSpaceForTabs"), //$NON-NLS-1$
+                       CssUIPreferences.EDITOR_SPACES_FOR_TABS, 1);
+               initialize();
+
+               return composite;
+       }
+
+       private static String getString(String key) {
+               return CssUIMessages.getString(
+                       "CssEditorPreferencePage.typing." + key); //$NON-NLS-1$
+       }
+
+       private void initialize() {
+               initializeFields();
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssPreferencePage.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/CssPreferencePage.java
new file mode 100644 (file)
index 0000000..41d92dc
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * 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: CssPreferencePage.java,v 1.1 2004-09-02 18:11:50 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.preferences;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import net.sourceforge.phpeclipse.css.core.CssCore;
+import net.sourceforge.phpeclipse.css.core.internal.CssCorePreferences;
+import net.sourceforge.phpeclipse.css.core.profiles.IProfileDescriptor;
+import net.sourceforge.phpeclipse.css.core.profiles.IProfileManager;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIMessages;
+
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+/**
+ * 
+ */
+public class CssPreferencePage extends PreferencePage
+       implements IWorkbenchPreferencePage {
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The CSS core preferences.
+        */
+       private Preferences preferences;
+
+       /**
+        * The radio buttons used to select the default profile.
+        */
+       private Button[] profileButtons;
+
+       /**
+        * The ID of the currently selected CSS profile.
+        */
+       private String selectedProfile;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Default constructor.
+        */
+       public CssPreferencePage() {
+               super(getString("description")); //$NON-NLS-1$
+               preferences = CssCore.getDefault().getPluginPreferences();
+       }
+
+       // PreferencePage Implementation -------------------------------------------
+
+       /* 
+        * @see PreferencePage#createContents(Composite)
+        */
+       protected Control createContents(Composite parent) {
+               Composite composite = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 1;
+               composite.setLayout(layout);
+
+               createProfileRadioGroup(composite);
+
+               return composite;
+       }
+
+       /* 
+        * @see PreferencePage#performDefaults()
+        */
+       protected void performDefaults() {
+               preferences.setToDefault(CssCorePreferences.PROFILE);
+               selectedProfile = preferences.getString(CssCorePreferences.PROFILE);
+               if (selectedProfile != null) {
+                       for (int i = 0; i < profileButtons.length; i++) {
+                               Button button = profileButtons[i];
+                               if (((String) button.getData()).equals(selectedProfile)) {
+                                       button.setSelection(true);
+                               } else {
+                                       button.setSelection(false);
+                               }
+                       }
+               }
+       }
+
+       /* 
+        * @see PreferencePage#performOk()
+        */
+       public boolean performOk() {
+               preferences.setValue(CssCorePreferences.PROFILE, selectedProfile);
+               return super.performOk();
+       }
+
+       // IWorkbenchPreferencePage Implementation ---------------------------------
+
+       /**
+        * @see IWorkbenchPreferencePage#init(IWorkbench)
+        */
+       public void init(IWorkbench workbench) {
+               selectedProfile = preferences.getString(CssCorePreferences.PROFILE);
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       /**
+        * Creates the radio button group for selecting the default CSS profile.
+        * 
+        * @param composite the composite to add the group to
+        */
+       private void createProfileRadioGroup(Composite composite) {
+               Group profileGroup = new Group(composite, SWT.SHADOW_ETCHED_IN);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 1;
+               profileGroup.setLayout(layout);
+               profileGroup.setText(getString("profile")); //$NON-NLS-1$
+
+               IProfileDescriptor[] profiles = getProfileDescriptors();
+               profileButtons = new Button[profiles.length];
+               for (int i = 0; i < profiles.length; i++) {
+                       Button button = new Button(profileGroup, SWT.RADIO | SWT.LEFT);
+                       button.setText(profiles[i].getName());
+                       button.setData(profiles[i].getId());
+                       if (profiles[i].getId().equals(selectedProfile)) {
+                               button.setSelection(true);
+                       }
+                       button.addSelectionListener(new SelectionAdapter() {
+                               public void widgetSelected(SelectionEvent event) {
+                                       selectedProfile = (String) event.widget.getData();
+                               }
+                       });
+                       profileButtons[i] = button;
+               }
+       }
+
+       /**
+        * Returns all available profile descriptors, alphabetically sorted by 
+        * display name.
+        * 
+        * @return the profile descriptors
+        */
+       private IProfileDescriptor[] getProfileDescriptors() {
+               IProfileManager mgr = CssCore.getDefault().getProfileManager();
+               IProfileDescriptor[] profiles = mgr.getProfileDescriptors();
+               Arrays.sort(profiles, new Comparator() {
+                       public int compare(Object o1, Object o2) {
+                               return ((IProfileDescriptor) o1).getName().compareTo(
+                                               ((IProfileDescriptor) o2).getName());
+                       }
+               });
+               return profiles;
+       }
+
+       private static String getString(String key) {
+               return CssUIMessages.getString(
+                       "CssPreferencePage." + key); //$NON-NLS-1$
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/OverlayPreferenceStore.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/OverlayPreferenceStore.java
new file mode 100644 (file)
index 0000000..e149eec
--- /dev/null
@@ -0,0 +1,597 @@
+/*
+ * 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: OverlayPreferenceStore.java,v 1.1 2004-09-02 18:11:51 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.preferences;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+public class OverlayPreferenceStore implements IPreferenceStore {
+
+       // Inner Classes -----------------------------------------------------------
+
+       /**
+        * Descriptor used to denote data types.
+        */
+       public static final class Type {
+               protected Type() {
+               }
+       }
+
+       /**
+        * Data structure for the overlay key.
+        */
+       public static class OverlayKey {
+
+               private Type fType;
+               private String fKey;
+
+               public OverlayKey(Type type, String key) {
+                       this.fType = type;
+                       this.fKey = key;
+               }
+       }
+
+       /**
+        * @see IPropertyChangeListener
+        */
+       private class PropertyListener implements IPropertyChangeListener {
+
+               /**
+                * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+                */
+               public void propertyChange(PropertyChangeEvent event) {
+                       OverlayKey key = findOverlayKey(event.getProperty());
+                       if (key != null) {
+                               propagateProperty(fParent, key, fStore);
+                       }
+               }
+       }
+
+       // Constants ---------------------------------------------------------------
+
+       /**
+        * Boolean property type.
+        */
+       public static final Type BOOLEAN = new Type();
+
+       /**
+        * Double property type.
+        */
+       public static final Type DOUBLE = new Type();
+
+       /**
+        * Floating point property type.
+        */
+       public static final Type FLOAT = new Type();
+
+       /**
+        * Integer property type.
+        */
+       public static final Type INT = new Type();
+
+       /**
+        * Long integer property type.
+        */
+       public static final Type LONG = new Type();
+
+       /**
+        * String property type.
+        */
+       public static final Type STRING = new Type();
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The parent preference store.
+        */
+       private IPreferenceStore fParent;
+
+       /**
+        * The underlying preference store.
+        */
+       private IPreferenceStore fStore;
+
+       /**
+        * The keys of this store.
+        */
+       private List fOverlayKeys = new ArrayList();
+
+       /**
+        * The property listener.
+        */
+       private PropertyListener fPropertyListener;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Creates and returns a new overlay preference store.
+        * 
+        * @param parent the parent preference store
+        */
+       public OverlayPreferenceStore(IPreferenceStore parent) {
+               this.fParent = parent;
+               fStore = new PreferenceStore();
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       public void addKey(Type type, String key) {
+               this.fOverlayKeys.add(new OverlayKey(type, key));
+       }
+       public void addBooleanKey(String key) {
+               addKey(BOOLEAN, key);
+       }
+       public void addDoubleKey(String key) {
+               addKey(DOUBLE, key);
+       }
+       public void addFloatKey(String key) {
+               addKey(FLOAT, key);
+       }
+       public void addIntKey(String key) {
+               addKey(INT, key);
+       }
+       public void addLongKey(String key) {
+               addKey(LONG, key);
+       }
+       public void addStringKey(String key) {
+               addKey(STRING, key);
+       }
+
+       /**
+        * Propagates all overlay keys from this store to the parent store.
+        */
+       public void propagate() {
+               for (Iterator i = fOverlayKeys.iterator(); i.hasNext(); ) {
+                       propagateProperty(fStore, (OverlayKey) i.next(), fParent);
+               }
+       }
+
+       /**
+        * Loads the values from the parent into this store.
+        */
+       public void load() {
+               for (Iterator i = fOverlayKeys.iterator(); i.hasNext(); ) {
+                       loadProperty(fParent, (OverlayKey) i.next(), fStore, true);
+               }
+       }
+
+       /**
+        * Loads the default values.
+        */
+       public void loadDefaults() {
+               for (Iterator i = fOverlayKeys.iterator(); i.hasNext(); ) {
+                       setToDefault(((OverlayKey) i.next()).fKey);
+               }
+       }
+
+       /**
+        * Starts to listen for changes.
+        */
+       public void startListening() {
+               if (fPropertyListener == null) {
+                       fPropertyListener = new PropertyListener();
+                       fParent.addPropertyChangeListener(fPropertyListener);
+               }
+       }
+
+       /**
+        * Stops to listen for changes.
+        */
+       public void stopListening() {
+               if (fPropertyListener != null) {
+                       fParent.removePropertyChangeListener(fPropertyListener);
+                       fPropertyListener = null;
+               }
+       }
+
+       // IPreferenceStore Implementation -----------------------------------------
+
+       /**
+        * @see IPreferenceStore#addPropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
+        */
+       public void addPropertyChangeListener(IPropertyChangeListener listener) {
+               fStore.addPropertyChangeListener(listener);
+       }
+
+       /**
+        * @see IPreferenceStore#removePropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
+        */
+       public void removePropertyChangeListener(IPropertyChangeListener listener) {
+               fStore.removePropertyChangeListener(listener);
+       }
+
+       /**
+        * @see IPreferenceStore#firePropertyChangeEvent(java.lang.String, java.lang.Object, java.lang.Object)
+        */
+       public void firePropertyChangeEvent(String name, Object oldValue,
+               Object newValue) {
+               fStore.firePropertyChangeEvent(name, oldValue, newValue);
+       }
+
+       /**
+        * @see IPreferenceStore#contains(java.lang.String)
+        */
+       public boolean contains(String name) {
+               return fStore.contains(name);
+       }
+
+       /**
+        * @see IPreferenceStore#getBoolean(java.lang.String)
+        */
+       public boolean getBoolean(String name) {
+               return fStore.getBoolean(name);
+       }
+
+       /**
+        * @see IPreferenceStore#getDefaultBoolean(java.lang.String)
+        */
+       public boolean getDefaultBoolean(String name) {
+               return fStore.getDefaultBoolean(name);
+       }
+
+       /**
+        * @see IPreferenceStore#getDefaultDouble(java.lang.String)
+        */
+       public double getDefaultDouble(String name) {
+               return fStore.getDefaultDouble(name);
+       }
+
+       /**
+        * @see IPreferenceStore#getDefaultFloat(String)
+        */
+       public float getDefaultFloat(String name) {
+               return fStore.getDefaultFloat(name);
+       }
+
+       /**
+        * @see IPreferenceStore#getDefaultInt(String)
+        */
+       public int getDefaultInt(String name) {
+               return fStore.getDefaultInt(name);
+       }
+
+       /**
+        * @see IPreferenceStore#getDefaultLong(String)
+        */
+       public long getDefaultLong(String name) {
+               return fStore.getDefaultLong(name);
+       }
+
+       /**
+        * @see IPreferenceStore#getDefaultString(String)
+        */
+       public String getDefaultString(String name) {
+               return fStore.getDefaultString(name);
+       }
+
+       /**
+        * @see IPreferenceStore#getDouble(String)
+        */
+       public double getDouble(String name) {
+               return fStore.getDouble(name);
+       }
+
+       /**
+        * @see IPreferenceStore#getFloat(String)
+        */
+       public float getFloat(String name) {
+               return fStore.getFloat(name);
+       }
+
+       /**
+        * @see IPreferenceStore#getInt(String)
+        */
+       public int getInt(String name) {
+               return fStore.getInt(name);
+       }
+
+       /**
+        * @see IPreferenceStore#getLong(String)
+        */
+       public long getLong(String name) {
+               return fStore.getLong(name);
+       }
+
+       /**
+        * @see IPreferenceStore#getString(String)
+        */
+       public String getString(String name) {
+               return fStore.getString(name);
+       }
+
+       /**
+        * @see IPreferenceStore#isDefault(String)
+        */
+       public boolean isDefault(String name) {
+               return fStore.isDefault(name);
+       }
+
+       /**
+        * @see IPreferenceStore#needsSaving()
+        */
+       public boolean needsSaving() {
+               return fStore.needsSaving();
+       }
+
+       /**
+        * @see IPreferenceStore#putValue(String, String)
+        */
+       public void putValue(String name, String value) {
+               if (covers(name)) {
+                       fStore.putValue(name, value);
+               }
+       }
+
+       /**
+        * @see IPreferenceStore#setDefault(String, double)
+        */
+       public void setDefault(String name, double value) {
+               if (covers(name)) {
+                       fStore.setDefault(name, value);
+               }
+       }
+
+       /**
+        * @see IPreferenceStore#setDefault(String, float)
+        */
+       public void setDefault(String name, float value) {
+               if (covers(name)) {
+                       fStore.setDefault(name, value);
+               }
+       }
+
+       /**
+        * @see IPreferenceStore#setDefault(String, int)
+        */
+       public void setDefault(String name, int value) {
+               if (covers(name)) {
+                       fStore.setDefault(name, value);
+               }
+       }
+
+       /**
+        * @see IPreferenceStore#setDefault(String, long)
+        */
+       public void setDefault(String name, long value) {
+               if (covers(name)) {
+                       fStore.setDefault(name, value);
+               }
+       }
+
+       /**
+        * @see IPreferenceStore#setDefault(String, String)
+        */
+       public void setDefault(String name, String value) {
+               if (covers(name)) {
+                       fStore.setDefault(name, value);
+               }
+       }
+
+       /**
+        * @see IPreferenceStore#setDefault(String, boolean)
+        */
+       public void setDefault(String name, boolean value) {
+               if (covers(name)) {
+                       fStore.setDefault(name, value);
+               }
+       }
+
+       /**
+        * @see IPreferenceStore#setToDefault(String)
+        */
+       public void setToDefault(String name) {
+               fStore.setToDefault(name);
+       }
+
+       /**
+        * @see IPreferenceStore#setValue(String, double)
+        */
+       public void setValue(String name, double value) {
+               if (covers(name)) {
+                       fStore.setValue(name, value);
+               }
+       }
+
+       /**
+        * @see IPreferenceStore#setValue(String, float)
+        */
+       public void setValue(String name, float value) {
+               if (covers(name)) {
+                       fStore.setValue(name, value);
+               }
+       }
+
+       /**
+        * @see IPreferenceStore#setValue(String, int)
+        */
+       public void setValue(String name, int value) {
+               if (covers(name)) {
+                       fStore.setValue(name, value);
+               }
+       }
+
+       /**
+        * @see IPreferenceStore#setValue(String, long)
+        */
+       public void setValue(String name, long value) {
+               if (covers(name)) {
+                       fStore.setValue(name, value);
+               }
+       }
+
+       /**
+        * @see IPreferenceStore#setValue(String, String)
+        */
+       public void setValue(String name, String value) {
+               if (covers(name)) {
+                       fStore.setValue(name, value);
+               }
+       }
+
+       /**
+        * @see IPreferenceStore#setValue(String, boolean)
+        */
+       public void setValue(String name, boolean value) {
+               if (covers(name)) {
+                       fStore.setValue(name, value);
+               }
+       }
+
+       // Protected Methods -------------------------------------------------------
+
+       /**
+        * Tries to find and return the overlay key for the given preference key
+        * string.
+        * 
+        * @param key the preference key string
+        * @return the overlay key or <code>null</code> if none can be found
+        */
+       protected final OverlayKey findOverlayKey(String key) {
+               for (Iterator i = fOverlayKeys.iterator(); i.hasNext(); ) {
+                       OverlayKey k = (OverlayKey) i.next();
+                       if (k.fKey.equals(key)) {
+                               return k;
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Propagates the given overlay key from the orgin to the target preference
+        * store.
+        * 
+        * @param origin the source preference store
+        * @param key the overlay key
+        * @param target the preference store to which the key is propagated
+        */
+       protected final void propagateProperty(IPreferenceStore origin,
+               OverlayKey key, IPreferenceStore target) {
+               if (origin.isDefault(key.fKey)) {
+                       if (!target.isDefault(key.fKey)) {
+                               target.setToDefault(key.fKey);
+                       }
+                       return;
+               }
+               Type d = key.fType;
+               if (BOOLEAN == d) {
+                       boolean originValue = origin.getBoolean(key.fKey);
+                       boolean targetValue = target.getBoolean(key.fKey);
+                       if (targetValue != originValue) {
+                               target.setValue(key.fKey, originValue);
+                       }
+               } else if (DOUBLE == d) {
+                       double originValue = origin.getDouble(key.fKey);
+                       double targetValue = target.getDouble(key.fKey);
+                       if (targetValue != originValue) {
+                               target.setValue(key.fKey, originValue);
+                       }
+               } else if (FLOAT == d) {
+                       float originValue = origin.getFloat(key.fKey);
+                       float targetValue = target.getFloat(key.fKey);
+                       if (targetValue != originValue) {
+                               target.setValue(key.fKey, originValue);
+                       }
+               } else if (INT == d) {
+                       int originValue = origin.getInt(key.fKey);
+                       int targetValue = target.getInt(key.fKey);
+                       if (targetValue != originValue) {
+                               target.setValue(key.fKey, originValue);
+                       }
+               } else if (LONG == d) {
+                       long originValue = origin.getLong(key.fKey);
+                       long targetValue = target.getLong(key.fKey);
+                       if (targetValue != originValue) {
+                               target.setValue(key.fKey, originValue);
+                       }
+               } else if (STRING == d) {
+                       String originValue = origin.getString(key.fKey);
+                       String targetValue = target.getString(key.fKey);
+                       if ((targetValue != null) && (originValue != null)
+                        && !targetValue.equals(originValue)) {
+                               target.setValue(key.fKey, originValue);
+                       }
+               }
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       /**
+        * Tells whether the given preference key string is
+        * covered by this overlay store.
+        * 
+        * @param key the preference key string
+        * @return <code>true</code> if this overlay store covers the given key
+        */
+       private boolean covers(String key) {
+               return (findOverlayKey(key) != null);
+       }
+
+       /**
+        * Loads the given key from the orgin into the target.
+        * 
+        * @param orgin the source preference store
+        * @param key the overlay key
+        * @param target the preference store to which the key is propagated
+        * @param forceInitialization if <code>true</code> the value in the target
+        *        gets initialized before loading
+        */
+       private void loadProperty(IPreferenceStore orgin, OverlayKey key,
+               IPreferenceStore target, boolean forceInitialization) {
+               Type d = key.fType;
+               if (BOOLEAN == d) {
+                       if (forceInitialization) {
+                               target.setValue(key.fKey, true);
+                       }
+                       target.setValue(key.fKey, orgin.getBoolean(key.fKey));
+                       target.setDefault(key.fKey, orgin.getDefaultBoolean(key.fKey));
+               } else if (DOUBLE == d) {
+                       if (forceInitialization) {
+                               target.setValue(key.fKey, 1.0D);
+                       }
+                       target.setValue(key.fKey, orgin.getDouble(key.fKey));
+                       target.setDefault(key.fKey, orgin.getDefaultDouble(key.fKey));
+               } else if (FLOAT == d) {
+                       if (forceInitialization) {
+                               target.setValue(key.fKey, 1.0F);
+                       }
+                       target.setValue(key.fKey, orgin.getFloat(key.fKey));
+                       target.setDefault(key.fKey, orgin.getDefaultFloat(key.fKey));
+               } else if (INT == d) {
+                       if (forceInitialization) {
+                               target.setValue(key.fKey, 1);
+                       }
+                       target.setValue(key.fKey, orgin.getInt(key.fKey));
+                       target.setDefault(key.fKey, orgin.getDefaultInt(key.fKey));
+               } else if (LONG == d) {
+                       if (forceInitialization) {
+                               target.setValue(key.fKey, 1L);
+                       }
+                       target.setValue(key.fKey, orgin.getLong(key.fKey));
+                       target.setDefault(key.fKey, orgin.getDefaultLong(key.fKey));
+               } else if (STRING == d) {
+                       if (forceInitialization) {
+                               target.setValue(key.fKey, "1"); //$NON-NLS-1$
+                       }
+                       target.setValue(key.fKey, orgin.getString(key.fKey));
+                       target.setDefault(key.fKey, orgin.getDefaultString(key.fKey));
+               }
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/SyntaxPreviewer.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/SyntaxPreviewer.java
new file mode 100644 (file)
index 0000000..f2e8a47
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * 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: SyntaxPreviewer.java,v 1.1 2004-09-02 18:11:50 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.preferences;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIPreferences;
+import net.sourceforge.phpeclipse.css.ui.internal.text.CssSourceViewerConfiguration;
+import net.sourceforge.phpeclipse.css.ui.text.CssTextTools;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+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.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * A previewer for the syntax styling preferences, used to give real time
+ * feedback on changes to the preferences.
+ */
+public class SyntaxPreviewer extends SourceViewer {
+
+       // Constants ---------------------------------------------------------------
+
+       /**
+        * Alias for the preference constant <code>EDITOR_BACKGROUND_COLOR</code>.
+        */
+       private static final String BACKGROUND_COLOR = 
+               CssUIPreferences.EDITOR_BACKGROUND_COLOR;
+
+       /**
+        * Alias for the preference constant
+        * <code>EDITOR_BACKGROUND_DEFAULT_COLOR</code>.
+        */
+       private static final String BACKGROUND_DEFAULT_COLOR = 
+               CssUIPreferences.EDITOR_BACKGROUND_DEFAULT_COLOR;
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The preference store used for loading the style settings.
+        */
+       private IPreferenceStore fStore;
+
+       /**
+        * Listener that handles changes to the preference store.
+        */
+       private IPropertyChangeListener fPropertyChangeListener =
+               new IPropertyChangeListener() {
+                       public void propertyChange(PropertyChangeEvent event) {
+                               if (affectsPresentation(event)) {
+                                       updateColors();
+                               }
+                               invalidateTextPresentation();
+                       }
+               };
+
+       private CssTextTools fTextTools;
+
+       /**
+        * The cached background color of the previewer.
+        */
+       private Color fBackgroundColor;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param parent The parent composite
+        * @param store The preference store to use for loading the style settings
+        */
+       public SyntaxPreviewer(Composite parent, IPreferenceStore store) {
+               super(parent, null, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
+               this.fStore = store;
+               this.fTextTools = new CssTextTools(this.fStore);
+
+               configure(new CssSourceViewerConfiguration(
+                       this.fTextTools, this.fStore));
+               setEditable(false);
+               getTextWidget().setFont(JFaceResources.getTextFont());
+
+               IDocument document = new Document(
+                       loadTextFromResource("preview.css")); //$NON-NLS-1$
+               this.fTextTools.setupDocument(document);
+               setDocument(document);
+
+               this.fStore.addPropertyChangeListener(this.fPropertyChangeListener);
+       }
+
+       // SourceViewer Implementation ---------------------------------------------
+
+       /**
+        * @see org.eclipse.jface.text.TextViewer#handleDispose()
+        */
+       protected void handleDispose() {
+               if (this.fStore != null) {
+                       if (this.fPropertyChangeListener != null) {
+                               this.fStore.removePropertyChangeListener(
+                                       this.fPropertyChangeListener);
+                               this.fPropertyChangeListener = null;
+                       }
+                       this.fStore = null;
+               }
+               if (this.fTextTools != null) {
+                       this.fTextTools.dispose();
+                       this.fTextTools = null;
+               }
+               if ((this.fBackgroundColor != null)
+                && !this.fBackgroundColor.isDisposed()) {
+                       this.fBackgroundColor.dispose();
+               }
+               super.handleDispose();
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private boolean affectsPresentation(PropertyChangeEvent event) {
+               String p = event.getProperty();
+               if (BACKGROUND_COLOR.equals(p)
+                || BACKGROUND_DEFAULT_COLOR.equals(p)) {
+                       return true;
+               }
+               return false;
+       }
+
+       /**
+        * Creates a color from the information stored in the given preference
+        * store.
+        * 
+        * @param key The preference key under which the color is stored
+        * @param display The display
+        * @return The color found, or <code>null</code> if no corresponding 
+        *         preference is available
+        */
+       private Color createColor(String key, Display display) {
+               Color color = null;      
+               if (this.fStore.contains(key)) {
+                       RGB rgb = null;
+                       if (this.fStore.isDefault(key)) {
+                               rgb = PreferenceConverter.getDefaultColor(this.fStore, key);
+                       } else {
+                               rgb = PreferenceConverter.getColor(this.fStore, key);
+                       }
+                       if (rgb != null) {
+                               color = new Color(display, rgb);
+                       }
+               }
+               return color;
+       }       
+       
+       /**
+        * Loads and returns the text stored in the specified resource.
+        * 
+        * @param name The resource name
+        * @return The text loaded from the resource, or an empty string if there
+        *         was an error reading the resource contents
+        */
+       private String loadTextFromResource(String name) {
+               String line;
+               String separator = System.getProperty("line.separator"); //$NON-NLS-1$
+               StringBuffer buffer = new StringBuffer(512);
+               BufferedReader reader = null;
+               try {
+                       reader = new BufferedReader(new InputStreamReader(
+                               getClass().getResourceAsStream(name)));
+                       while ((line = reader.readLine()) != null) {
+                               buffer.append(line);
+                               buffer.append(separator);
+                       }
+               } catch (IOException io) {
+                       CssUI.log(io);
+               } finally {
+                       if (reader != null) {
+                               try {
+                                       reader.close();
+                               } catch (IOException e) {
+                                       // ignore
+                               }
+                       }
+               }
+               return buffer.toString();
+       }
+       
+       /**
+        * Updates the previewer colors.
+        */
+       private void updateColors() {
+               if (this.fStore != null) {
+                       StyledText styledText = getTextWidget();
+                       Color color = null;
+                       if (!this.fStore.getBoolean(BACKGROUND_DEFAULT_COLOR)) {
+                               color = createColor(BACKGROUND_COLOR,
+                                       styledText.getDisplay());
+                       }
+                       styledText.setBackground(color);
+                       if (this.fBackgroundColor != null) {
+                               this.fBackgroundColor.dispose();
+                       }
+                       this.fBackgroundColor = color;
+               }
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/preview.css b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/preferences/preview.css
new file mode 100644 (file)
index 0000000..8242efc
--- /dev/null
@@ -0,0 +1,5 @@
+@import url("custom.css");\r
+a:link, a:visited {\r
+  /* Make links green, not underlined */\r
+  color: #0F0; text-decoration: none\r
+}\r
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/properties/CssPropertiesAdapterFactory.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/properties/CssPropertiesAdapterFactory.java
new file mode 100644 (file)
index 0000000..3ab1c42
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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: CssPropertiesAdapterFactory.java,v 1.1 2004-09-02 18:11:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.properties;
+
+import net.sourceforge.phpeclipse.css.core.model.IRule;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.core.runtime.IAdapterManager;
+import org.eclipse.ui.views.properties.IPropertySource;
+
+/**
+ * Factory for adapting model elements to property sources.
+ */
+public class CssPropertiesAdapterFactory implements IAdapterFactory {
+
+       // Static Methods ----------------------------------------------------------
+
+       /**
+        * Creates and registers this adapter factory with the given manager.
+        * 
+        * @param manager the adapter manager to register with
+        */
+       public static void register(IAdapterManager manager) {
+               CssPropertiesAdapterFactory factory = new CssPropertiesAdapterFactory();
+               manager.registerAdapters(factory, IRule.class);
+       }
+
+       // IAdapterFactory Implementation ------------------------------------------
+
+       /*
+        * @see IAdapterFactory#getAdapter(Object, Class)
+        */
+       public Object getAdapter(Object adaptableObject, Class adapterType) {
+               if (adapterType == IPropertySource.class) {
+                       if (adaptableObject instanceof IRule) {
+                               return new CssRulePropertySource((IRule) adaptableObject);
+                       }
+               }
+               return null;
+       }
+
+       /*
+        * @see IAdapterFactory#getAdapterList()
+        */
+       public Class[] getAdapterList() {
+               return new Class[] { IPropertySource.class };
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/properties/CssPropertyPage.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/properties/CssPropertyPage.java
new file mode 100644 (file)
index 0000000..024843d
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * 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: CssPropertyPage.java,v 1.1 2004-09-02 18:11:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.properties;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import net.sourceforge.phpeclipse.css.core.CssCore;
+import net.sourceforge.phpeclipse.css.core.internal.CssCorePreferences;
+import net.sourceforge.phpeclipse.css.core.internal.profiles.ProfileManager;
+import net.sourceforge.phpeclipse.css.core.profiles.IProfileDescriptor;
+import net.sourceforge.phpeclipse.css.core.profiles.IProfileManager;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIMessages;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.ui.dialogs.PropertyPage;
+
+/**
+ * Property page for CSS projects and files.
+ */
+public class CssPropertyPage extends PropertyPage {
+
+       // Instance Variables ------------------------------------------------------
+
+       private IProfileManager profileManager;
+
+       private boolean useCustomSettings;
+       private Group profileGroup;
+       private Button[] profileButtons;
+       private String selectedProfile;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        */
+       public CssPropertyPage() {
+               profileManager = CssCore.getDefault().getProfileManager();
+       }
+
+       // PropertyPage Implementation ---------------------------------------------
+
+       /**
+        * @see org.eclipse.jface.preference.PreferencePage#createContents(Composite)
+        */
+       protected Control createContents(Composite parent) {
+
+               Composite composite = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 1;
+               composite.setLayout(layout);
+
+               Object element = getElement();
+               if (element instanceof IResource) {
+                       IResource resource = (IResource) element;
+                       try {
+                               selectedProfile = resource.getPersistentProperty(
+                                       ProfileManager.PROFILE_PROPERTY);
+                       } catch (CoreException e) {
+                               // ignore
+                       }
+               }
+               useCustomSettings = (selectedProfile != null);
+               if (selectedProfile == null) {
+                       selectedProfile = getInheritedProfile();
+               }
+
+               Button useInheritedSettingsButton =
+                       new Button(composite, SWT.RADIO | SWT.LEFT);
+               if (element instanceof IProject) {
+                       useInheritedSettingsButton.setText(
+                               getString("useWorkspaceSettings")); //$NON-NLS-1$
+               } else if (element instanceof IResource) {
+                       useInheritedSettingsButton.setText(
+                               getString("useProjectSettings")); //$NON-NLS-1$
+               }
+               useInheritedSettingsButton.setSelection(!useCustomSettings);
+               Button useCustomSettingsButton =
+                       new Button(composite, SWT.RADIO | SWT.LEFT);
+               useCustomSettingsButton.setText(
+                               getString("useCustomSettings")); //$NON-NLS-1$
+               useCustomSettingsButton.addSelectionListener(new SelectionAdapter() {
+                       public void widgetSelected(SelectionEvent event) {
+                               useCustomSettings =
+                                       ((Button) event.widget).getSelection();
+                               updateProfileGroup();
+                       }
+               });
+               useCustomSettingsButton.setSelection(useCustomSettings);
+
+               profileGroup = new Group(composite, SWT.SHADOW_ETCHED_IN);
+               layout = new GridLayout();
+               layout.numColumns = 1;
+               profileGroup.setLayout(layout);
+               profileGroup.setText(getString("profile")); //$NON-NLS-1$
+
+               IProfileManager mgr = CssCore.getDefault().getProfileManager();
+               IProfileDescriptor[] profiles = mgr.getProfileDescriptors();
+               Arrays.sort(profiles, new Comparator() {
+                       public int compare(Object o1, Object o2) {
+                               return ((IProfileDescriptor) o1).getName().compareTo(
+                                               ((IProfileDescriptor) o2).getName());
+                       }
+               });
+
+               profileButtons = new Button[profiles.length];
+               for (int i = 0; i < profiles.length; i++) {
+                       Button button = new Button(profileGroup, SWT.RADIO | SWT.LEFT);
+                       button.setText(profiles[i].getName());
+                       button.setData(profiles[i].getId());
+                       if (profiles[i].getId().equals(selectedProfile)) {
+                               button.setSelection(true);
+                       }
+                       button.addSelectionListener(new SelectionAdapter() {
+                               public void widgetSelected(SelectionEvent event) {
+                                       selectedProfile = (String) event.widget.getData();
+                               }
+                       });
+                       profileButtons[i] = button;
+               }
+               updateProfileGroup();
+
+               return composite;
+       }
+
+       /**
+        * @see org.eclipse.jface.preference.IPreferencePage#performOk()
+        */
+       public boolean performOk() {
+               Object element = getElement();
+               if (element instanceof IResource) {
+                       IResource resource = (IResource) element;
+                       if (useCustomSettings) {
+                               profileManager.setProfile(resource, selectedProfile);
+                       } else {
+                               profileManager.setProfile(resource, null);
+                       }
+               }
+               return true;
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private String getInheritedProfile() {
+               Object element = getElement();
+               String retVal = null;            
+               if (element instanceof IResource) {
+                       IProject project = ((IResource) element).getProject();
+                       try {
+                               retVal = project.getPersistentProperty(
+                                       ProfileManager.PROFILE_PROPERTY);
+                       } catch (CoreException e) {
+                               // ignore
+                       }
+               }
+               if (retVal == null) {
+                       Preferences preferences =
+                                       CssCore.getDefault().getPluginPreferences();
+                       retVal = preferences.getString(CssCorePreferences.PROFILE);
+               }
+               return retVal;
+       }
+
+       private String getString(String key) {
+               return CssUIMessages.getString("CssPropertyPage." + key); //$NON-NLS-1$
+       }
+
+       private void updateProfileGroup() {
+               profileGroup.setEnabled(useCustomSettings);
+               for (int i = 0; i < profileButtons.length; i++) {
+                       profileButtons[i].setEnabled(useCustomSettings);
+               }
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/properties/CssRulePropertySource.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/properties/CssRulePropertySource.java
new file mode 100644 (file)
index 0000000..873aa8e
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * 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: CssRulePropertySource.java,v 1.1 2004-09-02 18:11:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.properties;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.css.core.CssCore;
+import net.sourceforge.phpeclipse.css.core.model.IDeclaration;
+import net.sourceforge.phpeclipse.css.core.model.IPropertyInfo;
+import net.sourceforge.phpeclipse.css.core.model.IRule;
+import net.sourceforge.phpeclipse.css.core.profiles.IProfile;
+import net.sourceforge.phpeclipse.css.core.profiles.IProfileManager;
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.views.properties.IPropertyDescriptor;
+import org.eclipse.ui.views.properties.IPropertySource;
+import org.eclipse.ui.views.properties.PropertyDescriptor;
+
+/**
+ * 
+ */
+public class CssRulePropertySource implements IPropertySource {
+
+       // Inner Classes -----------------------------------------------------------
+
+       /**
+        * Extended label provider that decorates the property values with specific
+        * icons when a priority is set.
+        */
+       private static class DeclarationLabelProvider extends LabelProvider {
+
+               /**
+                * The CSS declaration for which a label should be provided.
+                */
+               private IDeclaration declaration;
+
+               /**
+                * Constructor.
+                * 
+                * @param declaration the declaration for which to provide a label
+                */
+               public DeclarationLabelProvider(IDeclaration declaration) {
+                       this.declaration = declaration;
+               }
+
+               /*
+                * @see org.eclipse.jface.viewers.ILabelProvider#getImage(Object)
+                */
+               public Image getImage(Object element) {
+                       if (this.declaration.getPriority() != null) {
+                               CssUI plugin = CssUI.getDefault();
+                               return plugin.getImageRegistry().get(
+                                       CssUI.ICON_IMPORTANT);
+                       }
+                       return null;
+               }
+
+               /*
+                * @see org.eclipse.jface.viewers.ILabelProvider#getText(Object)
+                */
+               public String getText(Object element) {
+                       return this.declaration.getValue().getSource();
+               }
+
+       }
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The CSS rule for which properties should be provided.
+        */
+       private IRule rule;
+
+       /**
+        * Cached list of property descriptors (<code>IPropertyDescriptor</code>).
+        */
+       private List descriptors;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param styleRule the style rule for which to provide properties
+        */
+       public CssRulePropertySource(IRule styleRule) {
+               this.rule = styleRule;
+       }
+
+       // IPropertySource Implementation ------------------------------------------
+
+       /**
+        * @see IPropertySource#getEditableValue()
+        */
+       public Object getEditableValue() {
+               return null;
+       }
+
+       /**
+        * @see IPropertySource#getPropertyDescriptors()
+        */
+       public IPropertyDescriptor[] getPropertyDescriptors() {
+               if (this.descriptors == null) {
+                       IProfileManager mgr = CssCore.getDefault().getProfileManager();
+                       IProfile profile = mgr.getProfile(null);
+                       this.descriptors = new ArrayList();
+                       for (int i = 0; i < this.rule.getDeclarations().length; i++) {
+                               IDeclaration declaration = this.rule.getDeclarations()[i];
+                               String property = declaration.getProperty().getSource();
+                               PropertyDescriptor descriptor = new PropertyDescriptor(
+                                       new Integer(i), property);
+                               descriptor.setLabelProvider(
+                                       new DeclarationLabelProvider(declaration));
+                               IPropertyInfo info = profile.getPropertyInfo(property);
+                               if (info != null) {
+                                       descriptor.setCategory(info.getCategory());
+                               }
+                               this.descriptors.add(descriptor);
+                       }
+               }
+               return (IPropertyDescriptor[]) this.descriptors.toArray(
+                       new IPropertyDescriptor[this.descriptors.size()]);
+       }
+
+       /**
+        * @see IPropertySource#getPropertyValue(Object)
+        */
+       public Object getPropertyValue(Object id) {
+               int i = ((Integer) id).intValue();
+               ISourceReference propertyValue =
+                       this.rule.getDeclarations()[i].getValue();
+               return propertyValue.getSource();
+       }
+
+       /**
+        * @see IPropertySource#isPropertySet(Object)
+        */
+       public boolean isPropertySet(Object id) {
+               // read-only property
+               return false;
+       }
+
+       /**
+        * @see IPropertySource#resetPropertyValue(Object)
+        */
+       public void resetPropertyValue(Object id) {
+               // read-only property
+       }
+
+       /**
+        * @see IPropertySource#setPropertyValue(Object, Object)
+        */
+       public void setPropertyValue(Object id, Object value) {
+               // read-only property
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/AbstractCssScanner.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/AbstractCssScanner.java
new file mode 100644 (file)
index 0000000..b5149db
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * 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: AbstractCssScanner.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.text;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import net.sourceforge.phpeclipse.css.ui.text.IColorManager;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.resource.StringConverter;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.RGB;
+
+/**
+ * 
+ */
+public abstract class AbstractCssScanner extends BufferedRuleBasedScanner {
+
+       // Inner Classes -----------------------------------------------------------
+
+       /**
+        * Internal data structure for associating the various style preferences 
+        * of tokens with each other.
+        */
+       private static final class StyleKeys {
+
+               /**
+                * The preference key that determines the foreground color of the token.
+                */
+               private String colorKey;
+
+               /**
+                * The preference key that indicates whether the token is to be 
+                * displayed in bold face.
+                */
+               private String boldKey;
+
+               /**
+                * Constructor.
+                * 
+                * @param colorKey The color preference key
+                * @param boldKey The preference key determining whether the
+                *        corresponding tokens should be rendered bold
+                */
+               private StyleKeys(String colorKey, String boldKey) {
+                       this.colorKey = colorKey;
+                       this.boldKey = boldKey;
+               }
+
+               /**
+                * @see Object#equals(Object)
+                */
+               public boolean equals(Object o) {
+                       if (!(o instanceof StyleKeys)) {
+                               return false;
+                       }
+                       StyleKeys styleKeys = (StyleKeys) o;
+                       if (((colorKey != null) && !colorKey.equals(styleKeys.colorKey))
+                        || (colorKey != styleKeys.colorKey)) {
+                               return false;
+                       }
+                       if (((boldKey != null) && !boldKey.equals(styleKeys.boldKey))
+                        || (boldKey != styleKeys.boldKey)) {
+                               return false;
+                       }
+                       return true;
+               }
+
+               /**
+                * @see Object#hashCode()
+                */
+               public int hashCode() {
+                       int retVal = 17;
+                       retVal = (retVal * 37) +
+                               (colorKey != null ? colorKey.hashCode() : 0);
+                       retVal = (retVal * 37) +
+                               (boldKey != null ? boldKey.hashCode() : 0);
+                       return retVal;
+               }
+
+       }
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The preference store associated with the scanner.
+        */
+       private IPreferenceStore store;
+
+       /**
+        * Listener for preference store changes related to tokens.
+        */
+       private IPropertyChangeListener propertyChangeListener =
+               new IPropertyChangeListener() {
+                       public void propertyChange(PropertyChangeEvent event) {
+                               String property = event.getProperty();
+                               StyleKeys styleKeys = getStyleKeysContaining(property);
+                               if (styleKeys != null) {
+                                       if (styleKeys.colorKey.equals(property)) {
+                                               Token token = (Token) tokens.get(styleKeys);
+                                               handleColorChange(token, event);
+                                       } else if (styleKeys.boldKey.equals(property)) {
+                                               Token token = (Token) tokens.get(styleKeys);
+                                               handleBoldChange(token, event);
+                                       }
+                               }
+                       }
+               };
+       
+       /**
+        * The shared text colors.
+        */
+       private IColorManager colorManager;
+
+       /**
+        * A map containing the defined tokens keyed by the color preference key.
+        */
+       private Map tokens = new HashMap(4);
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param store the preference store
+        * @param manager the color manager
+        */
+       public AbstractCssScanner(IPreferenceStore store, IColorManager manager) {
+               store.addPropertyChangeListener(propertyChangeListener);
+               this.store = store;
+               this.colorManager = manager;
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Adapts the tokens managed by this scanner to changes made to the 
+        * corresponding preferences.
+        * 
+        * @param event the change event fired by the preference store
+        */
+       public void adaptToPreferenceChange(PropertyChangeEvent event) {
+               String property = event.getProperty();
+               StyleKeys styleKeys = getStyleKeysContaining(property);
+               if (styleKeys != null) {
+                       if (styleKeys.colorKey.equals(property)) {
+                               Token token = (Token) tokens.get(styleKeys);
+                               handleColorChange(token, event);
+                       } else if (styleKeys.boldKey.equals(property)) {
+                               Token token = (Token) tokens.get(styleKeys);
+                               handleBoldChange(token, event);
+                       }
+               }
+       }
+
+       /**
+        * Called to determine whether the change of a specific preference affects
+        * the presentation of the tokens managed by the scanner.
+        * 
+        * @param event the preference change event
+        * @return <code>true</code> if the change affects the presentation of one
+        *         of the tokens managed by the scanner, <code>false</code>
+        *         otherwise
+        */
+       public boolean affectsPresentation(PropertyChangeEvent event) {
+               String property = event.getProperty();
+               return (getStyleKeysContaining(property) != null);
+       }
+
+       // Protected Methods -------------------------------------------------------
+
+       /**
+        * Creates a token with the specified color and style as associated text
+        * attribute. The color and style are specified as preference keys.
+        * 
+        * @param colorKey The preference key of the color
+        * @param boldKey The preference key of the boolean value that determines
+        *        whether the text should be rendered bold, or <code>null</code>
+        * @return the created token
+        */
+       protected final IToken createToken(String colorKey, String boldKey) {
+               RGB rgb = PreferenceConverter.getColor(store, colorKey);
+               colorManager.unbindColor(colorKey);
+               colorManager.bindColor(colorKey, rgb);
+               int style = SWT.NORMAL;
+               if ((boldKey != null) && store.getBoolean(boldKey)) {
+                       style |= SWT.BOLD;
+               }
+               IToken token = new Token(new TextAttribute(
+                       colorManager.getColor(colorKey), null, style));
+               StyleKeys styleKeys = new StyleKeys(colorKey, boldKey);
+               tokens.put(styleKeys, token);
+               return token;
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private StyleKeys getStyleKeysContaining(String key) {
+               for (Iterator i = tokens.keySet().iterator(); i.hasNext(); ) {
+                       StyleKeys styleKeys = (StyleKeys) i.next();
+                       if (styleKeys.colorKey.equals(key)
+                        || styleKeys.boldKey.equals(key)) {
+                               return styleKeys;
+                       } 
+               }
+               return null;
+       }
+
+       private void handleColorChange(Token token, PropertyChangeEvent event) {
+               RGB rgb = null;
+               Object value = event.getNewValue();
+               if (value instanceof RGB) {
+                       rgb = (RGB) value;
+               } else if (value instanceof String) {
+                       rgb = StringConverter.asRGB((String) value);
+               }
+               if (rgb != null) {
+                       String key = event.getProperty();
+                       colorManager.unbindColor(key);
+                       colorManager.bindColor(key, rgb);
+                       Object data = token.getData();
+                       if (data instanceof TextAttribute) {
+                               TextAttribute oldAttr = (TextAttribute) data;
+                               token.setData(new TextAttribute(colorManager.getColor(key),
+                                       oldAttr.getBackground(), oldAttr.getStyle()));
+                       }
+               }
+       }
+
+       private void handleBoldChange(Token token, PropertyChangeEvent event) {
+               boolean bold = false;
+               Object value = event.getNewValue();
+               if (value instanceof Boolean) {
+                       bold = ((Boolean) value).booleanValue();
+               } else if (value instanceof String) {
+                       StringConverter.asBoolean((String) value);
+               }
+               Object data = token.getData();
+               if (data instanceof TextAttribute) {
+                       TextAttribute oldAttr = (TextAttribute) data;
+                       boolean wasBold = ((oldAttr.getStyle() & SWT.BOLD) != 0);
+                       if (wasBold != bold) {
+                               int newStyle = bold ? oldAttr.getStyle() | SWT.BOLD
+                                                                       : oldAttr.getStyle() ^ SWT.BOLD;
+                               token.setData(new TextAttribute(oldAttr.getForeground(),
+                                       oldAttr.getBackground(), newStyle));
+                       }
+               }
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/AnnotationAdapter.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/AnnotationAdapter.java
new file mode 100644 (file)
index 0000000..d743f29
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: AnnotationAdapter.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.text;
+
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.reconciler.IReconcileResult;
+import org.eclipse.jface.text.source.Annotation;
+
+/**
+ * Adapts a temporary or persistent annotation to a reconcile result.
+ */
+public abstract class AnnotationAdapter implements IReconcileResult {
+
+       /**
+        * Creates and returns the annotation adapted by this adapter.
+        * 
+        * @return an annotation (can be temporary or persistent)
+        */
+       public abstract Annotation createAnnotation();
+       
+       /**
+        * The position of the annotation adapted by this adapter.
+        * 
+        * @return the position
+        */
+       public abstract Position getPosition();
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssAnnotationHover.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssAnnotationHover.java
new file mode 100644 (file)
index 0000000..d2a68b2
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * 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: CssAnnotationHover.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.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 CssAnnotationHover implements IAnnotationHover {
+       /*
+        * @see IVerticalRulerHover#getHoverInfo(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 = model.getAnnotationIterator();
+               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/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssAutoEditStrategy.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssAutoEditStrategy.java
new file mode 100644 (file)
index 0000000..ee17d38
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * 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: CssAutoEditStrategy.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.text;
+
+import net.sourceforge.phpeclipse.css.core.internal.text.CssTextUtils;
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIPreferences;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultAutoIndentStrategy;
+import org.eclipse.jface.text.DefaultLineTracker;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ILineTracker;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.ITextEditorExtension3;
+import org.eclipse.ui.texteditor.ITextEditorExtension3.InsertMode;
+
+/**
+ * Implements various auto-editing aspects for editing CSS:
+ * <ul>
+ *  <li>
+ *   Smart indenting after opening or closing a block
+ *  </li>
+ *  <li>
+ *   Smart insertion of closing braces
+ *  </li>
+ * </ul>
+ * All these only operate when 'Smart Insert' mode is enabled, and the closing
+ * of braces, brackets, parenthesis and strings can be disabled in the editor
+ * preferences.
+ */
+public class CssAutoEditStrategy extends DefaultAutoIndentStrategy {
+
+       // Constants ---------------------------------------------------------------
+
+       /**
+        * Alias for the preference constant <code>EDITOR_SPACES_FOR_TABS</code>.
+        */
+       public static final String SPACES_FOR_TABS =
+               CssUIPreferences.EDITOR_SPACES_FOR_TABS;
+
+       /**
+        * Alias for the preference constant <code>EDITOR_TAB_WIDTH</code>.
+        */
+       public static final String TAB_WIDTH =
+               CssUIPreferences.EDITOR_TAB_WIDTH;
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The line tracker.
+        */
+       private ILineTracker lineTracker;
+
+       /**
+        * The preference store.
+        */
+       private IPreferenceStore store;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Default constructor.
+        */
+       public CssAutoEditStrategy() {
+               lineTracker = new DefaultLineTracker();
+               store = CssUI.getDefault().getPreferenceStore();
+       }
+
+       // DefaultAutoIndentStrategy Implementation --------------------------------
+
+       /**
+        * @see org.eclipse.jface.text.IAutoEditStrategy#customizeDocumentCommand(IDocument, DocumentCommand)
+        */
+       public void customizeDocumentCommand(IDocument d, DocumentCommand c) {
+               if (isSmartInsertMode()) {
+                       if (isNewLine(d, c)) {
+                               smartIndentAfterNewLine(d, c);
+                       } else if (c.text != null) {
+                               if (c.text.length() == 1) {
+                                       switch (c.text.charAt(0)) {
+                                               case '}': {
+                                                       smartInsertClosingBrace(d, c);
+                                                       break;
+                                               }
+                                               default: {
+                                                       // do nothing
+                                               }
+                                       }
+                               }
+                               if (store.getBoolean(SPACES_FOR_TABS)) {
+                                       convertTabs(d, c);
+                               }
+                       }
+               }
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private void convertTabs(IDocument d, DocumentCommand c) {
+               int index = c.text.indexOf('\t');
+               if (index > -1) {
+                       StringBuffer buffer = new StringBuffer();
+                       lineTracker.set(c.text);
+                       int lines = lineTracker.getNumberOfLines();
+                       try {
+                               for (int i = 0; i < lines; i++) {
+                                       int offset = lineTracker.getLineOffset(i);
+                                       int endOffset = offset + lineTracker.getLineLength(i);
+                                       String line = c.text.substring(offset, endOffset);
+                                       int position = 0;
+                                       if (i == 0) {
+                                               IRegion firstLine =
+                                                       d.getLineInformationOfOffset(c.offset);
+                                               position = c.offset - firstLine.getOffset();   
+                                       }
+                                       int length = line.length();
+                                       for (int j = 0; j < length; j++) {
+                                               char ch = line.charAt(j);
+                                               if (ch == '\t') {
+                                                       int tabWidth = getTabWidth();
+                                                       int remainder = position % tabWidth;
+                                                       remainder = tabWidth - remainder;
+                                                       for (int k = 0; k < remainder; k++) {
+                                                               buffer.append(' ');
+                                                       }
+                                                       position += remainder;
+                                               } else {
+                                                       buffer.append(ch);
+                                                       position++;
+                                               }
+                                       }
+                               }
+                               c.text = buffer.toString();
+                       } catch (BadLocationException e) {
+                               // ignore
+                       }
+               }
+       }
+
+       private String getIndentOfLine(IDocument d, int line)
+               throws BadLocationException {
+               if (line > -1) {
+                       int start = d.getLineOffset(line);
+                       int end = start + d.getLineLength(line) - 1;
+                       int whiteEnd = findEndOfWhiteSpace(d, start, end);
+                       return d.get(start, whiteEnd - start);
+               } else {
+                       return ""; //$NON-NLS-1$
+               }
+       }
+
+       private int getTabWidth() {
+               return store.getInt(TAB_WIDTH);
+       }
+
+       private boolean isNewLine(IDocument d, DocumentCommand c) {
+               if ((c.length == 0) && (c.text != null)) {
+                       String[] delimiters = d.getLegalLineDelimiters();
+                       for (int i = 0; i < delimiters.length; i++) {
+                               if (c.text.equals(delimiters[i])) {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }
+
+       private boolean isSmartInsertMode() {
+               IWorkbenchWindow window =
+                       PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+               if (window != null) {
+                       IWorkbenchPage page = window.getActivePage();
+                       if (page != null)  {
+                               IEditorPart part = page.getActiveEditor(); 
+                               if (part instanceof ITextEditorExtension3) {
+                                       InsertMode insertMode =
+                                               ((ITextEditorExtension3) part).getInsertMode();
+                                       return (insertMode == ITextEditorExtension3.SMART_INSERT);
+                               }
+                       }
+               }
+               return false;
+       }
+
+       private String createIndentation(int level) {
+               StringBuffer buf = new StringBuffer();
+               if (store.getBoolean(SPACES_FOR_TABS)) {
+                       int tabWidth = getTabWidth();
+                       for (int i = 0; i < level * tabWidth; i++) {
+                               buf.append(' ');
+                       }
+               } else {
+                       for (int i = 0; i < level; i++) {
+                               buf.append('\t');
+                       }
+               }
+               return buf.toString();
+       }
+
+       private void smartInsertClosingBrace(IDocument d, DocumentCommand c) {
+               int docLength = d.getLength();
+               if ((c.offset == -1) || (docLength == 0)) {
+                       return;
+               }
+               try {
+                       int lineOffset = d.getLineInformationOfOffset(c.offset).getOffset();
+                       if (c.offset == findEndOfWhiteSpace(d, lineOffset, c.offset)) {
+                               int openingBraceOffset =
+                                       CssTextUtils.findMatchingOpeningPeer(d, c.offset - 1, '}');
+                               if (openingBraceOffset >= 0) {
+                                       int openingBraceLine =
+                                               d.getLineOfOffset(openingBraceOffset);
+                                       StringBuffer buf =
+                                               new StringBuffer(getIndentOfLine(d, openingBraceLine));
+                                       buf.append(c.text);
+                                       c.length += c.offset - lineOffset;
+                                       c.offset = lineOffset;
+                                       c.text = buf.toString();
+                               }
+                       }
+               } catch (BadLocationException e) {
+                       CssUI.log(
+                               "Failed to smart indent after closing brace", e); //$NON-NLS-1$
+               }
+       }
+
+       private void smartIndentAfterNewLine(IDocument d, DocumentCommand c) {
+               try {
+                       int docLength = d.getLength();
+                       if ((c.offset == -1) || (docLength == 0)) {
+                               return;
+                       }
+                       StringBuffer buf = new StringBuffer(c.text);
+                       if ((c.offset < docLength) && (d.getChar(c.offset - 1) == '}')) {
+                               // indent with the same amount used before the block was opened 
+                               int openingBraceOffset =
+                                       CssTextUtils.findMatchingOpeningPeer(d, c.offset - 2, '}');
+                               if (openingBraceOffset >= 0) {
+                                       int openingBraceLine =
+                                               d.getLineOfOffset(openingBraceOffset);
+                                       buf.append(getIndentOfLine(d, openingBraceLine));
+                               }
+                       } else if ((c.offset < docLength)
+                                       && (d.getChar(c.offset - 1) == '{')) {
+                               int previousLine = d.getLineOfOffset(c.offset);
+                               buf.append(getIndentOfLine(d, previousLine));
+                               buf.append(createIndentation(1));
+                       } else {
+                               int previousLine = d.getLineOfOffset(c.offset);
+                               buf.append(getIndentOfLine(d, previousLine));
+                       }
+                       c.text = buf.toString();
+               } catch (BadLocationException e) {
+                       CssUI.log(
+                               "Failed to smart indent after new line", e); //$NON-NLS-1$
+               }
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssCodeScanner.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssCodeScanner.java
new file mode 100644 (file)
index 0000000..62447eb
--- /dev/null
@@ -0,0 +1,352 @@
+/*
+ * 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: CssCodeScanner.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.text;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import net.sourceforge.phpeclipse.css.core.internal.text.CssTextUtils;
+import net.sourceforge.phpeclipse.css.core.profiles.IProfile;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIPreferences;
+import net.sourceforge.phpeclipse.css.ui.text.IColorManager;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+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.IWhitespaceDetector;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+
+/**
+ * Rule based scanner responsible for syntax highlighting CSS source.
+ */
+public class CssCodeScanner extends AbstractCssScanner {
+
+       // Inner Classes -----------------------------------------------------------
+
+       /**
+        * Custom rule that detects the SGML/XML comment delimiters
+        * (<code>&lt;!--</code> and <code>--&gt;</code> which are allowed at the 
+        * beginning and the end of CSS content.
+        */
+       private class CdoCdcRule implements IRule {
+
+               /**
+                * The associated token.
+                */
+               private IToken token;
+
+               /**
+                * Constructor.
+                * 
+                * @param token the associated token
+                */
+               public CdoCdcRule(IToken token) {
+                       this.token = token;
+               }
+
+               /**
+                * @see IRule#evaluate(ICharacterScanner)
+                */
+               public synchronized IToken evaluate(ICharacterScanner scanner) {
+                       IToken retVal = Token.UNDEFINED;
+                       int count = 1;
+                       int c = scanner.read();
+                       if (c == '<') {
+                               count++;
+                               c = scanner.read();
+                               if (c == '!') {
+                                       count++;
+                                       c = scanner.read();
+                                       if (c == '-') {
+                                               count++;
+                                               c = scanner.read();
+                                               if (c == '-') {
+                                                       return token;
+                                               }
+                                       }
+                               }
+                       } else if (c == '-') {
+                               count++;
+                               c = scanner.read();
+                               if (c == '-') {
+                                       count++;
+                                       c = scanner.read();
+                                       if (c == '>') {
+                                               return token;
+                                       }
+                               }
+                       }
+                       while (count-- > 0) {
+                               scanner.unread();
+                       }
+                       return retVal;
+               }
+               
+       }
+
+       /**
+        * Custom rule that can detect an at-keyword such as <code>@import</code>.
+        */
+       private class AtKeywordRule implements IRule {
+
+               /**
+                * The associated token.
+                */
+               private IToken token;
+
+               /**
+                * Collection of known at-keywords.
+                */
+               private Collection atKeywords;
+
+               /**
+                * Constructor.
+                * 
+                * @param token the associated token
+                */
+               public AtKeywordRule(IToken token) {
+                       this.token = token;
+                       atKeywords = getProfile().getAtKeywords();
+               }
+
+               /**
+                * @see IRule#evaluate(ICharacterScanner)
+                */
+               public synchronized IToken evaluate(ICharacterScanner scanner) {
+                       IToken retVal = Token.UNDEFINED;
+                       int count = 1;
+                       int c = scanner.read();
+                       if (c == '@') {
+                               c = scanner.read();
+                               if (CssTextUtils.isCssIdentifierStart((char) c)) {
+                                       resetBuffer();
+                                       do {
+                                               appendToBuffer((char) c);
+                                               c = scanner.read();
+                                               count++;
+                                       } while (CssTextUtils.isCssIdentifierPart((char) c));
+                                       String candidate = getBufferContent().toLowerCase();
+                                       if (atKeywords.contains(candidate)) {
+                                               return token;
+                                       }
+                               }
+                       }
+                       while (count-- > 0) {
+                               scanner.unread();
+                       }
+                       return retVal;
+               }
+               
+       }
+
+       /**
+        * Custom rule that can detect a known property.
+        */
+       private class PropertyRule implements IRule {
+
+               /**
+                * The associated token.
+                */
+               private IToken token;
+
+               /**
+                * Collection of known properties.
+                */
+               private Collection properties;
+
+               /**
+                * Constructor.
+                * 
+                * @param token the associated token
+                */
+               public PropertyRule(IToken token) {
+                       this.token = token;
+                       properties = getProfile().getProperties();
+               }
+
+               /**
+                * @see IRule#evaluate(ICharacterScanner)
+                */
+               public synchronized IToken evaluate(ICharacterScanner scanner) {
+                       IToken retVal = Token.UNDEFINED;
+                       int count = 1;
+                       int c = scanner.read();
+                       if (CssTextUtils.isCssIdentifierStart((char) c)) {
+                               resetBuffer();
+                               do {
+                                       appendToBuffer((char) c);
+                                       c = scanner.read();
+                                       count++;
+                               } while (CssTextUtils.isCssIdentifierPart((char) c));
+                               String candidate = getBufferContent().toLowerCase();
+                               if (properties.contains(candidate)) {
+                                       while (CssTextUtils.isCssWhitespace((char) c)) {
+                                               c = scanner.read();
+                                               count++;
+                                       }
+                                       if (c == ':') {
+                                               scanner.unread();
+                                               return token;
+                                       }
+                               }
+                       }
+                       while (count-- > 0) {
+                               scanner.unread();
+                       }
+                       return retVal;
+               }
+               
+       }
+
+       /**
+        * Custom rule that can detect a pseudo-class in a selector.
+        */
+       private class PseudoClassRule implements IRule {
+
+               /**
+                * The associated token.
+                */
+               private IToken token;
+
+               /**
+                * Collection of known pseudo-classes.
+                */
+               private Collection pseudoClasses;
+
+               /**
+                * Constructor.
+                * 
+                * @param token the associated token
+                */
+               public PseudoClassRule(IToken token) {
+                       this.token = token;
+                       pseudoClasses = getProfile().getPseudoClassNames();
+               }
+
+               /**
+                * @see IRule#evaluate(ICharacterScanner)
+                */
+               public synchronized IToken evaluate(ICharacterScanner scanner) {
+                       IToken retVal = Token.UNDEFINED;
+                       int count = 1;
+                       int c = scanner.read();
+                       if (c == ':') {
+                               c = scanner.read();
+                               if (CssTextUtils.isCssIdentifierStart((char) c)) {
+                                       resetBuffer();
+                                       do {
+                                               appendToBuffer((char) c);
+                                               c = scanner.read();
+                                               count++;
+                                       } while (CssTextUtils.isCssIdentifierPart((char) c));
+                                       String candidate = getBufferContent().toLowerCase();
+                                       if (pseudoClasses.contains(candidate)) {
+                                               return token;
+                                       }
+                               }
+                       }
+                       while (count-- > 0) {
+                               scanner.unread();
+                       }
+                       return retVal;
+               }
+               
+       }
+
+       /**
+        * Detects CSS white space.
+        */
+       private static class WhitespaceDetector implements IWhitespaceDetector {
+
+               /**
+                * @see IWhitespaceDetector#isWhitespace(char)
+                */
+               public boolean isWhitespace(char c) {
+                       return CssTextUtils.isCssWhitespace(c);
+               }
+
+       }
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The current CSS profile.
+        */
+       private IProfile profile;
+
+       /**
+        * Shared buffer used by the word detectors.
+        */
+       private StringBuffer buffer = new StringBuffer();
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param store The preference store
+        * @param manager The color manager
+        * @param profile The CSS profile to use
+        */
+       public CssCodeScanner(IPreferenceStore store, IColorManager manager, 
+               IProfile profile) {
+               super(store, manager);
+               this.profile = profile;
+
+               List rules = new ArrayList();
+
+               rules.add(new WhitespaceRule(new WhitespaceDetector()));
+
+               rules.add(new CdoCdcRule(createToken(
+                       CssUIPreferences.EDITOR_COMMENT_COLOR,
+                       CssUIPreferences.EDITOR_COMMENT_BOLD)));
+               rules.add(new AtKeywordRule(createToken(
+                       CssUIPreferences.EDITOR_AT_KEYWORD_COLOR,
+                       CssUIPreferences.EDITOR_AT_KEYWORD_BOLD)));
+               rules.add(new PropertyRule(createToken(
+                       CssUIPreferences.EDITOR_PROPERTY_COLOR,
+                       CssUIPreferences.EDITOR_PROPERTY_BOLD)));
+               rules.add(new PseudoClassRule(createToken(
+                       CssUIPreferences.EDITOR_PSEUDO_CLASS_COLOR,
+                       CssUIPreferences.EDITOR_PSEUDO_CLASS_BOLD)));
+
+               setRules((IRule[]) rules.toArray(new IRule[rules.size()]));
+
+               setDefaultReturnToken(createToken(
+                       CssUIPreferences.EDITOR_DEFAULT_COLOR,
+                       CssUIPreferences.EDITOR_DEFAULT_BOLD));
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private IProfile getProfile() {
+               return profile;
+       }
+
+       private void appendToBuffer(char c) {
+               buffer.append(c);
+       }
+
+       private String getBufferContent() {
+               return buffer.toString();
+       }
+       
+       private void resetBuffer() {
+               buffer.setLength(0);
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssColorManager.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssColorManager.java
new file mode 100644 (file)
index 0000000..396fc26
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * 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: CssColorManager.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.text;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import net.sourceforge.phpeclipse.css.ui.text.IColorManager;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * CSS color manager.
+ */
+public class CssColorManager implements IColorManager {
+
+       // Instance Variables ------------------------------------------------------
+
+       private Map keyTable = new HashMap(10);
+
+       private Map displayTable = new HashMap(2);
+
+       /** 
+        * Flag which tells if the colors are automatically disposed when the
+        * current display gets disposed.
+        */
+       private boolean autoDisposeOnDisplayDispose;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Creates a new CSS color manager which automatically disposes the
+        * allocated colors when the current display gets disposed.
+        */ 
+       public CssColorManager() {
+               this(true);
+       }
+
+       /**
+        * Creates a new CSS color manager.
+        * 
+        * @param autoDisposeOnDisplayDispose if <code>true</code> the color manager
+        *        automatically disposes all managed colors when the current display
+        *        gets disposed and all calls to
+        *        {@link org.eclipse.jface.text.source.ISharedTextColors#dispose()}
+        *        are ignored.
+        */
+       public CssColorManager(boolean autoDisposeOnDisplayDispose) {
+               this.autoDisposeOnDisplayDispose = autoDisposeOnDisplayDispose;
+       }
+       
+       // IColorManager Implementation --------------------------------------------
+
+       /*
+        * @see org.eclipse.jface.text.source.ISharedTextColors#dispose()
+        */
+       public void dispose() {
+               if (!this.autoDisposeOnDisplayDispose) {
+                       dispose(Display.getCurrent());
+               }
+       }
+       
+       /*
+        * @see org.eclipse.jface.text.source.ISharedTextColors#getColor(RGB)
+        */
+       public Color getColor(RGB rgb) {
+               if (rgb == null) {
+                       return null;
+               }
+               final Display display = Display.getCurrent();
+               Map colorTable = (Map) this.displayTable.get(display);
+               if (colorTable == null) {
+                       colorTable = new HashMap(10);
+                       this.displayTable.put(display, colorTable);
+                       if (this.autoDisposeOnDisplayDispose) {
+                               display.disposeExec(new Runnable() {
+                                       public void run() {
+                                               dispose(display);
+                                       }
+                               });
+                       }
+               }
+               Color color = (Color) colorTable.get(rgb);
+               if (color == null) {
+                       color = new Color(Display.getCurrent(), rgb);
+                       colorTable.put(rgb, color);
+               }
+               return color;
+       }
+
+       /*
+        * @see IColorManager#bindColor(String, RGB)
+        */
+       public void bindColor(String key, RGB rgb) {
+               Object value = this.keyTable.get(key);
+               if (value != null) {
+                       throw new IllegalStateException();
+               }
+               this.keyTable.put(key, rgb);
+       }
+
+       /*
+        * @see IColorManager#getColor(String)
+        */
+       public Color getColor(String key) {
+               if (key == null) {
+                       return null;
+               }
+               RGB rgb = (RGB) this.keyTable.get(key);
+               return getColor(rgb);
+       }
+
+       /*
+        * @see IColorManager#unbindColor(String)
+        */
+       public void unbindColor(String key) {
+               this.keyTable.remove(key);
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private void dispose(Display display) {
+               Map colorTable = (Map) this.displayTable.get(display);
+               if (colorTable != null) {
+                       for (Iterator i = colorTable.values().iterator(); i.hasNext(); ) {
+                               Color color = (Color) i.next();
+                               if (color != null && !color.isDisposed()) {
+                                       color.dispose();
+                               }
+                       }
+               }
+       }
+       
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssCommentScanner.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssCommentScanner.java
new file mode 100644 (file)
index 0000000..5300fc4
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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: CssCommentScanner.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.text;
+
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIPreferences;
+import net.sourceforge.phpeclipse.css.ui.text.IColorManager;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.rules.IToken;
+
+/**
+ * 
+ */
+public class CssCommentScanner extends AbstractCssScanner {
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param store The preference store
+        */
+       public CssCommentScanner(IPreferenceStore store, IColorManager manager) {
+               super(store, manager);
+
+               IToken commentToken = createToken(
+                       CssUIPreferences.EDITOR_COMMENT_COLOR,
+                       CssUIPreferences.EDITOR_COMMENT_BOLD);
+               
+               setDefaultReturnToken(commentToken);
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssContentAssistProcessor.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssContentAssistProcessor.java
new file mode 100644 (file)
index 0000000..c3a712e
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+ * 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: CssContentAssistProcessor.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.text;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.css.core.internal.text.CssTextUtils;
+import net.sourceforge.phpeclipse.css.core.model.IAtRule;
+import net.sourceforge.phpeclipse.css.core.model.IDeclaration;
+import net.sourceforge.phpeclipse.css.core.model.IPropertyInfo;
+import net.sourceforge.phpeclipse.css.core.model.IRule;
+import net.sourceforge.phpeclipse.css.core.model.IStyleRule;
+import net.sourceforge.phpeclipse.css.core.model.IStyleSheet;
+import net.sourceforge.phpeclipse.css.core.profiles.IProfile;
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+import net.sourceforge.phpeclipse.css.ui.internal.CssDocumentProvider;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIPreferences;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.CompletionProposal;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.jface.text.contentassist.IContextInformationValidator;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Content assist processor for the CSS editor.
+ * 
+ * TODO If a completion proposal is requested before the style sheet has been
+ *      reconciled, we might not get any proposals, or they might be false.
+ */
+public class CssContentAssistProcessor implements IContentAssistProcessor {
+
+       // Constants ---------------------------------------------------------------
+
+       private static final String AUTOACTIVATION_TRIGGERS =
+               CssUIPreferences.CONTENTASSIST_AUTOACTIVATION_TRIGGERS;
+
+       private static final String ORDER_PROPOSALS =
+               CssUIPreferences.CONTENTASSIST_ORDER_PROPOSALS;
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The preference store.
+        */
+       private IPreferenceStore store;
+
+       /**
+        * The current CSS profile.
+        */
+       private IProfile profile;
+
+       /**
+        * The associated text editor, if any.
+        */
+       private ITextEditor editor;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param profile The CSS profile to use
+        */
+       public CssContentAssistProcessor(IPreferenceStore store, IProfile profile,
+               ITextEditor editor) {
+               this.store = store;
+               this.profile = profile;
+               this.editor = editor;
+       }
+
+       // IContentAssistProcessor -------------------------------------------------
+
+       /*
+        * @see IContentAssistProcessor#computeCompletionProposals
+        */
+       public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer,
+               int documentOffset) {
+               List retVal = Collections.EMPTY_LIST;
+               IDocument document = viewer.getDocument();
+               try {
+                       String prefix = getPrefix(document, documentOffset);
+                       if (prefix.startsWith("@")) { //$NON-NLS-1$
+                               retVal = proposeAtKeywords(document, documentOffset,
+                                       prefix.substring(1));
+                       } else if (prefix.startsWith(":")) { //$NON-NLS-1$
+                               retVal = proposePseudoClasses(document, documentOffset,
+                                       prefix.substring(1));
+                       } else {
+                               retVal = proposeProperties(document, documentOffset, prefix);
+                       }
+                       if ((store != null) && store.getBoolean(ORDER_PROPOSALS)) {
+                               sortProposals(retVal);
+                       }
+               } catch (BadLocationException e) {
+                       CssUI.log(
+                               "Unable to compute completion proposals", e); //$NON-NLS-1$
+               }
+               return (ICompletionProposal[]) retVal.toArray(
+                       new ICompletionProposal[retVal.size()]);
+       }
+
+       /*
+        * @see IContentAssistProcessor#computeContextInformation
+        */
+       public IContextInformation[] computeContextInformation(ITextViewer viewer,
+               int documentOffset) {
+               return new IContextInformation[0];
+       }
+
+       /*
+        * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters
+        */
+       public char[] getCompletionProposalAutoActivationCharacters() {
+               String chars = store.getString(AUTOACTIVATION_TRIGGERS);
+               if (chars == null) {
+                       return null;
+               }
+               return chars.toCharArray();
+       }
+
+       /*
+        * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters
+        */
+       public char[] getContextInformationAutoActivationCharacters() {
+               return null;
+       }
+
+       /*
+        * @see IContentAssistProcessor#getErrorMessage
+        */
+       public String getErrorMessage() {
+               return null;
+       }
+
+       /*
+        * @see IContentAssistProcessor#getContextInformationValidator
+        */
+       public IContextInformationValidator getContextInformationValidator() {
+               return null;
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       /**
+        * Returns the part of the word immediately before the position at which
+        * content assist was requested. The prefix is lower-cased before it is 
+        * returned, to enable case-insensitive matching.
+        * 
+        * @param document the document
+        * @param offset the offset into the document
+        * @return the prefix
+        */
+       private String getPrefix(IDocument document, int offset) {
+               try {
+                       int startPos = offset;
+                       while (startPos > 0) {
+                               char c = document.getChar(startPos - 1);
+                               if (!CssTextUtils.isCssIdentifierPart(c)
+                                && (c != '@') && (c != ':')) {
+                                       break;
+                               }
+                               startPos--;
+                               if ((c == '@') || (c == ':')) {
+                                       break;
+                               }
+                       }
+                       if (startPos < offset) {
+                               return document.get(startPos, offset - startPos).toLowerCase();
+                       }
+               } catch (BadLocationException e) {
+                       e.printStackTrace();
+               }
+               return ""; //$NON-NLS-1$
+       }
+
+       /**
+        * Returns the parsed model of the document loaded in the editor, or
+        * <code>null</code> if the editor hasn't been set or the model couldn't be
+        * retrieved.
+        * 
+        * @return the parsed model
+        */
+       private IStyleSheet getStyleSheet() {
+               if (editor != null) {
+                       IDocumentProvider provider = editor.getDocumentProvider();
+                       if (provider instanceof CssDocumentProvider) {
+                               return ((CssDocumentProvider) provider).getStyleSheet(
+                                       editor.getEditorInput());
+                       }
+               }
+               return null;
+       }
+
+       public boolean isAtKeyword(IDocument document, int offset)
+               throws BadLocationException {
+               IStyleSheet styleSheet = getStyleSheet();
+               if (styleSheet != null) {
+                       IRule rule = styleSheet.getRuleAt(offset);
+                       if (rule instanceof IAtRule) {
+                               ISourceReference name = ((IAtRule) rule).getName();
+                               if (name != null) {
+                                       IRegion region = name.getSourceRegion();
+                                       for (int j = region.getOffset(); j < offset; j++) {
+                                               char ch = document.getChar(j);
+                                               if (!CssTextUtils.isCssIdentifierPart(ch)) {
+                                                       return false;
+                                               }
+                                       }
+                                       return true;
+                               }
+                       } else if (rule == null) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Determines whether the document contains a property at the specified
+        * offset, or at least whether a property is theoretically allowed at that
+        * offset. 
+        * 
+        * @param document the document
+        * @param offset the offset into the document
+        * @return <code>true</code> if the specified offset is a legal position for
+        *         a property, <code>false</code> otherwise
+        * @throws BadLocationException if there was a problem accessing the
+        *         document
+        */
+       public boolean isProperty(IDocument document, int offset)
+               throws BadLocationException {
+               IStyleSheet styleSheet = getStyleSheet();
+               if (styleSheet != null) {
+                       IRule rule = styleSheet.getRuleAt(offset);
+                       if (rule != null) {
+                               IDeclaration declaration = rule.getDeclarationAt(offset);
+                               if (declaration != null) {
+                                       IRegion region = declaration.getSourceRegion();
+                                       for (int j = region.getOffset(); j < offset; j++) {
+                                               if (document.getChar(j) == ':') {
+                                                       return false;
+                                               }
+                                       }
+                                       return true;
+                               } else {
+                                       IRegion region = rule.getSourceRegion();
+                                       for (int j = region.getOffset(); j < offset; j++) {
+                                               if (document.getChar(j) == '{') {
+                                                       return true;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Determines whether the document contains a selector at the specified
+        * offset, or at least whether a selector is theoretically allowed at that
+        * offset.
+        */
+       public boolean isSelector(IDocument document, int offset)
+               throws BadLocationException {
+               IStyleSheet styleSheet = getStyleSheet();
+               if (styleSheet != null) {
+                       IRule rule = styleSheet.getRuleAt(offset);
+                       if (rule instanceof IStyleRule) {
+                               ISourceReference selector = ((IStyleRule) rule).getSelector();
+                               if (selector != null) {
+                                       IRegion region = selector.getSourceRegion();
+                                       for (int j = region.getOffset(); j < offset; j++) {
+                                               if (document.getChar(j) == '{') {
+                                                       return false;
+                                               }
+                                       }
+                                       return true;
+                               }
+                       } else if (rule == null) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       private List proposeAtKeywords(IDocument document, int offset,
+               String prefix) throws BadLocationException {
+               List proposals = new ArrayList();
+               if (isAtKeyword(document, offset)) {
+                       Image icon = CssUI.getDefault().getImageRegistry().get(
+                               CssUI.ICON_AT_RULE);
+                       Collection atRuleNames = profile.getAtKeywords();
+                       for (Iterator i = atRuleNames.iterator(); i.hasNext(); ) {
+                               String atRuleName = (String) i.next();
+                               if (atRuleName.startsWith(prefix)) {
+                                       ICompletionProposal proposal = new CompletionProposal(
+                                               atRuleName, offset - prefix.length(), prefix.length(),
+                                               atRuleName.length(), icon, atRuleName, null, null);
+                                       proposals.add(proposal);
+                               }
+                       }
+               }
+               return proposals;
+       }
+
+       /**
+        * Computes the completion proposals for properties. A property may only
+        * appear at the left-hand side of a declaration, so we check whether the
+        * document offset for which the proposals were requested is a legal
+        * position for a property, and only then compute the actual proposals.
+        * 
+        * @param document the document
+        * @param offset the offset into the document at which completion was
+        *        requested
+        * @param prefix the string immediately before the offset
+        * @return the list of {@link ICompletionProposal}s
+        */
+       private List proposeProperties(IDocument document, int offset,
+               String prefix) throws BadLocationException {
+               List proposals = new ArrayList();
+               if (isProperty(document, offset - 1)) {
+                       Image propertyIcon =
+                               CssUI.getDefault().getImageRegistry().get(
+                                       CssUI.ICON_PROPERTY);
+                       Image shorthandIcon =
+                               CssUI.getDefault().getImageRegistry().get(
+                                       CssUI.ICON_SHORTHAND);
+                       Collection propertyNames = profile.getProperties();
+                       for (Iterator i = propertyNames.iterator(); i.hasNext(); ) {
+                               String propertyName = (String) i.next();
+                               if (propertyName.startsWith(prefix)) {
+                                       Image icon = propertyIcon;
+                                       IPropertyInfo info = profile.getPropertyInfo(propertyName);
+                                       if (info.isShorthand()) {
+                                               icon = shorthandIcon;
+                                       }
+                                       ICompletionProposal proposal = new CompletionProposal(
+                                               propertyName, offset - prefix.length(),
+                                               prefix.length(), propertyName.length(), icon,
+                                               propertyName, null, info.getDescription());
+                                       proposals.add(proposal);
+                               }
+                       }
+               }
+               return proposals;
+       }
+
+       private List proposePseudoClasses(IDocument document, int offset,
+               String prefix) throws BadLocationException {
+               List proposals = new ArrayList();
+               if (isSelector(document, offset - 1)) {
+                       Image icon = CssUI.getDefault().getImageRegistry().get(
+                               CssUI.ICON_PSEUDO_CLASS);
+                       Collection pseudoClassNames = profile.getPseudoClassNames();
+                       for (Iterator i = pseudoClassNames.iterator(); i.hasNext(); ) {
+                               String pseudoClassName = (String) i.next();
+                               if (pseudoClassName.startsWith(prefix)) {
+                                       ICompletionProposal proposal = new CompletionProposal(
+                                               pseudoClassName, offset - prefix.length(),
+                                               prefix.length(), pseudoClassName.length(), icon,
+                                               pseudoClassName, null, null);
+                                       proposals.add(proposal);
+                               }
+                       }
+               }
+               return proposals;
+       }
+
+       private void sortProposals(List proposals) {
+               Collections.sort(proposals, new Comparator() {
+                       public int compare(Object o1, Object o2) {
+                               String s1 = ((ICompletionProposal) o1).getDisplayString();
+                               if (s1 == null) {
+                                       return -1;
+                               }
+                               String s2 = ((ICompletionProposal) o2).getDisplayString();
+                               return s1.compareToIgnoreCase(s2);
+                       }
+               });
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssDoubleClickStrategy.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssDoubleClickStrategy.java
new file mode 100644 (file)
index 0000000..2e45960
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * 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: CssDoubleClickStrategy.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.text;
+
+import net.sourceforge.phpeclipse.css.core.internal.text.CssTextUtils;
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.source.ICharacterPairMatcher;
+import org.eclipse.jface.util.Assert;
+
+/**
+ * Strategy for selecting CSS identifiers on double click in the editor.
+ * 
+ * This strategy implements selection of CSS identifiers on double click inside
+ * an identifier, as well as selection of blocks delimited by square brackets,
+ * curly braces and parenthesis when the user double clicks directly after
+ * either the opening or the closing delimiter.
+ */
+public class CssDoubleClickStrategy implements ITextDoubleClickStrategy {
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The pair matcher used to select ranges delimited by matching pairs of
+        * braces, brackets and parenthesis.
+        */
+       private ICharacterPairMatcher pairMatcher = new CssPairMatcher();
+
+       // ITextDoubleClickStrategy Implementation ---------------------------------
+
+       /*
+        * @see ITextDoubleClickStrategy#doubleClicked(ITextViewer)
+        */
+       public void doubleClicked(ITextViewer viewer) {
+               IDocument document = viewer.getDocument();
+               if (document.getLength() == 0) {
+                       return;   
+               }
+               int offset = viewer.getSelectedRange().x;
+               Assert.isLegal(offset >= 0,
+                       "Double click offset may not be negative"); //$NON-NLS-1$
+               Assert.isLegal(offset <= document.getLength(),
+                       "Double click offset out of range"); //$NON-NLS-1$
+               IRegion region = pairMatcher.match(document, offset);
+               if ((region != null) && (region.getLength() >= 2)) {
+                       viewer.setSelectedRange(region.getOffset() + 1,
+                               region.getLength() - 2);
+               } else {
+                       try {
+                               region = getSurroundingIdentifier(document, offset);
+                               if (region != null) {
+                                       viewer.setSelectedRange(
+                                               region.getOffset(), region.getLength());
+                               }
+                       } catch (BadLocationException e) {
+                               CssUI.log("Failed to get surrounding " + //$NON-NLS-1$
+                                       "word for double click selection"); //$NON-NLS-1$
+                       }
+               }
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       /**
+        * Returns the region that delimits the identifier surrounding the given
+        * offset into the document. If no identifier is found at the specified
+        * offset, this method returns <code>null</code>.
+        * 
+        * @param doc the document
+        * @param offset the zero-based offset into the document
+        * @return the region covered by the identifier, or <code>null</code> if no
+        *         identifier was found at that offset
+        */
+       private IRegion getSurroundingIdentifier(IDocument doc, int offset)
+               throws BadLocationException {
+               IRegion retVal = null;
+               int length = doc.getLength();
+               offset = Math.min(offset, length - 1);
+               if (CssTextUtils.isCssIdentifierPart(doc.getChar(offset))) {
+                       int start = offset;
+                       while (start > 0) {
+                               if (!CssTextUtils.isCssIdentifierPart(doc.getChar(start - 1))) {
+                                       break;
+                               }
+                               start--;
+                       }
+                       int end = offset;
+                       while (end < (length - 1)) {
+                               if (!CssTextUtils.isCssIdentifierPart(doc.getChar(end + 1))) {
+                                       break;
+                               }
+                               end++;
+                       }
+                       retVal = new Region(start, end - start + 1);
+               }
+               return retVal;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssPairMatcher.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssPairMatcher.java
new file mode 100644 (file)
index 0000000..b308117
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * 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: CssPairMatcher.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.text;
+
+import net.sourceforge.phpeclipse.css.core.internal.text.CssTextUtils;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.source.ICharacterPairMatcher;
+import org.eclipse.jface.util.Assert;
+
+/**
+ * 
+ */
+public class CssPairMatcher implements ICharacterPairMatcher {
+
+       // Constants ---------------------------------------------------------------
+
+       private static final char PAIRS[] = {
+               '{', '}', '(', ')', '[', ']'
+       };
+
+       // Instance Variables ------------------------------------------------------
+
+       private IDocument document;
+
+       private int offset;
+
+       private int anchor;
+
+       // ICharacterPairMatcher Implementation ------------------------------------
+
+       /*
+        * @see ICharacterPairMatcher#clear
+        */
+       public void clear() {
+               document = null;
+               offset = -1;
+               anchor = 0;
+       }
+
+       /*
+        * @see ICharacterPairMatcher#dispose
+        */
+       public void dispose() {
+               document = null;
+       }
+
+       /*
+        * @see ICharacterPairMatcher#match
+        */
+       public IRegion match(IDocument document, int offset) {
+               Assert.isNotNull(document);
+               Assert.isLegal(offset >= 0);
+               this.document = document;
+               this.offset = offset;
+
+               IRegion retVal = null;
+               try {
+                       retVal = matchPairsAt();
+               } catch (BadLocationException e) {
+                       // ignore, there's probably no matching character to highlight
+               }
+               return retVal;
+       }
+
+       /*
+        * @see ICharacterPairMatcher#getAnchor
+        */
+       public int getAnchor() {
+               return anchor;
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       private boolean isClosingCharacter(char ch) {
+               for (int i = 1; i < PAIRS.length; i += 2) {
+                       if (ch == PAIRS[i]) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       private boolean isOpeningCharacter(char ch) {
+               for (int i = 0; i < PAIRS.length; i += 2) {
+                       if (ch == PAIRS[i]) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       private IRegion matchPairsAt() throws BadLocationException {
+               int startPos = -1, endPos = -1;
+               char prevChar = document.getChar(Math.max(offset - 1, 0));
+               if (isOpeningCharacter(prevChar)) {
+                       startPos = offset - 1;
+                       if (startPos >= 0) {
+                               anchor = LEFT;
+                               endPos = CssTextUtils.findMatchingClosingPeer(
+                                       document, startPos + 1, prevChar);
+                               if (endPos > -1) {
+                                       return new Region(startPos, endPos - startPos + 1);
+                               }
+                       }
+               }
+               if (isClosingCharacter(prevChar)) {
+                       endPos = offset - 1;
+                       if (endPos >= 0) {
+                               anchor = RIGHT;
+                               startPos = CssTextUtils.findMatchingOpeningPeer(
+                                       document, endPos - 1, prevChar);
+                               if (startPos > -1) {
+                                       return new Region(startPos, endPos - startPos + 1);
+                               }
+                       }
+               } 
+               return null;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssPartitionScanner.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssPartitionScanner.java
new file mode 100644 (file)
index 0000000..751041b
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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: CssPartitionScanner.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.text;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.text.rules.IPredicateRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.MultiLineRule;
+import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * 
+ */
+public class CssPartitionScanner extends RuleBasedPartitionScanner {
+
+       // Constants ---------------------------------------------------------------
+
+       public static final String CSS_COMMENT =
+               "__css_comment_partition_content_type"; //$NON-NLS-1$
+
+       public static final String CSS_STRING =
+               "__css_string_partition_content_type"; //$NON-NLS-1$
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        */
+       public CssPartitionScanner() {
+
+               IToken commentToken = new Token(CSS_COMMENT);
+               IToken stringToken = new Token(CSS_STRING);
+
+               List rules = new ArrayList();
+
+               rules.add(new MultiLineRule(
+                       "/*", "*/", commentToken)); //$NON-NLS-1$ //$NON-NLS-2$
+
+               // TODO Strings can be continued over a new line using the escape 
+               // character (#42613)
+               rules.add(new SingleLineRule(
+                       "\"", "\"", stringToken, '\\')); //$NON-NLS-1$ //$NON-NLS-2$
+               rules.add(new SingleLineRule(
+                       "'", "'", stringToken, '\\')); //$NON-NLS-1$ //$NON-NLS-2$
+
+               setPredicateRules((IPredicateRule[])
+                       rules.toArray(new IPredicateRule[rules.size()]));
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssReconcileStep.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssReconcileStep.java
new file mode 100644 (file)
index 0000000..d5cbc26
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * 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: CssReconcileStep.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.text;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import net.sourceforge.phpeclipse.css.core.model.IStyleSheet;
+import net.sourceforge.phpeclipse.css.core.parser.IProblem;
+import net.sourceforge.phpeclipse.css.core.parser.IProblemCollector;
+import net.sourceforge.phpeclipse.css.core.parser.LexicalErrorException;
+import net.sourceforge.phpeclipse.css.core.parser.SyntaxErrorException;
+import net.sourceforge.phpeclipse.css.ui.internal.CssDocumentProvider;
+
+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.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Implementation of a reconcile step for building the CSS parse tree on changes
+ * to the editor content.
+ */
+public class CssReconcileStep extends AbstractReconcileStep {
+
+       // Inner Classes -----------------------------------------------------------
+
+       /**
+        * Adapts an <code>IStyleSheet</code> to the <code>IReconcilableModel</code>
+        * interface.
+        */
+       private class StyleSheetAdapter implements IReconcilableModel {
+
+               private IStyleSheet styleSheet;
+
+               public StyleSheetAdapter(IStyleSheet styleSheet) {
+                       this.styleSheet = styleSheet;
+               }
+
+               public IStyleSheet getStyleSheet() {
+                       return styleSheet;
+               }
+
+       }
+
+       /**
+        * 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;
+
+               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() - problem.getSourceStart() + 1;
+                       if (length < 0) {
+                               return null;
+                       }
+                       String type = null;
+                       if (problem.isWarning()) {
+                               type = "org.eclipse.ui.workbench.texteditor.warning"; //$NON-NLS-1$
+                       } else if (problem.isError()) {
+                               type = "org.eclipse.ui.workbench.texteditor.error"; //$NON-NLS-1$
+                       }
+                       return new Annotation(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 StyleSheetAdapter styleSheetAdapter;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Default constructor.
+        */
+       public CssReconcileStep(ITextEditor editor) {
+               this.editor = editor;
+               styleSheetAdapter = new StyleSheetAdapter(getStyleSheet());
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param step the step to add to the pipe
+        * @param editor the associated text editor
+        */
+       public CssReconcileStep(IReconcileStep step, ITextEditor editor) {
+               super(step);
+               this.editor = editor;
+               styleSheetAdapter = new StyleSheetAdapter(getStyleSheet());
+       }
+
+       // AbstractReconcileStep Implementation ------------------------------------
+
+       /*
+        * @see AbstractReconcileStep#reconcileModel(DirtyRegion, IRegion)
+        */
+       protected IReconcileResult[] reconcileModel(DirtyRegion dirtyRegion,
+               IRegion subRegion) {
+               IStyleSheet styleSheet = styleSheetAdapter.getStyleSheet();
+               ProblemCollector problemCollector = new ProblemCollector();
+               try {
+                       styleSheet.reconcile(problemCollector);
+               } catch (LexicalErrorException e) {
+                       // Already reported to the problem collector  
+               } catch (SyntaxErrorException e) {
+                       // Already reported to the problem collector  
+               }
+               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 styleSheetAdapter;
+       }
+
+       // Private Methods Implementation ------------------------------------------
+
+       /**
+        * Retrieve the style sheet associated with the editor input.
+        */
+       private IStyleSheet getStyleSheet() {
+               IDocumentProvider documentProvider = editor.getDocumentProvider();
+               if (documentProvider instanceof CssDocumentProvider) {
+                       CssDocumentProvider cssDocumentProvider = (CssDocumentProvider)
+                               documentProvider;
+                       return cssDocumentProvider.getStyleSheet(editor.getEditorInput());
+               }
+               return null;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssReconcilingStrategy.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssReconcilingStrategy.java
new file mode 100644 (file)
index 0000000..c1ab039
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * 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: CssReconcilingStrategy.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.text;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Iterator;
+
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+
+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;
+
+
+/**
+ * Reconciling strategy for CSS style sheets. This class is responsible for 
+ * keeping the parsed model in sync with the text.
+ */
+public class CssReconcilingStrategy
+       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 CssReconcilingStrategy(ITextEditor editor) {
+               this.editor = editor;
+               firstStep = new CssReconcileStep(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)) {
+                                               continue;
+                                       }
+
+                                       AnnotationAdapter result = (AnnotationAdapter) results[i];
+                                       Position pos = result.getPosition();
+                                       Annotation annotation = result.createAnnotation();
+                                       getAnnotationModel().addAnnotation(annotation, pos);
+                               }
+                       }
+               };
+
+               try {
+                       runnable.run(null);
+               } catch (InvocationTargetException e) {
+                       CssUI.log(e);
+               } catch (InterruptedException e) {
+                       CssUI.log(e);
+               }
+
+               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/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssSourceViewerConfiguration.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssSourceViewerConfiguration.java
new file mode 100644 (file)
index 0000000..534f8f1
--- /dev/null
@@ -0,0 +1,369 @@
+/*
+ * 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: CssSourceViewerConfiguration.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.text;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpeclipse.css.core.CssCore;
+import net.sourceforge.phpeclipse.css.core.profiles.IProfile;
+import net.sourceforge.phpeclipse.css.core.profiles.IProfileManager;
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIPreferences;
+import net.sourceforge.phpeclipse.css.ui.text.CssTextTools;
+import net.sourceforge.phpeclipse.css.ui.text.IColorManager;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.text.DefaultAutoIndentStrategy;
+import org.eclipse.jface.text.DefaultTextDoubleClickStrategy;
+import org.eclipse.jface.text.IAutoIndentStrategy;
+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.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.IFileEditorInput;
+import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Source viewer configuration for CSS. This class takes care of setting up 
+ * various aspects of the CSS editor, such as text hovers, syntax highlighting,
+ * reconciling or the double click strategy.
+ */
+public final class CssSourceViewerConfiguration
+       extends TextSourceViewerConfiguration {
+
+       // Constants ---------------------------------------------------------------
+
+       /**
+        * Alias for the preference constant <code>CONTENTASSIST_AUTOINSERT</code>.
+        */
+       private static final String AUTOINSERT =
+               CssUIPreferences.CONTENTASSIST_AUTOINSERT;
+
+       /**
+        * Alias for the preference constant
+        * <code>CONTENTASSIST_AUTOACTIVATION</code>.
+        */
+       private static final String AUTOACTIVATION =
+               CssUIPreferences.CONTENTASSIST_AUTOACTIVATION;
+
+       /**
+        * Alias for the preference constant
+        * <code>CONTENTASSIST_AUTOACTIVATION_DELAY</code>.
+        */
+       private static final String AUTOACTIVATION_DELAY =
+               CssUIPreferences.CONTENTASSIST_AUTOACTIVATION_DELAY;
+
+       /**
+        * Alias for the preference constant
+        * <code>CONTENTASSIST_PROPOSALS_BACKGROUND</code>.
+        */
+       private static final String PROPOSALS_BACKGROUND =
+               CssUIPreferences.CONTENTASSIST_PROPOSALS_BACKGROUND;
+
+       /**
+        * Alias for the preference constant
+        * <code>CONTENTASSIST_PROPOSALS_FOREGROUND</code>.
+        */
+       private static final String PROPOSALS_FOREGROUND =
+               CssUIPreferences.CONTENTASSIST_PROPOSALS_FOREGROUND;
+
+       /**
+        * Alias for the preference constant <code>EDITOR_SPACES_FOR_TABS</code>.
+        */
+       private static final String SPACES_FOR_TABS =
+               CssUIPreferences.EDITOR_SPACES_FOR_TABS;
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The associated editor.
+        */
+       private ITextEditor editor;
+
+       /**
+        * The preference store used.
+        */
+       private IPreferenceStore store;
+
+       /**
+        * The CSS profile.
+        */
+       private IProfile profile;
+
+       /**
+        * The associated text tools.
+        */
+       private CssTextTools textTools;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Default constructor.
+        */
+       public CssSourceViewerConfiguration() {
+               this(CssUI.getDefault().getTextTools());
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param textTools the CSS text tools to associate with the source viewer
+        *        configuration
+        */
+       public CssSourceViewerConfiguration(CssTextTools textTools) {
+               this(textTools, CssUI.getDefault().getPreferenceStore());
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param textTools the CSS text tools to associate with the source viewer
+        *        configuration
+        * @param store the preference store
+        */
+       public CssSourceViewerConfiguration(
+               CssTextTools textTools, IPreferenceStore store
+       ) {
+               this(textTools, store, null);
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param textTools the CSS text tools to associate with the source viewer
+        *        configuration
+        * @param store the preference store
+        * @param editor the text editor
+        */
+       public CssSourceViewerConfiguration(
+               CssTextTools textTools, IPreferenceStore store, ITextEditor editor
+       ) {
+               this.textTools = textTools;
+               this.store = store;
+               this.editor = editor;
+       }
+
+       // SourceViewerConfiguration Implementation --------------------------------
+
+       /*
+        * @see SourceViewerConfiguration#getAnnotationHover(ISourceViewer)
+        */
+       public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
+               return new CssAnnotationHover();
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getAutoIndentStrategy(ISourceViewer, String)
+        */
+       public IAutoIndentStrategy getAutoIndentStrategy(
+               ISourceViewer sourceViewer, String contentType
+       ) {
+               if (IDocument.DEFAULT_CONTENT_TYPE.equals(contentType)) {
+                       return new CssAutoEditStrategy();
+               }
+
+               return new DefaultAutoIndentStrategy();
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getConfiguredContentTypes(ISourceViewer)
+        */
+       public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
+               return new String[] {
+                       IDocument.DEFAULT_CONTENT_TYPE,
+                       CssPartitionScanner.CSS_COMMENT,
+                       CssPartitionScanner.CSS_STRING
+               };
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getContentAssistant(ISourceViewer)
+        */
+       public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
+               ContentAssistant assistant = new ContentAssistant();
+               assistant.setContentAssistProcessor(
+                       new CssContentAssistProcessor(store, getProfile(), editor),
+                       IDocument.DEFAULT_CONTENT_TYPE);
+               assistant.setInformationControlCreator(
+                       getInformationControlCreator(sourceViewer));
+               assistant.enableAutoInsert(store.getBoolean(AUTOINSERT));
+               assistant.enableAutoActivation(store.getBoolean(AUTOACTIVATION));
+               assistant.setAutoActivationDelay(store.getInt(AUTOACTIVATION_DELAY));
+               assistant.setContextInformationPopupOrientation(
+                       IContentAssistant.CONTEXT_INFO_BELOW);
+               assistant.setProposalPopupOrientation(
+                       IContentAssistant.PROPOSAL_STACKED);
+               assistant.setProposalSelectorBackground(getColorManager().getColor(
+                       PreferenceConverter.getColor(store, PROPOSALS_BACKGROUND)));
+               assistant.setProposalSelectorForeground(getColorManager().getColor(
+                       PreferenceConverter.getColor(store, PROPOSALS_FOREGROUND)));
+               return assistant;
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getDoubleClickStrategy(ISourceViewer, String)
+        */
+       public ITextDoubleClickStrategy getDoubleClickStrategy(
+               ISourceViewer sourceViewer, String contentType
+       ) {
+               if (IDocument.DEFAULT_CONTENT_TYPE.equals(contentType)) {
+                       return new CssDoubleClickStrategy();
+               }
+               return new DefaultTextDoubleClickStrategy();
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getIndentPrefixes(ISourceViewer, String)
+        */
+       public String[] getIndentPrefixes(
+               ISourceViewer sourceViewer, String contentType
+       ) {
+               List retVal = new ArrayList();
+               int tabWidth = getTabWidth(sourceViewer);
+               boolean useSpaces = store.getBoolean(SPACES_FOR_TABS);
+               for (int i = 0; i <= tabWidth; i++) {
+                       StringBuffer prefix = new StringBuffer();
+                       if (useSpaces) {
+                               for (int j = 0; j < tabWidth - i; j++) {
+                                       prefix.append(' ');
+                               }
+                               if (i > 0) {
+                                       prefix.append('\t');
+                               }
+                       } else {        
+                               for (int j = 0; j < i; j++) {
+                                       prefix.append(' ');
+                               }
+                               if (i < tabWidth) {
+                                       prefix.append('\t');
+                               }
+                       }
+                       retVal.add(prefix.toString());
+               }
+               retVal.add(""); //$NON-NLS-1$
+               return (String[]) retVal.toArray(new String[retVal.size()]);
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getPresentationReconciler(ISourceViewer)
+        */
+       public IPresentationReconciler getPresentationReconciler(
+               ISourceViewer sourceViewer
+       ) {
+               PresentationReconciler reconciler = new PresentationReconciler();
+               DefaultDamagerRepairer dr;
+
+               // Comments
+               dr = new DefaultDamagerRepairer(textTools.getCommentScanner());
+               reconciler.setDamager(dr, CssPartitionScanner.CSS_COMMENT);
+               reconciler.setRepairer(dr, CssPartitionScanner.CSS_COMMENT);
+
+               // Strings
+               dr = new DefaultDamagerRepairer(textTools.getStringScanner());
+               reconciler.setDamager(dr, CssPartitionScanner.CSS_STRING);
+               reconciler.setRepairer(dr, CssPartitionScanner.CSS_STRING);
+
+               // Code
+               dr = new DefaultDamagerRepairer(textTools.getCodeScanner(getProfile()));
+               reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+               reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+
+               return reconciler;
+       }
+
+       /*
+        * @see SourceViewerConfiguration#getReconciler(ISourceViewer)
+        */
+       public IReconciler getReconciler(ISourceViewer sourceViewer) {
+               if ((editor != null) && editor.isEditable()) {
+                       MonoReconciler reconciler = new MonoReconciler(
+                                       new CssReconcilingStrategy(editor), false);
+                       reconciler.setProgressMonitor(new NullProgressMonitor());
+                       reconciler.setDelay(500);
+                       return reconciler;
+               }
+
+               return null;
+       }
+
+       /*
+        * @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 CssTextHover(model);
+               }
+
+               return super.getTextHover(sourceViewer, contentType);
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       /**
+        * Returns the color manager associated with this configuration.
+        * 
+        * @return the color manager
+        */
+       private IColorManager getColorManager() {
+               if (textTools != null) {
+                       return textTools.getColorManager();
+               }
+               return null;
+       }
+
+       /**
+        * Returns the CSS profile for the resource currently being viewed, or 
+        * the default profile if this source viewer configuration isn't associated
+        * with an editor.
+        * 
+        * @return the profile
+        */
+       private IProfile getProfile() {
+               if (profile == null) {
+                       IResource resource = null;
+                       if (editor != null) {
+                               IEditorInput input = editor.getEditorInput();
+                               if (input instanceof IFileEditorInput) {
+                                       resource = ((IFileEditorInput) input).getFile();
+                               }
+                       }
+
+                       IProfileManager mgr = CssCore.getDefault().getProfileManager();
+                       profile = mgr.getProfile(resource);
+               }
+
+               return profile;
+       }
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssStringScanner.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssStringScanner.java
new file mode 100644 (file)
index 0000000..3c66241
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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: CssStringScanner.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.text;
+
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIPreferences;
+import net.sourceforge.phpeclipse.css.ui.text.IColorManager;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.rules.IToken;
+
+/**
+ * 
+ */
+public class CssStringScanner extends AbstractCssScanner {
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param store The preference store
+        */
+       public CssStringScanner(IPreferenceStore store, IColorManager manager) {
+               super(store, manager);
+
+               IToken stringToken = createToken(
+                       CssUIPreferences.EDITOR_STRING_COLOR,
+                       CssUIPreferences.EDITOR_STRING_BOLD);
+               
+               setDefaultReturnToken(stringToken);
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssTextHover.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssTextHover.java
new file mode 100644 (file)
index 0000000..7c52cfd
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: CssTextHover.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.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 CssTextHover implements ITextHover {
+       /**
+        * This hovers annotation model.
+        */
+       private IAnnotationModel model;
+
+       /**
+        * Creates a new annotation hover.
+        * 
+        * @param model this hover's annotation model
+        */
+       public CssTextHover(IAnnotationModel model)  {
+               this.model = model;
+       }
+
+       /*
+        * @see ITextHover#getHoverInfo(ITextViewer, IRegion)
+        */
+       public String getHoverInfo(ITextViewer textViewer, IRegion region) {
+               Iterator e = model.getAnnotationIterator();
+               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 CssWordFinder.findWord(textViewer.getDocument(), offset);
+       }
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssWordFinder.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssWordFinder.java
new file mode 100644 (file)
index 0000000..ca30fd0
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Igor Malinin - initial implementation
+ * 
+ * $Id: CssWordFinder.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
+ */
+package net.sourceforge.phpeclipse.css.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 CssWordFinder {
+       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/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/IReconcilingParticipant.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/IReconcilingParticipant.java
new file mode 100644 (file)
index 0000000..db1649e
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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
+ * 
+ * $Id: IReconcilingParticipant.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.text;
+
+/**
+ *  Interface for classes participating in reconciling.
+ */
+public interface IReconcilingParticipant {
+       
+       /**
+        * Called after reconciling has been finished.
+        */
+       void reconciled();
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/text/CssTextTools.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/text/CssTextTools.java
new file mode 100644 (file)
index 0000000..34448bd
--- /dev/null
@@ -0,0 +1,300 @@
+/*
+ * 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: CssTextTools.java,v 1.1 2004-09-02 18:11:51 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.text;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import net.sourceforge.phpeclipse.css.core.CssCore;
+import net.sourceforge.phpeclipse.css.core.profiles.IProfile;
+import net.sourceforge.phpeclipse.css.ui.internal.text.CssCodeScanner;
+import net.sourceforge.phpeclipse.css.ui.internal.text.CssColorManager;
+import net.sourceforge.phpeclipse.css.ui.internal.text.CssCommentScanner;
+import net.sourceforge.phpeclipse.css.ui.internal.text.CssPartitionScanner;
+import net.sourceforge.phpeclipse.css.ui.internal.text.CssStringScanner;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
+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 org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+/**
+ * Tools required to configure a CSS text viewer.
+ * 
+ * <p> 
+ *  The color manager and all scanners exist only one time, i.e. the same 
+ *  instances are returned to all clients. Thus, clients share those tools.
+ * </p>
+ */
+public class CssTextTools {
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The preference store to use.
+        */
+       private IPreferenceStore store;
+
+       /**
+        * Listener for changes to the preference store.
+        */
+       private IPropertyChangeListener propertyChangeListener =
+               new IPropertyChangeListener() {
+                       public void propertyChange(PropertyChangeEvent event) {
+                               adaptToPreferenceChange(event);
+                       }
+               };
+
+       /**
+        * The color manager.
+        */
+       private IColorManager colorManager;
+
+       /**
+        * The partition scanner.
+        */
+       private CssPartitionScanner partitionScanner;
+
+       /**
+        * Map of the code scanners, keyed by profile ID.
+        */
+       private Map codeScanners = new HashMap();
+
+       /**
+        * The token scanner for syntax highlighting comments in CSS source.
+        */
+       private CssCommentScanner commentScanner;
+
+       /**
+        * The token scanner for syntax highlighting string literals in CSS source.
+        */
+       private CssStringScanner stringScanner;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Creates a new CSS text tools collection.
+        * 
+        * @param store the preference store to initialize the text tools. The text
+        *        tools instance installs a listener on the passed preference store
+        *        to adapt itself to changes in the preference store.
+        */
+       public CssTextTools(IPreferenceStore store) {
+               this(store, true);
+       }
+
+       /**
+        * Creates a new CSS text tools collection.
+        * 
+        * @param store the preference store to initialize the text tools. The text
+        *        tool instance installs a listener on the passed preference store
+        *        to adapt itself to changes in the preference store.
+        * @param autoDisposeOnDisplayDispose if <code>true</code>      the color
+        *        manager automatically disposes all managed colors when the current
+        *        display gets disposed and all calls to
+        *        {@link org.eclipse.jface.text.source.ISharedTextColors#dispose()}
+        *        are ignored.
+        */
+       public CssTextTools(IPreferenceStore store,
+                       boolean autoDisposeOnDisplayDispose) {
+               store.addPropertyChangeListener(propertyChangeListener);
+               this.store = store;
+
+               colorManager = new CssColorManager(autoDisposeOnDisplayDispose);
+               partitionScanner = new CssPartitionScanner();
+               commentScanner = new CssCommentScanner(store, colorManager);
+               stringScanner = new CssStringScanner(store, colorManager);
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Returns whether the specified change to the preference store would effect
+        * the presentation of CSS text.
+        * 
+        * @param event the preference store change event
+        * @return <code>true</code> if the specified event affects the presentation
+        *        of CSS text, <code>false</code> otherwise
+        */
+       public boolean affectsPresentation(PropertyChangeEvent event) {
+               for (Iterator i = codeScanners.keySet().iterator(); i.hasNext();) {
+                       CssCodeScanner scanner = (CssCodeScanner)
+                                       codeScanners.get(i.next());
+                       if (scanner.affectsPresentation(event)) {
+                               return true;
+                       }
+               }
+               if (commentScanner.affectsPresentation(event)
+                || stringScanner.affectsPresentation(event)) {
+                       return true;
+               }
+               return false;
+       }
+
+       /**
+        * Factory method for creating a Java-specific document partitioner
+        * using this object's partitions scanner. This method is a 
+        * convenience method.
+        *
+        * @return a newly created Java document partitioner
+        */
+       public IDocumentPartitioner createDocumentPartitioner() {
+               String[] types = new String[] {
+                       CssPartitionScanner.CSS_COMMENT,
+                       CssPartitionScanner.CSS_STRING
+               };
+               return new DefaultPartitioner(getPartitionScanner(), types);
+       }
+
+       /**
+        * Disposes all the individual tools of this tools collection.
+        */
+       public void dispose() {
+
+               // dispose the scanners
+               codeScanners.clear();
+               commentScanner = null;
+               stringScanner = null;
+               partitionScanner = null;
+
+               // dispose the color manager
+               if (colorManager != null) {
+                       colorManager.dispose();
+                       colorManager = null;
+               }
+               
+               // detach from the preference store
+               if (store != null) {
+                       store.removePropertyChangeListener(propertyChangeListener);
+                       propertyChangeListener = null;
+                       store = null;
+               }
+       }
+
+       /**
+        * Returns the color manager which is used to manage
+        * any Java-specific colors needed for such things like syntax highlighting.
+        *
+        * @return the color manager to be used for Java text viewers
+        */
+       public IColorManager getColorManager() {
+               return colorManager;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan CSS source code.
+        *
+        * @param profile the profile for which to retrieve the code scanner
+        * @return a CSS source code scanner
+        */
+       public RuleBasedScanner getCodeScanner(IProfile profile) {
+               if (profile == null) {
+                       // use the default profile
+                       profile = CssCore.getDefault().getProfileManager().getProfile(null);
+               }
+               String profileId = profile.getDescriptor().getId();
+               RuleBasedScanner codeScanner = (RuleBasedScanner)
+                       codeScanners.get(profileId);
+               if (codeScanner == null) {
+                       codeScanner = new CssCodeScanner(store, this.colorManager, profile);
+                       codeScanners.put(profileId, codeScanner);
+               }
+               return codeScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan CSS comments.
+        *
+        * @return a CSS comment scanner
+        */
+       public RuleBasedScanner getCommentScanner() {
+               return commentScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan CSS strings.
+        *
+        * @return a CSS string scanner
+        */
+       public RuleBasedScanner getStringScanner() {
+               return stringScanner;
+       }
+
+       /**
+        * Returns a scanner which is configured to scan CSS-specific partitions,
+        * which are comments, strings and regular code.
+        *
+        * @return a CSS partition scanner
+        */
+       public IPartitionTokenScanner getPartitionScanner() {
+               return partitionScanner;
+       }
+
+       /**
+        * Sets up the given document for the default partitioning.
+        * 
+        * @param document the document to be set up
+        */
+       public void setupDocument(IDocument document) {
+               setupDocument(document, IDocumentExtension3.DEFAULT_PARTITIONING);
+       }
+
+       /**
+        * Sets up the given document for the given partitioning.
+        * 
+        * @param document the document to be set up
+        * @param partitioning the document partitioning
+        */
+       public void setupDocument(IDocument document, String partitioning) {
+               IDocumentPartitioner partitioner = createDocumentPartitioner();
+               if (document instanceof IDocumentExtension3) {
+                       IDocumentExtension3 extension = (IDocumentExtension3) document;
+                       extension.setDocumentPartitioner(partitioning, partitioner);
+               } else {
+                       document.setDocumentPartitioner(partitioner);
+               }
+               partitioner.connect(document);
+       }
+
+       // Protected Methods -------------------------------------------------------
+
+       /**
+        * Adapts the behavior of the contained components to the change according
+        * to the given event.
+        * 
+        * @param event the event to which to adapt
+        */
+       protected void adaptToPreferenceChange(PropertyChangeEvent event) {
+               for (Iterator i = codeScanners.keySet().iterator(); i.hasNext();) {
+                       CssCodeScanner scanner = (CssCodeScanner)
+                                       codeScanners.get(i.next());
+                       if (scanner.affectsPresentation(event)) {
+                               scanner.adaptToPreferenceChange(event);
+                       }
+               }
+               if (commentScanner.affectsPresentation(event)) {
+                       commentScanner.adaptToPreferenceChange(event);
+               }
+               if (stringScanner.affectsPresentation(event)) {
+                       stringScanner.adaptToPreferenceChange(event);
+               }
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/text/IColorManager.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/text/IColorManager.java
new file mode 100644 (file)
index 0000000..253d0ca
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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: IColorManager.java,v 1.1 2004-09-02 18:11:51 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.text;
+
+import org.eclipse.jface.text.source.ISharedTextColors;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+
+/**
+ * Extends the <code>ISharedTextColors</code> interface by providing methods
+ * to bind and unbind colors to specific keys, and retrieve the colors by key.
+ * 
+ * TODO Find out whether this can be replaced with the JFace ColorRegistry
+ */
+public interface IColorManager extends ISharedTextColors {
+
+       /**
+        * Binds a color to the specified key.
+        * 
+        * @param key the key to which the color should be bound
+        * @param rgb the color to bind to the key
+        */
+       void bindColor(String key, RGB rgb);
+
+       /**
+        * Returns the color bound to a specific key.
+        * 
+        * @param key the key to which the color was previously bound
+        * @return the color bound to the specified key, or <code>null</code> if no
+        *         color was bound to that key
+        */
+       Color getColor(String key);
+
+       /**
+        * Unbinds (and disposes) a color.
+        * 
+        * @param key the key to which the color was previously bound
+        */
+       void unbindColor(String key);
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.html.ui/.classpath b/archive/net.sourceforge.phpeclipse.html.ui/.classpath
new file mode 100644 (file)
index 0000000..065ac06
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/archive/net.sourceforge.phpeclipse.html.ui/.cvsignore b/archive/net.sourceforge.phpeclipse.html.ui/.cvsignore
new file mode 100644 (file)
index 0000000..ba077a4
--- /dev/null
@@ -0,0 +1 @@
+bin
diff --git a/archive/net.sourceforge.phpeclipse.html.ui/.project b/archive/net.sourceforge.phpeclipse.html.ui/.project
new file mode 100644 (file)
index 0000000..4c6b7dc
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>net.sourceforge.phpeclipse.html.ui</name>
+       <comment></comment>
+       <projects>
+               <project>net.sf.wdte.ui</project>
+               <project>net.sf.wdte.xml.core</project>
+               <project>net.sf.wdte.xml.ui</project>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.pde.PluginNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/archive/net.sourceforge.phpeclipse.html.ui/build.properties b/archive/net.sourceforge.phpeclipse.html.ui/build.properties
new file mode 100644 (file)
index 0000000..d13b964
--- /dev/null
@@ -0,0 +1,4 @@
+source.htmlui.jar = src/
+output.htmlui.jar = bin/
+bin.includes = plugin.xml,\
+               htmlui.jar
diff --git a/archive/net.sourceforge.phpeclipse.html.ui/icons/full/obj16/html.png b/archive/net.sourceforge.phpeclipse.html.ui/icons/full/obj16/html.png
new file mode 100644 (file)
index 0000000..178c947
Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.html.ui/icons/full/obj16/html.png differ
diff --git a/archive/net.sourceforge.phpeclipse.html.ui/plugin.xml b/archive/net.sourceforge.phpeclipse.html.ui/plugin.xml
new file mode 100644 (file)
index 0000000..277ae4f
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin
+   id="net.sourceforge.phpeclipse.html.ui"
+   name="Web Development Tools HTML UI"
+   version="0.0.1"
+   provider-name="WDTE Project"
+   class="net.sourceforge.phpeclipse.html.ui.HTMLUI">
+   
+   <runtime>
+      <library name="htmlui.jar">
+         <export name="*"/>
+      </library>
+   </runtime>
+   <requires>
+      <import plugin="net.sourceforge.phpeclipse.xml.ui"/>
+      <import plugin="net.sourceforge.phpeclipse.ui"/>
+      <import plugin="net.sourceforge.phpeclipse.xml.core"/>
+      <import plugin="org.eclipse.jface.text"/>
+      <import plugin="org.eclipse.ui.workbench.texteditor"/>
+      <import plugin="org.eclipse.core.resources"/>
+      <import plugin="org.eclipse.text"/>
+      <import plugin="org.eclipse.ui.editors"/>
+      <import plugin="org.eclipse.ui.ide"/>
+      <import plugin="org.eclipse.ui"/>
+      <import plugin="org.eclipse.core.filebuffers"/>
+      <import plugin="org.eclipse.core.runtime"/>
+   </requires>
+
+
+   <extension
+         point="org.eclipse.ui.editors">
+      <editor 
+            name="HTML Editor"
+            icon="icons/full/obj16/html.png"
+            extensions="html, htm, xhtml"
+            class="net.sourceforge.phpeclipse.html.ui.internal.editor.HTMLEditor"
+            id="net.sourceforge.phpeclipse.html.ui.editor">
+      </editor>
+   </extension>
+   <extension
+         point="org.eclipse.core.filebuffers.documentSetup">
+      <participant
+            extensions="html, htm, xhtml"
+            class="net.sourceforge.phpeclipse.html.ui.internal.editor.HTMLDocumentSetupParticipant">
+      </participant>
+   </extension>
+   <extension
+         point="org.eclipse.ui.editors.documentProviders">
+      <provider
+            extensions="html, htm, xhtml"
+            class="net.sourceforge.phpeclipse.html.ui.internal.editor.HTMLDocumentProvider"
+            id="net.sourceforge.phpeclipse.html.ui.documentProvider">
+      </provider>
+   </extension>
+
+
+</plugin>
diff --git a/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/HTMLUI.java b/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/HTMLUI.java
new file mode 100644 (file)
index 0000000..06576ad
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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: HTMLUI.java,v 1.1 2004-09-02 18:13:31 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.html.ui;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+public class HTMLUI extends AbstractUIPlugin {
+
+       // Class Variables ---------------------------------------------------------
+
+       /** The shared instance. */
+       private static HTMLUI plugin;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * The constructor.
+        */
+       public HTMLUI() {
+               plugin = this;
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Returns the shared instance.
+        */
+       public static HTMLUI getDefault() {
+               return plugin;
+       }
+}
diff --git a/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/HTMLUIMessages.java b/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/HTMLUIMessages.java
new file mode 100644 (file)
index 0000000..e777371
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * 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: HTMLUIMessages.java,v 1.1 2004-09-02 18:13:32 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.html.ui.internal;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Utility class that provides easy access to externalized strings.
+ */
+public final class HTMLUIMessages {
+
+       // Constants ---------------------------------------------------------------
+
+       /**
+        * Qualified name of the resource bundle containing the localized messages.
+        */
+       private static final String RESOURCE_BUNDLE =
+               "net.sourceforge.phpeclipse.html.ui.internal.HTMLUIMessages"; //$NON-NLS-1$
+
+       // Class Variables ---------------------------------------------------------
+
+       /**
+        * The resource bundle.
+        */
+       private static ResourceBundle resourceBundle =
+               ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Hidden constructor.
+        */
+       private HTMLUIMessages() {
+               // Hidden
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Returns the resource bundle.
+        * 
+        * @return the resource bundle
+        */
+       public static ResourceBundle getResourceBundle() {
+               return resourceBundle;
+       }
+
+       /**
+        * Returns the message identified by the specified key.
+        * 
+        * @param key the message key
+        * @return the localized message, or the key enclosed by exclamation marks
+        *         if no message was found for the key
+        */
+       public static String getString(String key) {
+               try {
+                       return resourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return "!" + key + "!"; //$NON-NLS-2$ //$NON-NLS-1$
+               }
+       }
+
+       /**
+        * Returns the message identified by the specified key, replacing a single
+        * parameter with the provided value.
+        * 
+        * @param key the message key
+        * @param arg the parameter value
+        * @return the formatted string, or the key enclosed by exclamation marks
+        *         if no message was found for the key
+        */
+       public static String getString(String key, String arg) {
+               return getString(key, new String[] { arg });
+       }
+
+       /**
+        * Returns the message identified by the specified key, replacing all
+        * parameters with the provided values.
+        * 
+        * @param key the message key
+        * @param args the parameter values
+        * @return the formatted string, or the key enclosed by exclamation marks
+        *         if no message was found for the key
+        */
+       public static String getString(String key, String[] args) {
+               return MessageFormat.format(getString(key), args);      
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/HTMLUIMessages.properties b/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/HTMLUIMessages.properties
new file mode 100644 (file)
index 0000000..9cb2a3c
--- /dev/null
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2004 Christopher Lenz and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     Christopher Lenz - initial english resources
+# 
+# $Id: HTMLUIMessages.properties,v 1.1 2004-09-02 18:13:32 jsurfer Exp $
+#
diff --git a/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/editor/HTMLDocumentProvider.java b/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/editor/HTMLDocumentProvider.java
new file mode 100644 (file)
index 0000000..fdbb818
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: HTMLDocumentProvider.java,v 1.1 2004-09-02 18:13:32 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.html.ui.internal.editor;
+
+import net.sourceforge.phpeclipse.xml.ui.internal.editor.XMLDocumentProvider;
+
+/**
+ * Document provider for HTML files.
+ */
+public class HTMLDocumentProvider extends XMLDocumentProvider {
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/editor/HTMLDocumentSetupParticipant.java b/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/editor/HTMLDocumentSetupParticipant.java
new file mode 100644 (file)
index 0000000..92f2aed
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2004 Christopher Lenz and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial implementation
+ * 
+ * $Id: HTMLDocumentSetupParticipant.java,v 1.1 2004-09-02 18:13:32 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.html.ui.internal.editor;
+
+import net.sourceforge.phpeclipse.xml.ui.internal.editor.XMLDocumentSetupParticipant;
+
+/**
+ * Document setup participant that sets up the HTML specific partitioning.
+ */
+public class HTMLDocumentSetupParticipant extends XMLDocumentSetupParticipant {
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/editor/HTMLEditor.java b/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/editor/HTMLEditor.java
new file mode 100644 (file)
index 0000000..4ccff01
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * 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: HTMLEditor.java,v 1.1 2004-09-02 18:13:32 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.html.ui.internal.editor;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import net.sourceforge.phpeclipse.html.ui.internal.preview.HTMLPreviewPage;
+import net.sourceforge.phpeclipse.html.ui.internal.text.HTMLConfiguration;
+import net.sourceforge.phpeclipse.ui.views.preview.IBrowserPreviewPage;
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+import net.sourceforge.phpeclipse.xml.ui.internal.editor.XMLDocumentProvider;
+import net.sourceforge.phpeclipse.xml.ui.internal.editor.XMLEditor;
+import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.texteditor.ContentAssistAction;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+
+
+/**
+ * HTML editor implementation.
+ */
+public class HTMLEditor extends XMLEditor {
+
+       // Instance Variables ------------------------------------------------------
+       
+       /** The associated preview page. */
+       private HTMLPreviewPage previewPage;
+
+       // XMLEditor Implementation ------------------------------------------------
+
+       /* 
+        * @see org.eclipse.ui.texteditor.AbstractTextEditor#editorSaved()
+        */
+       protected void editorSaved() {
+               if (previewPage != null) {
+                       previewPage.update();
+               }
+       }
+
+       /* 
+        * @see org.eclipse.core.runtime.IAdaptable#getAdapter(Class)
+        */
+       public Object getAdapter(Class adapter) {
+               if (adapter == IBrowserPreviewPage.class) {
+                       if (previewPage == null) {
+                               previewPage = createPreviewPage();
+                       }
+                       return previewPage;
+               }
+               return super.getAdapter(adapter);
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       /**
+        * Creates the HTML preview page.
+        */
+       private HTMLPreviewPage createPreviewPage() {
+               IEditorInput input = getEditorInput();
+               if (input instanceof IFileEditorInput) {
+                       IFile file = ((IFileEditorInput) input).getFile();
+                       try {
+                               URL location = file.getLocation().toFile().toURL();
+                               return new HTMLPreviewPage(location);
+                       } catch (MalformedURLException e) { }
+               }
+               return null;
+       }
+       protected void createActions() {
+               super.createActions();
+
+               IAction action = new ContentAssistAction(HTMLEditorMessages.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);
+       }
+       /*
+        * @see org.eclipse.ui.editors.text.TextEditor#initializeEditor()
+        */
+       protected void initializeEditor() {
+               super.initializeEditor();
+
+               XMLTextTools xmlTextTools = XMLPlugin.getDefault().getXMLTextTools();
+               setSourceViewerConfiguration(new HTMLConfiguration(xmlTextTools, this));
+               setDocumentProvider(new XMLDocumentProvider());
+       }
+}
diff --git a/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/editor/HTMLEditorMessages.java b/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/editor/HTMLEditorMessages.java
new file mode 100644 (file)
index 0000000..94c3dd0
--- /dev/null
@@ -0,0 +1,45 @@
+/**********************************************************************
+Copyright (c) 2000, 2002 IBM Corp. and others.
+All rights reserved. This program and the accompanying materials
+are made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+    IBM Corporation - Initial implementation
+    Klaus Hartlage - www.eclipseproject.de
+**********************************************************************/
+package net.sourceforge.phpeclipse.html.ui.internal.editor;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class HTMLEditorMessages {
+
+       private static final String RESOURCE_BUNDLE= "net.sourceforge.phpeclipse.html.ui.internal.editor.HTMLEditorMessages";//$NON-NLS-1$
+
+       private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+       private HTMLEditorMessages() {
+       }
+
+       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/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/editor/HTMLEditorMessages.properties b/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/editor/HTMLEditorMessages.properties
new file mode 100644 (file)
index 0000000..bea66ef
--- /dev/null
@@ -0,0 +1,10 @@
+#############################################################
+#
+# (c) Copyright IBM Corp. 2000, 2001.
+# All Rights Reserved.
+#
+#############################################################
+ContentAssistProposal.label=Content Assist@Ctrl+SPACE
+ContentAssistProposal.tooltip=Content Assist
+ContentAssistProposal.image=
+ContentAssistProposal.description=Content Assist
diff --git a/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/preview/HTMLPreviewPage.java b/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/preview/HTMLPreviewPage.java
new file mode 100644 (file)
index 0000000..3608a09
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * 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: HTMLPreviewPage.java,v 1.1 2004-09-02 18:13:31 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.html.ui.internal.preview;
+
+import java.net.URL;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.LocationAdapter;
+import org.eclipse.swt.browser.LocationEvent;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.part.Page;
+import org.eclipse.ui.texteditor.IUpdate;
+
+import net.sourceforge.phpeclipse.ui.views.preview.IBrowserPreviewPage;
+
+/**
+ * Provides a HTML preview page based on the SWT browser control.
+ */
+public class HTMLPreviewPage extends Page
+       implements IBrowserPreviewPage, IUpdate {
+
+       // Instance Variables ------------------------------------------------------
+
+       /** The browser widget. */
+       private Browser browser;
+
+       /** The URL of the resource to preview. */
+       private URL location;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param location the URL of the resource to preview
+        */
+       public HTMLPreviewPage(URL location) {
+               this.location = location;
+       }
+
+       // IPage Implementation ----------------------------------------------------
+
+       /* 
+        * @see org.eclipse.ui.part.IPage#createControl(Composite)
+        */
+       public void createControl(Composite parent) {
+               browser = new Browser(parent, SWT.NONE);
+               browser.setLayout(new FillLayout());
+               browser.setUrl(location.toString());
+               browser.addLocationListener(new LocationAdapter() {
+                       public void changing(LocationEvent event) {
+                               if (event.location != null) {
+                                       event.doit = false;
+                               }
+                       }
+               });
+       }
+
+       /* 
+        * @see org.eclipse.ui.part.IPage#getControl()
+        */
+       public Control getControl() {
+               return browser;
+       }
+
+       /* 
+        * @see org.eclipse.ui.part.IPage#setFocus()
+        */
+       public void setFocus() {
+               browser.setFocus();
+       }
+
+       // IUpdate Implementation --------------------------------------------------
+
+       /* 
+        * @see IUpdate#update()
+        */
+       public void update() {
+               browser.refresh();
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/text/HTMLCompletionProcessor.java b/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/text/HTMLCompletionProcessor.java
new file mode 100644 (file)
index 0000000..3f85ac0
--- /dev/null
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.html.ui.internal.text;
+
+import net.sourceforge.phpeclipse.ui.WebUI;
+import net.sourceforge.phpeclipse.ui.templates.template.BasicCompletionProcessor;
+import net.sourceforge.phpeclipse.ui.templates.template.HTMLContextType;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.templates.TemplateContextType;
+
+
+/**
+ * A completion processor for XML templates.
+ */
+public class HTMLCompletionProcessor extends BasicCompletionProcessor {
+       
+       /**
+        * Return the XML context type that is supported by this plugin. 
+        */
+       protected TemplateContextType getContextType(ITextViewer viewer, IRegion region) {
+               return WebUI.getDefault().getContextTypeRegistry().getContextType(HTMLContextType.HTML_CONTEXT_TYPE);
+       }
+
+       
+}
diff --git a/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/text/HTMLConfiguration.java b/archive/net.sourceforge.phpeclipse.html.ui/src/net/sourceforge/phpeclipse/html/ui/internal/text/HTMLConfiguration.java
new file mode 100644 (file)
index 0000000..34ca886
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Created on 25.08.2004
+ *
+ * TODO To change the template for this generated file go to
+ * Window - Preferences - Java - Code Style - Code Templates
+ */
+package net.sourceforge.phpeclipse.html.ui.internal.text;
+
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLConfiguration;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLPartitionScanner;
+import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools;
+
+import org.eclipse.jface.text.IDocument;
+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.source.ISourceViewer;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * @author khartlage
+ * 
+ * TODO To change the template for this generated type comment go to Window - Preferences - Java - Code Style - Code Templates
+ */
+public class HTMLConfiguration extends XMLConfiguration {
+  public HTMLConfiguration(XMLTextTools tools) {
+    this(tools, null);
+  }
+
+  public HTMLConfiguration(XMLTextTools tools, ITextEditor editor) {
+    super(tools, editor);
+  }
+
+  public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
+    ContentAssistant assistant = new ContentAssistant();
+    assistant.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+
+    IContentAssistProcessor processor = new HTMLCompletionProcessor();
+    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.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE);
+    assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
+
+    return assistant;
+  }
+}
\ No newline at end of file
diff --git a/archive/net.sourceforge.phpeclipse.js.core/.classpath b/archive/net.sourceforge.phpeclipse.js.core/.classpath
new file mode 100644 (file)
index 0000000..065ac06
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/archive/net.sourceforge.phpeclipse.js.core/.cvsignore b/archive/net.sourceforge.phpeclipse.js.core/.cvsignore
new file mode 100644 (file)
index 0000000..ba077a4
--- /dev/null
@@ -0,0 +1 @@
+bin
diff --git a/archive/net.sourceforge.phpeclipse.js.core/.project b/archive/net.sourceforge.phpeclipse.js.core/.project
new file mode 100644 (file)
index 0000000..3c10404
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>net.sourceforge.phpeclipse.js.core</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+               <nature>org.eclipse.pde.PluginNature</nature>
+       </natures>
+</projectDescription>
diff --git a/archive/net.sourceforge.phpeclipse.js.core/build.properties b/archive/net.sourceforge.phpeclipse.js.core/build.properties
new file mode 100644 (file)
index 0000000..dd10961
--- /dev/null
@@ -0,0 +1,15 @@
+bin.includes = icons/,\
+               jseditorsrc.zip,\
+               plugin.xml,\
+               plugin.properties,\
+               net.sf.wdte.js.core.jar
+src.includes = src/,\
+               scripts/,\
+               plugin.xml,\
+               build.properties,\
+               .project,\
+               .classpath,\
+               plugin.properties
+source.net.sf.wdte.js.core.jar = src/
+jars.compile.order = net.sf.wdte.js.core.jar
+output.net.sf.wdte.js.core.jar = bin/
diff --git a/archive/net.sourceforge.phpeclipse.js.core/plugin.properties b/archive/net.sourceforge.phpeclipse.js.core/plugin.properties
new file mode 100644 (file)
index 0000000..d7fd576
--- /dev/null
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2004 Christopher Lenz and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     Christopher Lenz - initial english resources
+# 
+# $Id: plugin.properties,v 1.1 2004-09-02 18:14:39 jsurfer Exp $
+#
+
+pluginName = Web Development Tools JavaScript Core
+providerName= WDTE Project
diff --git a/archive/net.sourceforge.phpeclipse.js.core/plugin.xml b/archive/net.sourceforge.phpeclipse.js.core/plugin.xml
new file mode 100644 (file)
index 0000000..4a60e64
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin
+   id="net.sourceforge.phpeclipse.js.core"
+   name="%pluginName"
+   version="0.0.9"
+   provider-name="%providerName"
+   class="net.sourceforge.phpeclipse.js.core.JSCorePlugin">
+
+   <runtime>
+      <library name="net.sourceforge.phpeclipse.js.core.jar">
+         <export name="*"/>
+      </library>
+   </runtime>
+   <requires>
+      <import plugin="org.eclipse.core.resources"/>
+      <import plugin="org.eclipse.core.runtime"/>
+      <import plugin="org.eclipse.jface.text"/>
+      <import plugin="org.eclipse.swt"/>
+   </requires>
+
+   <extension point="org.eclipse.team.core.fileTypes">
+      <fileTypes type="text" extension="js"/>
+   </extension>
+
+</plugin>
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/JSCorePlugin.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/JSCorePlugin.java
new file mode 100644 (file)
index 0000000..2809937
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * $RCSfile: JSCorePlugin.java,v $
+ *
+ * Copyright 2002
+ * CH-1700 Fribourg, Switzerland
+ * All rights reserved.
+ *
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.2  2004/05/22 16:14:37  l950637
+ * Adapt for Eclipse 3.0M9
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.3  2003/12/10 20:19:16  agfitzp
+ * 3.0 port
+ *
+ * Revision 1.2  2003/06/21 03:48:51  agfitzp
+ * fixed global variables as functions bug
+ * fixed length calculation of instance variables
+ * Automatic outlining is now a preference
+ *
+ * Revision 1.1  2003/05/28 15:17:12  agfitzp
+ * net.sourceforge.phpeclipse.js.core 0.0.1 code base
+ *
+ *========================================================================
+*/
+
+package net.sourceforge.phpeclipse.js.core;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Plugin;
+
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+public class JSCorePlugin extends Plugin
+{
+   //The shared instance.
+   private static JSCorePlugin plugin;
+
+   //Resource bundle.
+   private ResourceBundle resourceBundle;
+   
+   private boolean defaultsInitialized = false;
+   
+   /**
+    * current func list
+    */
+   private List currentFunctions = new LinkedList();
+     
+   /**
+    * The constructor.
+    * @param descriptor
+    */
+   public JSCorePlugin() {
+      plugin = this;
+
+      try {
+         resourceBundle = ResourceBundle.getBundle("net.sourceforge.phpeclipse.js.core.JSCorePluginResources");
+      } catch(MissingResourceException x) {
+         resourceBundle = null;
+      }
+   }
+
+   /**
+    * Returns the shared instance.
+    * @return
+    */
+   public static JSCorePlugin getDefault() {
+      return plugin;
+   }
+
+   /**
+    * Returns the workspace instance.
+    * @return
+    */
+   public static IWorkspace getWorkspace() {
+      return ResourcesPlugin.getWorkspace();
+   }
+
+   /**
+    * Returns the string from the plugin's resource bundle, or 'key' if not found.
+    * @param key
+    * 
+    * @return
+    */
+   public static String getResourceString(String key) {
+      ResourceBundle bundle = JSCorePlugin.getDefault().getResourceBundle();
+
+      try {
+         return bundle.getString(key);
+      } catch(MissingResourceException e) {
+         return key;
+      }
+   }
+
+   /**
+    * Returns the plugin's resource bundle,
+    * @return
+    */
+   public ResourceBundle getResourceBundle() {
+      return resourceBundle;
+   }
+   
+       /**
+        * Returns the currentFunctions.
+        * @return List
+        */
+       public List getCurrentFunctions() {
+               return currentFunctions;
+       }
+
+       /**
+        * Sets the currentFunctions.
+        * @param currentFunctions The currentFunctions to set
+        */
+       public void setCurrentFunctions(List currentFunctions) {
+               this.currentFunctions = currentFunctions;
+       }
+}
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSClassElement.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSClassElement.java
new file mode 100644 (file)
index 0000000..6e8ee1e
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Created on May 15, 2003
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.2  2003/05/30 20:53:09  agfitzp
+ * 0.0.2 : Outlining is now done as the user types. Some other bug fixes.
+ *
+ *
+ *========================================================================
+*/
+package net.sourceforge.phpeclipse.js.core.model;
+
+import java.util.HashMap;
+
+import org.eclipse.core.resources.IFile;
+
+/**
+ * @author fitzpata
+ *
+ */
+public class JSClassElement extends JSElement
+{
+       protected HashMap childrenByName;
+       protected boolean isPrototype = false;
+
+       /**
+        * @param aName
+        * @param offset
+        * @param length
+        */
+       public JSClassElement(IFile aFile, String aName, int offset, int length)
+       {
+               super(aFile, aName, offset, length);
+               childrenByName = new HashMap();
+       }
+
+       public void addChildElement(JSElement anElement)
+       {
+               String elementName = anElement.getName();
+               if(!childrenByName.containsKey(elementName))
+               {
+                       this.children.add(anElement);
+                       this.childrenByName.put(elementName, anElement);
+                       anElement.setParent(this);
+               }
+       }
+
+       public int category()
+       {
+               return CLASS;   
+       }
+
+       /**
+        * @return
+        */
+       public boolean isPrototype()
+       {
+               return isPrototype;
+       }
+
+       /**
+        * @param b
+        */
+       public void setPrototype(boolean b)
+       {
+               isPrototype = b;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSClassMethodElement.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSClassMethodElement.java
new file mode 100644 (file)
index 0000000..02832bb
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Created on May 20, 2003
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.2  2003/05/30 20:53:09  agfitzp
+ * 0.0.2 : Outlining is now done as the user types. Some other bug fixes.
+ *
+ *========================================================================
+ */
+package net.sourceforge.phpeclipse.js.core.model;
+
+import org.eclipse.core.resources.IFile;
+
+/**
+ * @author fitzpata
+ *
+ */
+public class JSClassMethodElement extends JSFunctionElement
+{
+       public JSClassMethodElement(IFile aFile, String aName, String argumentString, int offset, int length)
+       {
+               super(aFile, aName, argumentString, offset, length);
+       }
+       
+
+       public int category()
+       {
+               return CLASS_METHOD;    
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSClassVariableElement.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSClassVariableElement.java
new file mode 100644 (file)
index 0000000..e1e483f
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Created on May 20, 2003
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.2  2003/05/30 20:53:09  agfitzp
+ * 0.0.2 : Outlining is now done as the user types. Some other bug fixes.
+ *
+ *========================================================================
+ */
+package net.sourceforge.phpeclipse.js.core.model;
+
+import org.eclipse.core.resources.IFile;
+
+/**
+ * @author fitzpata
+ *
+ */
+public class JSClassVariableElement extends JSElement
+{
+
+       /**
+        * @param aName
+        * @param offset
+        * @param length
+        */
+       public JSClassVariableElement(IFile aFile, String aName, int offset, int length)
+       {
+               super(aFile, aName, offset, length);
+       }
+
+       public int category()
+       {
+               return CLASS_VARIABLE;  
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSElement.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSElement.java
new file mode 100644 (file)
index 0000000..034b2e3
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * $RCSfile: JSElement.java,v $
+ *
+ * Copyright 2002
+ * CH-1700 Fribourg, Switzerland
+ * All rights reserved.
+ *
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.2  2004/02/27 18:28:10  cell
+ * Make model elements platform objects so they are automatically adapted
+ *
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.2  2003/05/30 20:53:08  agfitzp
+ * 0.0.2 : Outlining is now done as the user types. Some other bug fixes.
+ *
+ * Revision 1.1  2003/05/28 15:17:12  agfitzp
+ * net.sourceforge.phpeclipse.js.core 0.0.1 code base
+ *
+ *========================================================================
+*/
+
+package net.sourceforge.phpeclipse.js.core.model;
+
+import java.util.List;
+import java.util.LinkedList;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.PlatformObject;
+
+/**
+ * DOCUMENT ME!
+ * 
+ * @author Addi 
+ */
+abstract public class JSElement extends PlatformObject
+       implements JSElementCategories
+{
+       protected IFile file;
+       protected String name;
+       protected int offset;
+       protected int numberOfLines;
+       protected int length;
+
+       protected JSElement parent;
+       protected List children;
+
+       /**
+        * Creates a new JSElement and stores parent element and location in the text.
+        * 
+        * @param aName text corresponding to the func
+        * @param offset  the offset into the text
+        * @param length  the length of the element
+        */
+       public JSElement(IFile aFile, String aName, int offset, int length)
+       {
+               this.file = aFile;
+               this.name = aName;
+               this.offset = offset;
+               this.length = length;
+               this.children = new LinkedList();
+       }
+
+       /**
+        * Method declared on IWorkbenchAdapter
+        * @param o
+        * 
+        * @return
+        */
+       public String getLabel(Object o)
+       {
+               return name;
+       }
+
+       /**
+        * Returns the number of characters in this section.
+        * @return
+        */
+       public int getLength()
+       {
+               return length;
+       }
+
+       /**
+        * Returns the number of lines in the element.
+        * 
+        * @return the number of lines in the element
+        */
+       public int getNumberOfLines()
+       {
+               return numberOfLines;
+       }
+
+       /**
+        * Returns the offset of this section in the file.
+        * @return
+        */
+       public int getStart()
+       {
+               return offset;
+       }
+
+       /**
+        * Sets the number of lines in the element
+        * 
+        * @param newNumberOfLines  the number of lines in the element
+        */
+       public void setNumberOfLines(int newNumberOfLines)
+       {
+               numberOfLines = newNumberOfLines;
+       }
+
+       /**
+        * @see java.lang.Object#toString()
+        */
+       public String toString()
+       {
+               return getLabel(this);
+       }
+
+       /**
+        * @see org.eclipse.ui.model.IWorkbenchAdapter#getChildren(Object)
+        */
+       public Object[] getChildren(Object o)
+       {
+               Object[] result = new Object[children.size()];
+               return children.toArray(result);
+       }
+
+       /**
+        * @see org.eclipse.ui.model.IWorkbenchAdapter#getParent(Object)
+        */
+       public Object getParent(Object o)
+       {
+               return null;
+       }
+       
+       /**
+        * 
+        * @return A category enumeration for sub-types.
+        */
+       abstract public int category();
+
+       /**
+        * @return
+        */
+       public String getName()
+       {
+               return name;
+       }
+
+       /**
+        * @return
+        */
+       public int getOffset()
+       {
+               return offset;
+       }
+
+       /**
+        * @return
+        */
+       public JSElement getParent()
+       {
+               return parent;
+       }
+
+       /**
+        * @param element
+        */
+       protected void setParent(JSElement element)
+       {
+               parent = element;
+       }
+
+       /**
+        * @param anElement
+        * @return
+        */
+       public boolean sharesParentWith(JSElement anElement)
+       {
+               if(parent == null) {
+                       return anElement.getParent() == null;
+               }
+               
+               return parent.equals(anElement.getParent());
+       }
+
+       /**
+        * @param anElement
+        * @return
+        */
+       public boolean equals(JSElement anElement)
+       {
+               return sharesParentWith(anElement) && name.equals(anElement.getName());
+       }
+
+       /**
+        * @return Returns the file.
+        */
+       public IFile getFile() {
+               return file;
+       }
+
+       /**
+        * @param file The file to set.
+        */
+       protected void setFile(IFile file) {
+               this.file = file;
+       }
+
+}
\ No newline at end of file
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSElementCategories.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSElementCategories.java
new file mode 100644 (file)
index 0000000..0b0b9d9
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Created on May 20, 2003
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.2  2003/05/30 20:53:09  agfitzp
+ * 0.0.2 : Outlining is now done as the user types. Some other bug fixes.
+ *
+ *========================================================================
+ */
+package net.sourceforge.phpeclipse.js.core.model;
+
+/**
+ * @author fitzpata
+ *
+ */
+public interface JSElementCategories
+{
+       static final int CLASS = 1;
+       static final int FUNCTION = 2;
+       static final int VARIABLE = 3;
+       static final int CLASS_VARIABLE = 4;
+       static final int INSTANCE_VARIABLE = 5;
+       static final int CLASS_METHOD = 6;
+       static final int INSTANCE_METHOD = 7;
+}
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSElementList.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSElementList.java
new file mode 100644 (file)
index 0000000..e20096d
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * $RCSfile: JSElementList.java,v $
+ *
+ * Copyright 2002
+ * CH-1700 Fribourg, Switzerland
+ * All rights reserved.
+ *
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.2  2004/02/27 18:28:10  cell
+ * Make model elements platform objects so they are automatically adapted
+ *
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.1  2003/05/30 20:53:08  agfitzp
+ * 0.0.2 : Outlining is now done as the user types. Some other bug fixes.
+ *
+ * Revision 1.1  2003/05/28 15:17:11  agfitzp
+ * net.sourceforge.phpeclipse.js.core 0.0.1 code base
+ *
+ *========================================================================
+*/
+
+package net.sourceforge.phpeclipse.js.core.model;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.PlatformObject;
+
+/**
+ * DOCUMENT ME!
+ * 
+ * @author Addi 
+ */
+public class JSElementList extends PlatformObject
+{
+       protected List children = new ArrayList();
+
+       /**
+        * Creates a new adaptable list with the given children.
+        */
+       public JSElementList()
+       {
+       }
+
+       /**
+        * Creates a new adaptable list with the given children.
+        * @param newChildren
+        */
+       public JSElementList(JSElement[] newChildren)
+       {
+               for (int i = 0; i < newChildren.length; i++)
+               {
+                       children.add(newChildren[i]);
+               }
+       }
+
+       /**
+        * Creates a new adaptable list with the given children.
+        * @param newChildren
+        */
+       public JSElementList(List newChildren)
+       {
+               for (int i = 0; i < newChildren.size(); i++)
+               {
+                       children.add(newChildren.get(i));
+               }
+       }
+
+       /**
+        * Adds all the adaptable objects in the given enumeration to this list. Returns this list.
+        * @param iterator
+        * 
+        * @return
+        */
+       public JSElementList add(Iterator iterator)
+       {
+               while (iterator.hasNext())
+               {
+                       add((JSElement) iterator.next());
+               }
+
+               return this;
+       }
+
+       /**
+        * Adds the given adaptable object to this list. Returns this list.
+        * @param adaptable
+        * 
+        * @return
+        */
+       public JSElementList add(JSElement anElement)
+       {
+               children.add(anElement);
+
+               return this;
+       }
+
+       /**
+        * Returns the elements in this list.
+        * @return
+        */
+       public Object[] getChildren()
+       {
+               return children.toArray();
+       }
+
+       /**
+        *
+        *
+        * @param o 
+        *
+        * @return 
+        */
+       public Object[] getChildren(Object o)
+       {
+               return children.toArray();
+       }
+
+       /**
+        *
+        *
+        * @param object 
+        *
+        * @return 
+        */
+       public String getLabel(Object object)
+       {
+               return object == null ? "" : object.toString();
+       }
+
+       /**
+        *
+        *
+        * @param object 
+        *
+        * @return 
+        */
+       public Object getParent(Object object)
+       {
+               return null;
+       }
+
+       /**
+        * Removes the given adaptable object from this list.
+        * @param adaptable
+        */
+       public void remove(JSElement anElement)
+       {
+               children.remove(anElement);
+       }
+
+       /**
+        * Returns the number of items in the list
+        * @return
+        */
+       public int size()
+       {
+               return children.size();
+       }
+
+       public JSElement findEquivilent(JSElement anElement)
+       {
+               for(int i = 0; i < size();i++)
+               {
+                       JSElement aCandidate = (JSElement) children.get(i);
+                       if(anElement.equals(aCandidate))
+                       {
+                               return aCandidate;
+                       }
+               }
+               
+               
+               return null;
+       }
+
+       public JSElement get(int index)
+       {
+               if(index >= size())
+               {
+                       return null;
+               }
+               return (JSElement) children.get(index);
+       }
+
+       /**
+        * @return
+        */
+       public IAdaptable asAdaptable() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+}
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSFunctionElement.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSFunctionElement.java
new file mode 100644 (file)
index 0000000..0169913
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Created on May 15, 2003
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.2  2003/05/30 20:53:09  agfitzp
+ * 0.0.2 : Outlining is now done as the user types. Some other bug fixes.
+ *
+ *========================================================================
+ */
+package net.sourceforge.phpeclipse.js.core.model;
+
+import org.eclipse.core.resources.IFile;
+
+/**
+ * @author fitzpata
+ */
+public class JSFunctionElement extends JSElement
+{
+
+       protected String arguments;
+       /**
+        * @param aName
+        * @param offset
+        * @param length
+        */
+       public JSFunctionElement(IFile aFile, String aName, String argumentString, int offset, int length)
+       {
+               super(aFile, aName, offset, length);
+               arguments = argumentString;
+       }
+
+       /**
+        * Method declared on IWorkbenchAdapter
+        * @param o
+        * 
+        * @return
+        */
+       public String getLabel(Object o)
+       {
+               String firstPart = name;
+               if(firstPart.length() <= 0){
+                       firstPart =  "<anonymous>";
+               }
+               
+               return firstPart + arguments;
+       }
+
+       public int category()
+       {
+               return FUNCTION;
+       }
+
+       /**
+        * @return
+        */
+       public String getArguments()
+       {
+               return arguments;
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSGlobalVariableElement.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSGlobalVariableElement.java
new file mode 100644 (file)
index 0000000..5a37558
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Created on May 20, 2003
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.2  2003/05/30 20:53:09  agfitzp
+ * 0.0.2 : Outlining is now done as the user types. Some other bug fixes.
+ *
+ *========================================================================
+ */
+package net.sourceforge.phpeclipse.js.core.model;
+
+import org.eclipse.core.resources.IFile;
+
+/**
+ * @author fitzpata
+ *
+ */
+public class JSGlobalVariableElement extends JSElement
+{
+
+       /**
+        * @param aName
+        * @param offset
+        * @param length
+        */
+       public JSGlobalVariableElement(IFile aFile, String aName, int offset, int length)
+       {
+               super(aFile, aName, offset, length);
+       }
+
+       public int category()
+       {
+               return VARIABLE;        
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSInstanceMethodElement.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSInstanceMethodElement.java
new file mode 100644 (file)
index 0000000..3b74f05
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Created on May 20, 2003
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.2  2003/05/30 20:53:09  agfitzp
+ * 0.0.2 : Outlining is now done as the user types. Some other bug fixes.
+ *
+ *========================================================================
+ */
+package net.sourceforge.phpeclipse.js.core.model;
+
+import org.eclipse.core.resources.IFile;
+
+/**
+ * @author fitzpata
+ *
+ */
+public class JSInstanceMethodElement extends JSFunctionElement
+{
+       public JSInstanceMethodElement(IFile aFile, String aName, String argumentString, int offset, int length)
+       {
+               super(aFile, aName, argumentString, offset, length);
+       }
+       
+       public int category()
+       {
+               return INSTANCE_METHOD; 
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSInstanceVariableElement.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/model/JSInstanceVariableElement.java
new file mode 100644 (file)
index 0000000..a1747dc
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Created on May 20, 2003
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.2  2003/05/30 20:53:09  agfitzp
+ * 0.0.2 : Outlining is now done as the user types. Some other bug fixes.
+ *
+ *========================================================================
+ */
+package net.sourceforge.phpeclipse.js.core.model;
+
+import org.eclipse.core.resources.IFile;
+
+/**
+ * @author fitzpata
+ *
+ */
+public class JSInstanceVariableElement extends JSElement
+{
+
+       /**
+        * @param aName
+        * @param offset
+        * @param length
+        */
+       public JSInstanceVariableElement(IFile aFile, String aName, int offset, int length)
+       {
+               super(aFile, aName, offset, length);
+       }
+
+       public int category()
+       {
+               return INSTANCE_VARIABLE;       
+       }
+
+}
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSParser.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSParser.java
new file mode 100644 (file)
index 0000000..7796b4a
--- /dev/null
@@ -0,0 +1,926 @@
+/*
+ * $RCSfile: JSParser.java,v $
+ *
+ * Copyright 2002
+ * CH-1700 Fribourg, Switzerland
+ * All rights reserved.
+ *
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.6  2003/12/10 20:19:16  agfitzp
+ * 3.0 port
+ *
+ * Revision 1.5  2003/06/21 03:48:51  agfitzp
+ * fixed global variables as functions bug
+ * fixed length calculation of instance variables
+ * Automatic outlining is now a preference
+ *
+ * Revision 1.4  2003/05/30 20:53:09  agfitzp
+ * 0.0.2 : Outlining is now done as the user types. Some other bug fixes.
+ *
+ * Revision 1.3  2003/05/28 20:47:58  agfitzp
+ * Outline the document, not the file.
+ *
+ * Revision 1.2  2003/05/28 15:20:00  agfitzp
+ * Trivial change to test CVS commit
+ *
+ * Revision 1.1  2003/05/28 15:17:12  agfitzp
+ * net.sourceforge.phpeclipse.js.core 0.0.1 code base
+ *
+ *========================================================================
+*/
+
+package net.sourceforge.phpeclipse.js.core.parser;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+import net.sourceforge.phpeclipse.js.core.model.*;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.IToken;
+
+/**
+ * DOCUMENT ME!
+ * 
+ * @author Addi 
+ */
+public class JSParser
+{
+
+       public static final String FUNCTION = "function";
+
+       /**
+        * line separator
+        */
+       public static final String LINE_SEPARATOR = System.getProperty("line.separator");
+
+       /**
+        * Array of system types to ignore.
+        */
+       private static String[] systemClassNames= {"Array","String"};
+
+
+       protected HashMap systemClassMap = new HashMap();
+         
+       protected IFile sourceFile;
+       protected IDocument sourceDocument;
+       protected HashMap functions = new HashMap();
+       protected HashMap classes = new HashMap();
+       protected HashMap globalVariables = new HashMap();
+       protected List elementList = new LinkedList();
+       protected JSSyntaxScanner scanner = new JSSyntaxScanner();
+
+       /**
+        * Constructor for JSParser.
+        */
+       public JSParser()
+       {
+               super();
+
+               int i;
+
+               for(i = 0;i < systemClassNames.length; i++)
+               {
+                       String aName = systemClassNames[i];
+                       systemClassMap.put(aName, aName);                
+               }
+       }
+
+       /**
+        * Returns a string containing the contents of the given file.  Returns an empty string if there
+        * were any errors reading the file.
+        * @param file
+        * 
+        * @return
+        */
+       protected static String getText(IFile file)
+       {
+               try
+               {
+                       InputStream in = file.getContents();
+                       return streamToString(in);
+               } catch (Exception e)
+               {
+                       e.printStackTrace();
+               }
+               return "";
+       }
+
+       protected static String streamToString(InputStream in) throws IOException
+       {
+               ByteArrayOutputStream out = new ByteArrayOutputStream();
+               byte[] buf = new byte[1024];
+               int read = in.read(buf);
+
+               while (read > 0)
+               {
+                       out.write(buf, 0, read);
+                       read = in.read(buf);
+               }
+
+               return out.toString();
+       }
+
+       /**
+        * Skips ahead and finds next non-whitespace token.
+        *
+        */
+       public IToken nextNonWhitespaceToken()
+       {
+               IToken aToken = scanner.nextToken();
+
+               while (!aToken.isEOF() && aToken.isWhitespace())
+               {
+                       aToken = scanner.nextToken();
+               }
+
+               return aToken;
+       }
+
+       /**
+        * Parses the input given by the argument.
+        * 
+        * @param file  the element containing the input text
+        * 
+        * @return an element collection representing the parsed input
+        */
+       public List parse(IFile file)
+       {
+               this.sourceFile = file;
+               return parse(new Document(getText(file)));
+       }
+
+       /**
+        * Parses the input given by the argument.
+        * 
+        * @param aSourceDocument  the element containing the input text
+        * 
+        * @return an element collection representing the parsed input
+        */
+       public List parse(IDocument aSourceDocument)
+       {
+               sourceDocument = aSourceDocument;
+               
+               scanner.setRange(sourceDocument, 0, sourceDocument.getLength());
+               IToken token = scanner.nextToken();
+               while (!token.isEOF())
+               {
+                       int offset = scanner.getTokenOffset();
+                       int length = scanner.getTokenLength();
+                       String expression = getExpression(offset, length);
+               
+                       if (token.equals(JSSyntaxScanner.TOKEN_FUNCTION))
+                       {
+                               addFunction(expression, offset, length);
+                       }
+               
+                       if (token.equals(JSSyntaxScanner.TOKEN_DEFAULT))
+                       {
+                               //We need to check if the token is already a function or class
+                               if (functions.containsKey(expression) || classes.containsKey(expression))
+                               {
+                                       token = nextNonWhitespaceToken();
+                                       if (token.equals(JSSyntaxScanner.TOKEN_MEMBER))
+                                       {
+                                               detectInstanceMethod(offset, expression);
+                                       } else
+                                       {
+                                               detectClassMethod(token, offset, expression);
+                                       }
+                               } else
+                               {
+                                       if (expression.equals("var"))
+                                       {
+                                               detectGlobalVariable();
+                                       }
+                               }
+                       }
+                       token = scanner.nextToken();
+               }
+               return elementList;
+       }
+
+       private void addFunction(String expression, int offset, int length)
+       {
+               String functionSignature = getNaked(expression);
+               int braceOffset = functionSignature.indexOf("(");
+               String functionName = functionSignature.substring(0, braceOffset).trim();
+               String arguments =
+                       functionSignature.substring(functionSignature.indexOf("("), functionSignature.indexOf(")") + 1);
+
+               if (functionName.indexOf(".") >= 0)
+               {
+                       //If the function signature includes .prototype. then it's a member.
+                       if (functionName.indexOf(".prototype.") >= 0)
+                       {
+                               String className = functionName.substring(0, functionName.indexOf("."));
+                               String memberName = functionName.substring(functionName.lastIndexOf(".") + 1);
+                               JSInstanceMethodElement aMethod =
+                                       this.addInstanceMethod(memberName, className, arguments, offset, offset, length);
+                               detectInstanceMethodContext(className, aMethod);
+                       } else
+                       {
+                               String className = functionName.substring(0, functionName.indexOf("."));
+                               if (functions.containsKey(className) || classes.containsKey(className))
+                               {
+                                       String memberName = functionName.substring(functionName.lastIndexOf(".") + 1);
+                                       JSFunctionElement aMethod =
+                                               this.addClassMethod(memberName, className, arguments, offset, offset, length);
+                               }
+                       }
+               } else
+               {
+                       if(! functions.containsKey(functionName))
+                       {
+                               JSFunctionElement aFunction = new JSFunctionElement(this.sourceFile, functionName, arguments, offset, length);
+       
+                               elementList.add(aFunction);
+                               functions.put(functionName, aFunction);
+       
+                               detectFunctionContext(aFunction);
+                       }
+               }
+       }
+
+       /**
+        *
+        */     
+       private void checkForSpecialGlobalTypes(JSGlobalVariableElement aVariable)
+       {
+               IToken token = nextNonWhitespaceToken();
+               if (!token.isEOF())
+               {
+                       if(!checkForDynamicClass(aVariable, token))
+                       {
+                               checkForAnonymousFunction(aVariable, token);
+                       }
+               }
+       }
+
+       /**
+        *
+        */     
+       private boolean checkForDynamicClass(JSGlobalVariableElement aVariable, IToken rhsToken)
+       {
+               if (rhsToken.equals(JSSyntaxScanner.TOKEN_DEFAULT))
+               {
+                       int offset = scanner.getTokenOffset();
+                       int length = scanner.getTokenLength();
+                       
+                       String expression = getExpression(offset, length);
+
+                       if (expression.equals("new"))
+                       {
+                               IToken token = nextNonWhitespaceToken();
+                               if (!token.isEOF())
+                               {
+                                       if (token.equals(JSSyntaxScanner.TOKEN_DEFAULT))
+                                       {
+                                               offset = scanner.getTokenOffset();
+                                               length = scanner.getTokenLength();
+                                               expression = getExpression(offset, length);
+                                                                                                                                               
+                                               if(! isSystemClass(expression))
+                                               {
+                                                       JSClassElement aClass = findOrCreateClass(aVariable.getName());
+                                                       if(aClass != null)
+                                                       {
+                                                               //Tell the class it's dynamically declared: what we will parse as class methods & vars are really instance methods & vars
+                                                               aClass.setPrototype(true);
+                                                               
+                                                               return true;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+               return false;   
+       }
+
+       /**
+        *
+        */     
+       private boolean checkForAnonymousFunction(JSGlobalVariableElement aVariable, IToken rhsToken)
+       {
+               if (rhsToken.equals(JSSyntaxScanner.TOKEN_FUNCTION))
+               {
+                       String functionName = aVariable.getName();
+                       int offset = aVariable.getOffset();
+                       int length = aVariable.getLength();
+                       
+                       int functionOffset = scanner.getTokenOffset();
+                       int functionLength = scanner.getTokenLength();
+                       String functionSignature =
+                               getExpression(functionOffset, functionLength);
+                       String arguments = getArgumentString(functionSignature);
+
+                       JSFunctionElement aFunction = new JSFunctionElement(this.sourceFile, functionName, arguments, offset, functionOffset - offset + functionLength);
+
+                       elementList.add(aFunction);
+                       functions.put(functionName, aFunction);
+
+                       elementList.remove(aVariable);
+                       globalVariables.remove(functionName);
+
+                       detectFunctionContext(aFunction);
+                       
+                       return true;
+               }
+               
+               return false;
+       }               
+
+       /**
+        *
+        */     
+       private String getExpression(int offset, int length)
+       {
+               String expression;
+               try {
+                       expression = sourceDocument.get(offset, length);//sourceBuffer.substring(offset, offset + length);
+               } catch(BadLocationException e)
+               {
+                       expression = "";
+               }
+               return expression;
+       }
+
+       /**
+        *
+        */     
+       private void detectGlobalVariable()
+       {
+               IToken token;
+               int length;
+               int offset;
+
+               token = nextNonWhitespaceToken();
+               if (!token.isEOF())
+               {
+                       if (token.equals(JSSyntaxScanner.TOKEN_DEFAULT))
+                       {
+                               int varOffset = scanner.getTokenOffset();
+                               length = scanner.getTokenLength();
+                               String variableName = getExpression(varOffset, length);
+
+                               token = nextNonWhitespaceToken();
+                               if (!token.isEOF())
+                               {
+                                       offset = scanner.getTokenOffset();
+                                       length = scanner.getTokenLength();
+                                       String expression = getExpression(offset, length);
+                                       if (expression.equals("="))
+                                       {
+                                               JSGlobalVariableElement aVariable = addGlobalVariable(variableName, varOffset);
+                                               checkForSpecialGlobalTypes(aVariable);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       private void detectClassMethod(IToken token, int classOffset, String className)
+       {
+               int offset = scanner.getTokenOffset();
+               int length = scanner.getTokenLength();
+               String expression = getExpression(offset, length);
+               
+               if (expression.equals("."))
+               {
+
+                       token = nextNonWhitespaceToken();
+                       if (!token.isEOF())
+                       {
+                               offset = scanner.getTokenOffset();
+                               length = scanner.getTokenLength();
+                               String memberName = getExpression(offset, length);
+               
+                               token = nextNonWhitespaceToken();
+                               if (!token.isEOF())
+                               {
+                                       offset = scanner.getTokenOffset();
+                                       length = scanner.getTokenLength();
+                                       expression = getExpression(offset, length);
+                                       if (expression.equals("="))
+                                       {
+       
+                                               token = nextNonWhitespaceToken();
+                                               int tokenOffset = scanner.getTokenOffset();
+                                               int tokenLength = scanner.getTokenLength();
+       
+                                               if (token.equals(JSSyntaxScanner.TOKEN_FUNCTION))
+                                               {
+                                                       String functionSignature = getExpression(tokenOffset, tokenLength);
+                                                       String arguments = getArgumentString(functionSignature);
+       
+                                                       JSFunctionElement aMethod =
+                                                               addClassMethod(memberName, className, arguments, classOffset, tokenOffset, tokenLength);
+                                                       
+       
+                                               } else
+                                               {
+                                                       addClassVariable(memberName, className, classOffset);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       private String getArgumentString(String functionSignature)
+       {
+               return functionSignature.substring(
+                               functionSignature.indexOf("("),
+                               functionSignature.indexOf(")") + 1);
+       }
+
+       private void detectInstanceMethod(int classOffset, String className)
+       {
+               String expression;
+               IToken token;
+               int length;
+               int offset;
+
+               token = nextNonWhitespaceToken();
+               if (!token.isEOF())
+               {
+                       offset = scanner.getTokenOffset();
+                       length = scanner.getTokenLength();
+                       expression = getExpression(offset, length);
+
+                       if (expression.equals("."))
+                       {
+
+                               token = nextNonWhitespaceToken();
+                               if (!token.isEOF())
+                               {
+                                       offset = scanner.getTokenOffset();
+                                       length = scanner.getTokenLength();
+                                       String memberName = getExpression(offset, length);
+
+                                       token = nextNonWhitespaceToken();
+                                       if (!token.isEOF())
+                                       {
+                                               offset = scanner.getTokenOffset();
+                                               length = scanner.getTokenLength();
+                                               expression = getExpression(offset, length);
+                                               if (expression.equals("="))
+                                               {
+                                                       token = nextNonWhitespaceToken();
+                                                       if (token.equals(JSSyntaxScanner.TOKEN_FUNCTION))
+                                                       {
+                                                               int functionOffset = scanner.getTokenOffset();
+                                                               int functionLength = scanner.getTokenLength();
+                                                               String functionSignature =
+                                                                       getExpression(functionOffset, functionLength);
+                                                               String arguments = getArgumentString(functionSignature);
+       
+                                                               JSInstanceMethodElement aMethod =
+                                                                       addInstanceMethod(
+                                                                               memberName,
+                                                                               className,
+                                                                               arguments,
+                                                                               classOffset,
+                                                                               functionOffset,
+                                                                               functionLength);
+       
+                                                               detectInstanceMethodContext(className, aMethod);
+       
+                                                       } else
+                                                       {
+                                                               addInstanceVariable(memberName, className, classOffset, (".prototype.").length());
+                                                       }
+       
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       private void parseInstanceMethodContext(String className, JSFunctionElement aMethod)
+       {
+               IToken token;
+
+               token = nextNonWhitespaceToken();
+               while (!token.isEOF())
+               {
+                       int offset = scanner.getTokenOffset();
+                       int length = scanner.getTokenLength();
+                       String expression = getExpression(offset, length);
+
+                       //                      if (token.equals(JSSyntaxScanner.TOKEN_END_CONTEXT))
+                       if (expression.equals("}"))
+                       {
+                               return;
+                       } else if (expression.equals("{"))
+                       {
+                               parseInstanceMethodContext(className, aMethod);
+                       } else if (token.equals(JSSyntaxScanner.TOKEN_DEFAULT))
+                       {
+                               if (expression.equals("this"))
+                               {
+                                       handleThisReference(className, offset);
+                               }
+                       }
+
+                       token = nextNonWhitespaceToken();
+               }
+       }
+
+       private void detectInstanceMethodContext(String className, JSFunctionElement aMethod)
+       {
+               IToken token;
+
+               token = nextNonWhitespaceToken();
+               while (!token.isEOF())
+               {
+                       int offset = scanner.getTokenOffset();
+                       int length = scanner.getTokenLength();
+                       String expression = getExpression(offset, length);
+
+                       //                      if (token.equals(JSSyntaxScanner.TOKEN_BEGIN_CONTEXT))
+                       if (expression.equals("{"))
+                       {
+                               parseInstanceMethodContext(className, aMethod);
+                               return;
+                       }
+
+                       token = nextNonWhitespaceToken();
+               }
+       }
+
+       private void parseClassMethodContext(JSFunctionElement aMethod)
+       {
+               IToken token;
+
+               token = nextNonWhitespaceToken();
+               while (!token.isEOF())
+               {
+                       int offset = scanner.getTokenOffset();
+                       int length = scanner.getTokenLength();
+                       String expression = getExpression(offset, length);
+
+                       if (expression.equals("}"))
+                       {
+                               return;
+                       } else if (expression.equals("{"))
+                       {
+                               parseClassMethodContext(aMethod);
+                       }
+
+                       token = nextNonWhitespaceToken();
+               }
+       }
+
+       private void detectClassMethodContext(JSFunctionElement aMethod)
+       {
+               IToken token = nextNonWhitespaceToken();
+               while (!token.isEOF())
+               {
+                       int offset = scanner.getTokenOffset();
+                       int length = scanner.getTokenLength();
+                       String expression = getExpression(offset, length);
+
+                       if (expression.equals("{"))
+                       {
+                               parseClassMethodContext(aMethod);
+                               return;
+                       }
+
+                       token = nextNonWhitespaceToken();
+               }
+       }
+
+       private void handleThisReference(String className, int expressionStart)
+       {
+               IToken token = nextNonWhitespaceToken();
+               if (!token.isEOF())
+               {
+                       int offset = scanner.getTokenOffset();
+                       int length = scanner.getTokenLength();
+       
+                       String expression = getExpression(offset, length);
+       
+                       if(expression.equals("."))
+                       {
+                               token = nextNonWhitespaceToken();
+                               if (!token.isEOF())
+                               {
+                                       int memberStart = scanner.getTokenOffset();
+                                       length = scanner.getTokenLength();
+       
+                                       String memberName = getExpression(memberStart, length);
+       
+                                       token = nextNonWhitespaceToken();
+                                       if (!token.isEOF())
+                                       {
+                                               offset = scanner.getTokenOffset();
+                                               length = scanner.getTokenLength();
+                                               expression = getExpression(offset, length);
+               
+                                               if (expression.equals("="))
+                                               {
+                                                       addInstanceVariable(memberName, className, expressionStart, 1 + 4 - className.length());
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       private void parseFunctionContext(JSFunctionElement aFunction)
+       {
+               IToken token;
+
+               token = nextNonWhitespaceToken();
+               while (!token.isEOF())
+               {
+                       int offset = scanner.getTokenOffset();
+                       int length = scanner.getTokenLength();
+                       String expression = getExpression(offset, length);
+
+                       if (expression.equals("}"))
+                       {
+                               return;
+                       } else if (expression.equals("{"))
+                       {
+                               parseFunctionContext(aFunction);
+                       } else if (token.equals(JSSyntaxScanner.TOKEN_DEFAULT))
+                       {
+                               if (expression.equals("this"))
+                               {
+                                       handleThisReference(aFunction.getName(), offset);
+                               }
+                       }
+
+                       token = nextNonWhitespaceToken();
+               }
+       }
+
+       private void detectFunctionContext(JSFunctionElement aFunction)
+       {
+               IToken token = nextNonWhitespaceToken();
+               while (!token.isEOF())
+               {
+                       int offset = scanner.getTokenOffset();
+                       int length = scanner.getTokenLength();
+                       String expression = getExpression(offset, length);
+
+                       if (expression.equals("{"))
+                       {
+                               parseFunctionContext(aFunction);
+                               return;
+                       }
+
+                       token = nextNonWhitespaceToken();
+               }
+       }
+
+       private JSInstanceMethodElement addInstanceMethod(
+               String memberName,
+               String className,
+               String arguments,
+               int classOffset,
+               int functionOffset,
+               int functionLength)
+       {
+               int signatureLength = functionOffset - classOffset + functionLength;
+               JSInstanceMethodElement aMethod =
+                       new JSInstanceMethodElement(this.sourceFile, memberName, arguments, classOffset, signatureLength);
+
+               findOrCreateClass(className).addChildElement(aMethod);
+
+               return aMethod;
+       }
+
+       private JSFunctionElement addClassMethod(
+               String memberName,
+               String className,
+               String arguments,
+               int classOffset,
+               int functionOffset,
+               int functionLength)
+       {
+               JSClassElement aClass = findOrCreateClass(className); 
+               int signatureLength = functionOffset - classOffset + functionLength;
+               JSFunctionElement aMethod;
+               
+               if(aClass.isPrototype()) {
+                       aMethod = new JSInstanceMethodElement(this.sourceFile, memberName, arguments, classOffset, signatureLength);
+
+                       aClass.addChildElement(aMethod);
+                       detectInstanceMethodContext(className, aMethod);
+               } else {
+                       aMethod = new JSClassMethodElement(this.sourceFile, memberName, arguments, classOffset, signatureLength);
+
+                       aClass.addChildElement(aMethod);
+                       detectClassMethodContext(aMethod);
+               }
+
+               return aMethod;
+       }
+
+       /**
+        * @param memberName
+        * @param className
+        * @param classOffset
+        * @return
+        */
+       private JSElement addClassVariable(String memberName, String className, int classOffset)
+       {
+               //One extra char for "."
+               JSElement aVariable;
+               JSClassElement aClass = findOrCreateClass(className);
+               
+               if(aClass.isPrototype())
+               {
+                       aVariable =     new JSInstanceVariableElement(this.sourceFile, memberName, classOffset, className.length() + memberName.length() + 1);
+
+               } else {
+                       aVariable =     new JSClassVariableElement(this.sourceFile, memberName, classOffset, className.length() + memberName.length() + 1);
+               }
+               aClass.addChildElement(aVariable);
+
+               return aVariable;
+       }
+
+       private JSInstanceVariableElement addInstanceVariable(
+               String memberName,
+               String className,
+               int classOffset,
+               int paddingWidth)
+       {
+               //11 extra chars for ".prototype."
+               JSInstanceVariableElement aVariable =
+                       new JSInstanceVariableElement(
+                               this.sourceFile, 
+                               memberName,
+                               classOffset,
+                               className.length() + memberName.length() + paddingWidth);
+
+               findOrCreateClass(className).addChildElement(aVariable);
+
+               return aVariable;
+       }
+
+       private JSGlobalVariableElement addGlobalVariable(String variableName, int offset)
+       {
+               JSGlobalVariableElement aVariable;
+               if (!globalVariables.containsKey(variableName))
+               {
+                       aVariable = new JSGlobalVariableElement(this.sourceFile, variableName, offset, variableName.length());
+
+                       elementList.add(aVariable);
+                       globalVariables.put(variableName, aVariable);
+               } else
+               {
+                       aVariable = (JSGlobalVariableElement) classes.get(variableName);
+               }
+
+               return aVariable;
+       }
+
+       private JSClassElement findOrCreateClass(String className)
+       {
+               JSClassElement aClass = null;
+               if (!classes.containsKey(className))
+               {
+                       if(functions.containsKey(className))
+                       {
+                               //if we're creating a class from an existing function we must
+                               //migrate the existing function to become a constructor in the class.
+                               JSFunctionElement constructor = (JSFunctionElement) functions.get(className);
+       
+                               aClass = new JSClassElement(this.sourceFile, className, constructor.getStart(), constructor.getLength());
+                               aClass.addChildElement(constructor);
+       
+                               elementList.remove(constructor);
+                               elementList.add(aClass);
+                               classes.put(className, aClass);
+                       } else if(globalVariables.containsKey(className))
+                       {
+                               //if we're creating a class from an existing global variable we must
+                               //migrate the existing function to become a constructor in the class.
+                               JSGlobalVariableElement aVariable = (JSGlobalVariableElement) globalVariables.get(className);
+
+                               aClass = new JSClassElement(this.sourceFile, className, aVariable.getStart(), aVariable.getLength());
+
+                               elementList.remove(aVariable);
+                               elementList.add(aClass);
+                               classes.put(className, aClass);                         
+                               globalVariables.remove(className);
+                       } else {
+                               //The final case is if we have no idea where this class came from, but shouldn't be ignored.
+                               aClass = new JSClassElement(this.sourceFile, className, 0, 0);
+
+                               elementList.add(aClass);
+                               classes.put(className, aClass);                         
+                       }
+               } else
+               {
+                       aClass = (JSClassElement) classes.get(className);
+               }
+
+               return aClass;
+       }
+       
+       public boolean isSystemClass(String aClassName)
+       {
+               return systemClassMap.containsKey(aClassName);
+       }
+
+       /**
+        * Method getNaked.
+        * @param funcName
+        */
+       private String getNaked(String funcName)
+       {
+               if (funcName == null)
+               {
+                       return null;
+               }
+
+               funcName = funcName.trim().substring(FUNCTION.length()).trim();
+               funcName = replaceInString(funcName.trim(), LINE_SEPARATOR, "");
+
+               StringBuffer strBuf = new StringBuffer("");
+               int len = funcName.length();
+               boolean wasSpace = false;
+               for (int i = 0; i < len; i++)
+               {
+                       char ch = funcName.charAt(i);
+                       if (ch == ' ')
+                       {
+                               wasSpace = true;
+                       } else // not space
+                               {
+                               if (wasSpace)
+                               {
+                                       strBuf.append(' ');
+                               }
+                               strBuf.append(ch);
+                               wasSpace = false;
+                       }
+               }
+               return strBuf.toString();
+       }
+
+       /**
+        * replace in a string a string sequence with another string sequence
+        */
+       public static String replaceInString(String source, String whatBefore, String whatAfter)
+       {
+               if (null == source || source.length() == 0)
+               {
+                       return source;
+               }
+               int beforeLen = whatBefore.length();
+               if (beforeLen == 0)
+               {
+                       return source;
+               }
+               StringBuffer result = new StringBuffer("");
+               int lastIndex = 0;
+               int index = source.indexOf(whatBefore, lastIndex);
+               while (index >= 0)
+               {
+                       result.append(source.substring(lastIndex, index));
+                       result.append(whatAfter);
+                       lastIndex = index + beforeLen;
+
+                       // get next
+                       index = source.indexOf(whatBefore, lastIndex);
+               }
+               result.append(source.substring(lastIndex));
+               return result.toString();
+       }
+
+       /**
+        * @return Returns the elementList.
+        */
+       public List getElementList() {
+               return elementList;
+       }
+
+}
\ No newline at end of file
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSPartitionScanner.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSPartitionScanner.java
new file mode 100644 (file)
index 0000000..f5a05ae
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * $RCSfile: JSPartitionScanner.java,v $
+ *
+ * Copyright 2002
+ * CH-1700 Fribourg, Switzerland
+ * All rights reserved.
+ *
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.3  2003/05/30 20:53:09  agfitzp
+ * 0.0.2 : Outlining is now done as the user types. Some other bug fixes.
+ *
+ * Revision 1.2  2003/05/28 20:47:58  agfitzp
+ * Outline the document, not the file.
+ *
+ * Revision 1.1  2003/05/28 15:17:12  agfitzp
+ * net.sourceforge.phpeclipse.js.core 0.0.1 code base
+ *
+ *========================================================================
+*/
+
+package net.sourceforge.phpeclipse.js.core.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+//import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.*;
+
+/**
+ * 
+ *
+ * @author $Author: jsurfer $, $Date: 2004-09-02 18:14:38 $
+ *
+ * @version $Revision: 1.1 $
+ */
+public class JSPartitionScanner extends RuleBasedPartitionScanner {
+       public final static String JS_DEFAULT = "__js_default";
+       public final static String JS_COMMENT = "__js_comment";
+       public final static String JS_KEYWORD = "__js_keyword";
+       public final static String JS_STRING = "__js_string";
+
+       public final static IToken TOKEN_STRING = new Token(JS_STRING);
+       public final static IToken TOKEN_COMMENT = new Token(JS_COMMENT);
+       public final static IToken TOKEN_DEFAULT = new Token(JS_DEFAULT);
+       public final static IToken TOKEN_KEYWORD = new Token(JS_KEYWORD);
+
+       /**
+        * Array of keyword token strings.
+        */
+       private static String[] keywordTokens= {
+               "break", 
+               "case", "catch", "continue", 
+               "default", "do", 
+               "else", 
+               "for", "function",
+               "goto", 
+               "if", "in", 
+               "new", 
+               "return",
+               "switch",
+               "this", "throw", "try",
+               "var", "void",
+               "while", "with"
+       };
+
+       /**
+        * Array of constant token strings.
+        */
+       private static String[] constantTokens= { "false", "null", "true" };
+
+
+       /**
+        * Creates a new JSPartitionScanner object.
+        */
+       public JSPartitionScanner() {
+               List rules = new ArrayList();
+
+               rules.add(new MultiLineRule("/*", "*/", TOKEN_COMMENT));
+               rules.add(new SingleLineRule("//", "", TOKEN_COMMENT));
+               rules.add(new SingleLineRule("\"", "\"", TOKEN_STRING, '\\'));
+               rules.add(new SingleLineRule("'", "'", TOKEN_STRING, '\\'));
+               
+               PredicateWordRule keywordRule = new PredicateWordRule(new JSWordDetector(), TOKEN_DEFAULT, keywordTokens, TOKEN_KEYWORD);
+               keywordRule.addWords(constantTokens, TOKEN_KEYWORD);
+               rules.add(keywordRule);
+               
+               setRuleList(rules);
+       }
+
+
+       private void setRuleList(List rules)
+       {
+               IPredicateRule[] result = new IPredicateRule[rules.size()];
+               rules.toArray(result);
+               setPredicateRules(result);
+       }
+}
\ No newline at end of file
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSReferenceDetector.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSReferenceDetector.java
new file mode 100644 (file)
index 0000000..d8be925
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Created on May 14, 2003
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.2  2003/05/30 20:53:09  agfitzp
+ * 0.0.2 : Outlining is now done as the user types. Some other bug fixes.
+ *
+ *========================================================================
+ */
+package net.sourceforge.phpeclipse.js.core.parser;
+
+/**
+ * @author fitzpata
+ */
+public class JSReferenceDetector extends JSWordDetector {
+       /**
+        * @see IWordDetector#isWordStart
+        * Try to detect tokens starting with a reference operator.
+        */
+       public boolean isWordStart(char c) {
+               return (c == '.');
+       }
+}
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSScanner.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSScanner.java
new file mode 100644 (file)
index 0000000..7fbb3e6
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * $RCSfile: JSScanner.java,v $
+ *
+ * Copyright 2002
+ * CH-1700 Fribourg, Switzerland
+ * All rights reserved.
+ *
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.1  2003/05/28 15:17:12  agfitzp
+ * net.sourceforge.phpeclipse.js.core 0.0.1 code base
+ *
+ *========================================================================
+*/
+
+package net.sourceforge.phpeclipse.js.core.parser;
+
+import java.util.*;
+import org.eclipse.jface.text.rules.*;
+import org.eclipse.jface.text.*;
+
+import org.eclipse.swt.graphics.Color;
+
+/**
+ * 
+ *
+ * @author $Author: jsurfer $, $Date: 2004-09-02 18:14:38 $
+ *
+ * @version $Revision: 1.1 $
+ */
+public class JSScanner extends RuleBasedScanner
+{
+   /**
+    * Creates a new JSScanner object.
+    *
+    * @param manager 
+    */
+   public JSScanner(Color aColor)
+   {
+      List rules = new ArrayList();
+      IToken procInstr = new Token(new TextAttribute(aColor));
+
+      // Add generic whitespace rule.
+      rules.add(new WhitespaceRule(new JSWhitespaceDetector()));
+
+      IRule[] result = new IRule[rules.size()];
+      rules.toArray(result);
+      setRules(result);
+   }
+
+}
\ No newline at end of file
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSStringScanner.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSStringScanner.java
new file mode 100644 (file)
index 0000000..b9cbaf4
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * $RCSfile: JSStringScanner.java,v $
+ *
+ * Copyright 2002
+ * CH-1700 Fribourg, Switzerland
+ * All rights reserved.
+ *
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.1  2003/05/28 15:17:11  agfitzp
+ * net.sourceforge.phpeclipse.js.core 0.0.1 code base
+ *
+ *========================================================================
+*/
+
+package net.sourceforge.phpeclipse.js.core.parser;
+
+import org.eclipse.jface.text.*;
+import java.util.*;
+import org.eclipse.jface.text.rules.*;
+
+import org.eclipse.swt.graphics.Color;
+
+
+/**
+ * 
+ *
+ * @author $Author: jsurfer $, $Date: 2004-09-02 18:14:38 $
+ *
+ * @version $Revision: 1.1 $
+ */
+public class JSStringScanner extends RuleBasedScanner
+{
+   /**
+    * Creates a new JSFuncScanner object.
+    *
+    * @param manager 
+    */
+   public JSStringScanner(Color aColor)
+   {
+      IToken string = new Token(new TextAttribute(aColor));
+      Vector rules = new Vector();
+
+      // Add rule for single and double quotes
+      rules.add(new SingleLineRule("\"", "\"", string, '\\'));
+      rules.add(new SingleLineRule("'", "'", string, '\\'));
+
+
+      // Add generic whitespace rule.
+      rules.add(new WhitespaceRule(new JSWhitespaceDetector()));
+
+      IRule[] result = new IRule[rules.size()];
+      rules.copyInto(result);
+      setRules(result);
+   }
+
+   /**
+    *
+    *
+    * @return 
+    */
+   public IToken nextToken()
+   {
+      return super.nextToken();
+   }
+}
\ No newline at end of file
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSSyntaxModelFactory.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSSyntaxModelFactory.java
new file mode 100644 (file)
index 0000000..2d4b149
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * $RCSfile: JSSyntaxModelFactory.java,v $
+ * 
+ * Copyright 2002 CH-1700 Fribourg, Switzerland All rights reserved.
+ * 
+ * ========================================================================
+ * Modifications history
+ * ========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.2  2004/02/27 17:25:25  cell
+ * Fix NPE for files without an extension
+ *
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ * Revision 1.3 2003/05/30 20:53:08 agfitzp
+ * 0.0.2 : Outlining is now done as the user types. Some other bug fixes.
+ * 
+ * Revision 1.2 2003/05/28 20:47:56 agfitzp Outline the document, not the file.
+ * 
+ * Revision 1.1 2003/05/28 15:17:11 agfitzp net.sourceforge.phpeclipse.js.core 0.0.1 code
+ * base
+ * 
+ * ========================================================================
+ */
+
+package net.sourceforge.phpeclipse.js.core.parser;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.IDocument;
+
+import net.sourceforge.phpeclipse.js.core.model.*;
+
+/**
+ * @author Addi
+ */
+public class JSSyntaxModelFactory {
+       private static JSSyntaxModelFactory instance = new JSSyntaxModelFactory();
+
+       /**
+        * Creates a new JSSyntaxModelFactory.
+        */
+       private JSSyntaxModelFactory() {
+       }
+       /**
+        * @param adaptable
+        * 
+        * @return
+        */
+       public JSElementList getContentOutline(IProject aProject) {
+               return new JSElementList(getSyntacticElements(aProject));
+       }
+
+       /**
+        * @param adaptable
+        * 
+        * @return
+        */
+       public JSElementList getContentOutline(IFile adaptable) {
+               return new JSElementList(getSyntacticElements(adaptable));
+       }
+
+       /**
+        * @param document
+        * 
+        * @return
+        */
+       public JSElementList getContentOutline(IDocument document) {
+               return new JSElementList(getSyntacticElements(document));
+       }
+
+       /**
+        * Returns the singleton.
+        * 
+        * @return
+        */
+       public static JSSyntaxModelFactory getInstance() {
+               return instance;
+       }
+
+       /**
+        * @param file
+        * 
+        * @return
+        */
+       private List getSyntacticElements(IProject aProject) {
+               int i;
+               JSParser aParser = new JSParser();
+               Object[] jsFiles = getJSFilesFor(aProject);
+
+               for (i = 0; i < jsFiles.length; i++) {
+                       aParser.parse((IFile) jsFiles[i]);
+               }
+               return aParser.getElementList();
+       }
+
+       /**
+        * @param project
+        * @return
+        */
+       private Object[] getJSFilesFor(IProject project) {
+               LinkedList files = new LinkedList();
+               collectJSFiles(project, files);
+               return files.toArray();
+       }
+
+       private void collectJSFiles(IContainer aContainer, LinkedList files) {
+               try {
+                       int i;
+                       IResource[] members = aContainer.members();
+                       for (i = 0; i < members.length; i++) {
+                               IResource aResource = members[i];
+                               if (aResource.getType() == IResource.FILE) {
+                                       IFile aFile = (IFile) aResource;
+                                       String ext = aFile.getFileExtension();
+                                       if ((ext != null) && ext.equals("js")) {
+                                               files.add(aFile);
+                                       }
+                               } else if (aResource.getType() == IResource.FOLDER) {
+                                       collectJSFiles((IFolder) aResource, files);
+                               }
+                       }
+               } catch (CoreException e) {
+               }
+       }
+       /**
+        * @param file
+        * 
+        * @return
+        */
+
+       private List getSyntacticElements(IFile file) {
+               return (new JSParser()).parse(file);
+       }
+
+       /**
+        * @param file
+        * 
+        * @return
+        */
+       private List getSyntacticElements(IDocument document) {
+               return (new JSParser()).parse(document);
+       }
+}
\ No newline at end of file
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSSyntaxScanner.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSSyntaxScanner.java
new file mode 100644 (file)
index 0000000..544e96f
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Created on May 16, 2003
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.2  2003/05/30 20:53:09  agfitzp
+ * 0.0.2 : Outlining is now done as the user types. Some other bug fixes.
+ *
+ *========================================================================
+ */
+package net.sourceforge.phpeclipse.js.core.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.jface.text.rules.*;
+
+/**
+ * Scanner for detecting syntactic elements: comments, strings, classes, functions
+ *
+ * @author fitzpata
+ *
+ */
+public class JSSyntaxScanner extends BufferedRuleBasedScanner {
+       public final static String JS_DEFAULT = "__js_default";
+       public final static String JS_COMMENT = "__js_comment";
+       public final static String JS_FUNCTION = "__js_function";
+       public final static String JS_STRING = "__js_string";
+       public final static String JS_MEMBER = "__js_member";
+       public final static String JS_PERIOD = "__js_period";
+
+       public final static IToken TOKEN_STRING = new Token(JS_STRING);
+       public final static IToken TOKEN_COMMENT = new Token(JS_COMMENT);
+       public final static IToken TOKEN_DEFAULT = new Token(JS_DEFAULT);
+       public final static IToken TOKEN_FUNCTION = new Token(JS_FUNCTION);
+       public final static IToken TOKEN_MEMBER = new Token(JS_MEMBER);
+       public final static IToken TOKEN_PERIOD = new Token(JS_PERIOD);
+
+       /**
+        * String for detecting member declarations.
+        */
+       private static String memberToken=  ".prototype";
+
+       /**
+        * Creates a new JSSyntaxScanner object.
+        */
+       public JSSyntaxScanner() {
+               List rules = new ArrayList();
+
+               rules.add(new MultiLineRule("/*", "*/", TOKEN_COMMENT));
+               rules.add(new SingleLineRule("//", "", TOKEN_COMMENT));
+               rules.add(new SingleLineRule("\"", "\"", TOKEN_STRING, '\\'));
+               rules.add(new SingleLineRule("'", "'", TOKEN_STRING, '\\'));
+               
+               rules.add(new WhitespaceRule(new JSWhitespaceDetector()));
+               
+               rules.add(new MultiLineRule("function(", ")", TOKEN_FUNCTION));
+               rules.add(new MultiLineRule("function ", ")", TOKEN_FUNCTION));
+
+               rules.add(new WordRule(new JSWordDetector(), TOKEN_DEFAULT));
+               rules.add(new PredicateWordRule(new JSReferenceDetector(), memberToken, TOKEN_MEMBER));
+               
+               setRuleList(rules);
+       }
+
+
+       /**
+        * set the rule list
+        * @param rules
+        */
+       private void setRuleList(List rules)
+       {
+               IRule[] result = new IRule[rules.size()];
+               rules.toArray(result);
+               setRules(result);
+       }
+}
\ No newline at end of file
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSWhitespaceDetector.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSWhitespaceDetector.java
new file mode 100644 (file)
index 0000000..625be0f
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * $RCSfile: JSWhitespaceDetector.java,v $
+ *
+ * Copyright 2002
+ * CH-1700 Fribourg, Switzerland
+ * All rights reserved.
+ *
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.1  2003/05/28 15:17:12  agfitzp
+ * net.sourceforge.phpeclipse.js.core 0.0.1 code base
+ *
+ *========================================================================
+*/
+
+package net.sourceforge.phpeclipse.js.core.parser;
+
+import org.eclipse.jface.text.rules.IWhitespaceDetector;
+
+
+/**
+ * 
+ *
+ * @author $Author: jsurfer $, $Date: 2004-09-02 18:14:38 $
+ *
+ * @version $Revision: 1.1 $
+ */
+public class JSWhitespaceDetector implements IWhitespaceDetector
+{
+   /**
+    *
+    *
+    * @param c 
+    *
+    * @return 
+    */
+   public boolean isWhitespace(char c)
+   {
+      return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
+   }
+}
\ No newline at end of file
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSWordDetector.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/JSWordDetector.java
new file mode 100644 (file)
index 0000000..98a69b4
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Created on May 13, 2003
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.2  2003/05/30 20:53:09  agfitzp
+ * 0.0.2 : Outlining is now done as the user types. Some other bug fixes.
+ *
+ *========================================================================
+ */
+package net.sourceforge.phpeclipse.js.core.parser;
+
+/**
+ * @author fitzpata
+ *
+ */
+
+import org.eclipse.jface.text.rules.IWordDetector;
+
+/**
+ * A JavaScript aware word detector.
+ * JavaScript tokens are almost identical to Java so this
+ * class is borrowed from org.eclipse.jdt.internal.ui.text.JavaWordDetector.
+ */
+public class JSWordDetector implements IWordDetector {
+
+       /**
+        * @see IWordDetector#isWordStart
+        * JavaScript tokens are almost identical to Java so for now
+        * we can just borrow this behavior.
+        */
+       public boolean isWordStart(char c) {
+               return Character.isJavaIdentifierStart(c);
+       }
+       
+       /**
+        * @see IWordDetector#isWordPart
+        * JavaScript tokens are almost identical to Java so for now
+        * we can just borrow this behavior.
+        */
+       public boolean isWordPart(char c) {
+               return Character.isJavaIdentifierPart(c);
+       }
+}
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/NonRuleBasedDamagerRepairer.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/NonRuleBasedDamagerRepairer.java
new file mode 100644 (file)
index 0000000..0f99bfd
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * $RCSfile: NonRuleBasedDamagerRepairer.java,v $
+ *
+ * Copyright 2002
+ * CH-1700 Fribourg, Switzerland
+ * All rights reserved.
+ *
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.1  2003/05/28 15:17:11  agfitzp
+ * net.sourceforge.phpeclipse.js.core 0.0.1 code base
+ *
+ *========================================================================
+*/
+
+package net.sourceforge.phpeclipse.js.core.parser;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.presentation.IPresentationDamager;
+import org.eclipse.jface.text.presentation.IPresentationRepairer;
+//import org.eclipse.jface.util.Assert;
+import org.eclipse.swt.custom.StyleRange;
+
+
+/**
+ * 
+ *
+ * @author $Author: jsurfer $, $Date: 2004-09-02 18:14:38 $
+ *
+ * @version $Revision: 1.1 $
+ */
+public class NonRuleBasedDamagerRepairer implements IPresentationDamager, IPresentationRepairer
+{
+   /** The document this object works on */
+   protected IDocument fDocument;
+
+   /** The default text attribute if non is returned as data by the current token */
+   protected TextAttribute fDefaultTextAttribute;
+
+   /**
+    * Constructor for NonRuleBasedDamagerRepairer.
+    * @param defaultTextAttribute
+    */
+   public NonRuleBasedDamagerRepairer(TextAttribute defaultTextAttribute)
+   {
+//      Assert.isNotNull(defaultTextAttribute);
+
+      fDefaultTextAttribute = defaultTextAttribute;
+   }
+
+   /**
+    * @see IPresentationRepairer#setDocument(IDocument)
+    */
+   public void setDocument(IDocument document)
+   {
+      fDocument = document;
+   }
+
+   /**
+    * Returns the end offset of the line that contains the specified offset or if the offset is
+    * inside a line delimiter, the end offset of the next line.
+    * 
+    * @param offset the offset whose line end offset must be computed
+    * 
+    * @return the line end offset for the given offset
+    * 
+    * @exception BadLocationException if offset is invalid in the current document
+    */
+   protected int endOfLineOf(int offset) throws BadLocationException
+   {
+      IRegion info = fDocument.getLineInformationOfOffset(offset);
+
+      if(offset <= info.getOffset() + info.getLength())
+      {
+         return info.getOffset() + info.getLength();
+      }
+
+      int line = fDocument.getLineOfOffset(offset);
+
+      try
+      {
+         info = fDocument.getLineInformation(line + 1);
+
+         return info.getOffset() + info.getLength();
+      }
+      catch(BadLocationException x)
+      {
+         return fDocument.getLength();
+      }
+   }
+
+   /**
+    * @see IPresentationDamager#getDamageRegion(ITypedRegion, DocumentEvent, boolean)
+    */
+   public IRegion getDamageRegion(ITypedRegion partition, DocumentEvent event, 
+                                  boolean documentPartitioningChanged)
+   {
+      if(!documentPartitioningChanged)
+      {
+         try
+         {
+            IRegion info = fDocument.getLineInformationOfOffset(event.getOffset());
+            int start = Math.max(partition.getOffset(), info.getOffset());
+
+            int end = event.getOffset() + 
+                      (event.getText() == null ? event.getLength()
+                                               : event.getText().length());
+
+            if(info.getOffset() <= end && end <= info.getOffset() + info.getLength())
+            {
+               // optimize the case of the same line
+               end = info.getOffset() + info.getLength();
+            }
+            else
+            {
+               end = endOfLineOf(end);
+            }
+
+            end = Math.min(partition.getOffset() + partition.getLength(), end);
+
+            return new Region(start, end - start);
+         }
+         catch(BadLocationException x)
+         {
+         }
+      }
+
+      return partition;
+   }
+
+   /**
+    * @see IPresentationRepairer#createPresentation(TextPresentation, ITypedRegion)
+    */
+   public void createPresentation(TextPresentation presentation, ITypedRegion region)
+   {
+      addRange(presentation, region.getOffset(), region.getLength(), fDefaultTextAttribute);
+   }
+
+   /**
+    * Adds style information to the given text presentation.
+    * 
+    * @param presentation the text presentation to be extended
+    * @param offset the offset of the range to be styled
+    * @param length the length of the range to be styled
+    * @param attr the attribute describing the style of the range to be styled
+    */
+   protected void addRange(TextPresentation presentation, int offset, int length, 
+                           TextAttribute attr)
+   {
+      if(attr != null)
+      {
+         presentation.addStyleRange(
+                new StyleRange(offset, length, attr.getForeground(), attr.getBackground(), 
+                               attr.getStyle()));
+      }
+   }
+}
\ No newline at end of file
diff --git a/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/PredicateWordRule.java b/archive/net.sourceforge.phpeclipse.js.core/src/net/sourceforge/phpeclipse/js/core/parser/PredicateWordRule.java
new file mode 100644 (file)
index 0000000..d59d81c
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Created on May 13, 2003
+ *========================================================================
+ * Modifications history
+ *========================================================================
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1  2004/02/26 02:25:42  agfitzp
+ * renamed packages to match xml & css
+ *
+ * Revision 1.1  2004/02/05 03:10:08  agfitzp
+ * Initial Submission
+ *
+ * Revision 1.1.2.1  2003/12/12 21:37:24  agfitzp
+ * Experimental work for Classes view
+ *
+ * Revision 1.2  2003/05/30 20:53:09  agfitzp
+ * 0.0.2 : Outlining is now done as the user types. Some other bug fixes.
+ *
+ *========================================================================
+ */
+package net.sourceforge.phpeclipse.js.core.parser;
+
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IPredicateRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WordRule;
+import org.eclipse.jface.text.rules.IWordDetector;
+
+/**
+ * @author fitzpata
+ */
+public class PredicateWordRule extends WordRule implements IPredicateRule {
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.text.rules.IPredicateRule#getSuccessToken()
+        */
+        
+       protected IToken successToken = Token.UNDEFINED;
+        
+       public void addWords(String[] tokens, IToken token)
+       {
+               for (int i = 0; i < tokens.length; i++) {
+                       addWord(tokens[i], token);
+               }
+               
+       }
+        
+       public IToken getSuccessToken() {
+               return successToken;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.text.rules.IPredicateRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner, boolean)
+        */
+       public IToken evaluate(ICharacterScanner scanner, boolean resume) {
+               successToken = this.evaluate(scanner, resume);//true);
+               return successToken;
+       }
+       
+       /**
+        * Creates a rule which, with the help of an word detector, will return the token
+        * associated with the detected word. If no token has been associated, the scanner 
+        * will be rolled back and an undefined token will be returned in order to allow 
+        * any subsequent rules to analyze the characters.
+        *
+        * @param detector the word detector to be used by this rule, may not be <code>null</code>
+        *
+        * @see #addWord
+        */
+
+       public PredicateWordRule(IWordDetector detector) {
+               super(detector);
+       }
+
+       /**
+        * Creates a rule which, with the help of an word detector, will return the token
+        * associated with the detected word. If no token has been associated, the
+        * specified default token will be returned.
+        *
+        * @param detector the word detector to be used by this rule, may not be <code>null</code>
+        * @param defaultToken the default token to be returned on success 
+        *              if nothing else is specified, may not be <code>null</code>
+        *
+        * @see #addWord
+        */
+       public PredicateWordRule(IWordDetector detector, IToken defaultToken) {
+               super(detector, defaultToken);
+       }
+
+
+       public PredicateWordRule(IWordDetector detector, String tokenString, IToken tokenType) {
+               super(detector);
+               this.addWord(tokenString, tokenType);
+       }
+       
+       public PredicateWordRule(IWordDetector detector, String[] tokens, IToken tokenType) {
+               super(detector);
+               this.addWords(tokens, tokenType);
+       }
+
+       public PredicateWordRule(IWordDetector detector, IToken defaultToken, String[] tokens, IToken tokenType) {
+               super(detector, defaultToken);
+               this.addWords(tokens, tokenType);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.core/.classpath b/net.sourceforge.phpeclipse.core/.classpath
new file mode 100644 (file)
index 0000000..065ac06
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/net.sourceforge.phpeclipse.core/.cvsignore b/net.sourceforge.phpeclipse.core/.cvsignore
new file mode 100644 (file)
index 0000000..ba077a4
--- /dev/null
@@ -0,0 +1 @@
+bin
diff --git a/net.sourceforge.phpeclipse.core/.project b/net.sourceforge.phpeclipse.core/.project
new file mode 100644 (file)
index 0000000..09c002a
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>net.sourceforge.phpeclipse.core</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.pde.PluginNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/net.sourceforge.phpeclipse.core/build.properties b/net.sourceforge.phpeclipse.core/build.properties
new file mode 100644 (file)
index 0000000..212d6fb
--- /dev/null
@@ -0,0 +1,4 @@
+source.webcore.jar = src/
+output.webcore.jar = bin/
+bin.includes = plugin.xml,\
+               webcore.jar
diff --git a/net.sourceforge.phpeclipse.core/plugin.xml b/net.sourceforge.phpeclipse.core/plugin.xml
new file mode 100644 (file)
index 0000000..4e119fa
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin
+   id="net.sourceforge.phpeclipse.core"
+   name="Web Development Tools Core"
+   version="0.0.1"
+   provider-name="WDTE Project"
+   class="net.sourceforge.phpeclipse.core.WebCore">
+
+   <runtime>
+      <library name="webcore.jar">
+         <export name="*"/>
+      </library>
+   </runtime>
+   <requires>
+      <import plugin="org.eclipse.core.runtime"/>
+      <import plugin="org.eclipse.text"/>
+   </requires>
+
+
+</plugin>
diff --git a/net.sourceforge.phpeclipse.core/src/net/sourceforge/phpeclipse/core/WebCore.java b/net.sourceforge.phpeclipse.core/src/net/sourceforge/phpeclipse/core/WebCore.java
new file mode 100644 (file)
index 0000000..52621b2
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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: WebCore.java,v 1.1 2004-09-02 18:05:22 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.core;
+
+import org.eclipse.core.runtime.Plugin;
+
+//import net.sourceforge.phpeclipse.core.parser.ISourceParser;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+public class WebCore extends Plugin {
+
+       // Instance Variables ------------------------------------------------------
+
+       /** The shared instance. */
+       private static WebCore plugin;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * The constructor.
+        */
+       public WebCore() {
+               plugin = this;
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Returns the shared instance.
+        */
+       public static WebCore getDefault() {
+               return plugin;
+       }
+
+       /**
+        * Creates and returns a parser that can handle resources of the specified
+        * MIME type.
+        * 
+        * @param mimeType the MIME type of the resource for which a parser should
+        *        be created
+        * @return the instantiated parser, or <tt>null</tt> if no parser for that
+        *         MIME type is registered
+        */
+//     public ISourceParser createParser(String mimeType) {
+//             return null;
+//     }
+}
diff --git a/net.sourceforge.phpeclipse.core/src/net/sourceforge/phpeclipse/core/model/ISourceModel.java b/net.sourceforge.phpeclipse.core/src/net/sourceforge/phpeclipse/core/model/ISourceModel.java
new file mode 100644 (file)
index 0000000..7c63cbb
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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: ISourceModel.java,v 1.1 2004-09-02 18:05:21 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.core.model;
+
+/**
+ * 
+ */
+public interface ISourceModel {
+
+       /**
+        * Returns the top-level elements of the source model.
+        * 
+        * @return an array of the top-level elements
+        */
+       ISourceReference[] getElements();
+
+       /**
+        * Returns the elements that are direct children of the given element.
+        * 
+        * @param element the element for which to return the child elements
+        * @return an array of child elements, or an empty array if the given
+        *         element has no children
+        */
+       ISourceReference[] getChildren(ISourceReference element);
+
+       /**
+        * Returns the direct parent element of the specified element.
+        * 
+        * @param element the element for which the parent should be returned
+        * @return the parent element, or <tt>null</tt> if the specified element
+        *         does not have a parent (meaning it is a top-level element)
+        */
+       ISourceReference getParent(ISourceReference element);
+
+}
diff --git a/net.sourceforge.phpeclipse.core/src/net/sourceforge/phpeclipse/core/model/ISourceReference.java b/net.sourceforge.phpeclipse.core/src/net/sourceforge/phpeclipse/core/model/ISourceReference.java
new file mode 100644 (file)
index 0000000..b5efffa
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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
+ * 
+ * $Id: ISourceReference.java,v 1.1 2004-09-02 18:05:21 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.core.model;
+
+import org.eclipse.jface.text.IRegion;
+
+/**
+ * Common protocol for model elements that have associated source code.
+ */
+public interface ISourceReference {
+
+       /**
+        * Returns the source code associated with this model element.
+        * 
+        * <p>
+        *   This method extracts the substring from the source buffer containing
+        *   this source element. This corresponds to the source regione that would
+        *   be returned by {@link ISourceReference#getSourceRegion()}</code>.
+        * </p>
+        * 
+        * @return The source code, or <code>null</code> if this element has no 
+        *         associated source code
+        */
+       String getSource();
+
+       /**
+        * Returns the source range associated with this element.
+        * 
+        * @return The source region, or <code>null</code> if this element has no 
+        *         associated source code
+        */
+       IRegion getSourceRegion();
+
+}
diff --git a/net.sourceforge.phpeclipse.core/src/net/sourceforge/phpeclipse/core/model/SourceReference.java b/net.sourceforge.phpeclipse.core/src/net/sourceforge/phpeclipse/core/model/SourceReference.java
new file mode 100644 (file)
index 0000000..ece105c
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * 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: SourceReference.java,v 1.1 2004-09-02 18:05:21 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.core.model;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+
+/**
+ * Default implementation of {@link ISourceReference} based on
+ * {@link IDocument}.
+ */
+public class SourceReference implements ISourceReference {
+
+       // Instance Variables ------------------------------------------------------
+
+       /** The associated document. */
+       private IDocument document;
+
+       /** The region in the document that maps to the source reference. */
+       private IRegion sourceRegion;
+
+       // Constructors ------------------------------------------------------------
+
+       /**
+        * Constructor.
+        * 
+        * @param document The document that contains the source reference
+        */
+       public SourceReference(IDocument document) {
+               this(document, 0, 0);
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param document The document that contains the source reference
+        */
+       public SourceReference(IDocument document, int offset) {
+               this(document, offset, 0);
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param document The document that contains the source reference
+        */
+       public SourceReference(IDocument document, int offset, int length) {
+               this.document = document;
+               this.sourceRegion = new Region(offset, length);
+       }
+
+       // ISourceReference Implementation -----------------------------------------
+
+       /*
+        * @see ISourceReference#getSource()
+        */
+       public String getSource() {
+               try {
+                       return document.get(sourceRegion.getOffset(),
+                               sourceRegion.getLength());
+               } catch (BadLocationException e) {
+                       throw new IllegalStateException(
+                               "Model not synchronized with document"); //$NON-NLS-1$
+               }
+       }
+
+       /*
+        * @see ISourceReference#getSourceRegion()
+        */
+       public IRegion getSourceRegion() {
+               return sourceRegion;
+       }
+
+       // Public Methods ----------------------------------------------------------
+
+       /**
+        * Sets the source region covered by the element.
+        * 
+        * @param offset the offset of the region
+        * @param length the length of the region
+        */
+       public final void setSourceRegion(int offset, int length) {
+               sourceRegion = new Region(offset, length);
+       }
+
+       /**
+        * Sets the source region covered by the element.
+        * 
+        * @param region the source region to set
+        */
+       public final void setSourceRegion(IRegion region) {
+               setSourceRegion(region.getOffset(), region.getLength());
+       }
+
+       // Protected Methods -------------------------------------------------------
+
+       /**
+        * Returns the underlying document.
+        * 
+        * @return the underlying document
+        */
+       protected final IDocument getDocument() {
+               return document;
+       }
+
+}