Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd.Willink2011-10-14 14:06:23 +0000
committerEd.Willink2011-10-14 14:06:23 +0000
commit7cb3441985ea04f1ac28c9a928bfe2f2cf31f775 (patch)
treef32c8b670035fbe74285b001b528551fbafee6eb /archive/org.eclipse.qvt.declarative.editor.imp.runtime
parent5665a568da221342f66034909de6357598f05108 (diff)
downloadorg.eclipse.qvtd-7cb3441985ea04f1ac28c9a928bfe2f2cf31f775.tar.gz
org.eclipse.qvtd-7cb3441985ea04f1ac28c9a928bfe2f2cf31f775.tar.xz
org.eclipse.qvtd-7cb3441985ea04f1ac28c9a928bfe2f2cf31f775.zip
Archive LPG and IMP-based plugins
Diffstat (limited to 'archive/org.eclipse.qvt.declarative.editor.imp.runtime')
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/.classpath7
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/.project28
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/.settings/org.eclipse.jdt.core.prefs74
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/.settings/org.eclipse.jdt.ui.prefs3
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/META-INF/MANIFEST.MF46
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/about.html41
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/about_files/LICENSE-2.0.txt202
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/build.properties8
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/IMP-editor.gifbin0 -> 983 bytes
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/alphab_sort_co.gifbin0 -> 153 bytes
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/error_co.gifbin0 -> 82 bytes
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/file.GIFbin0 -> 947 bytes
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/folder.GIFbin0 -> 907 bytes
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/mark_occurrences.gifbin0 -> 321 bytes
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/outline_item.gifbin0 -> 983 bytes
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/project.GIFbin0 -> 942 bytes
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/view_menu.gifbin0 -> 89 bytes
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/warning_co.gifbin0 -> 173 bytes
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/org.eclipse.imp.runtime.patch499
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/plugin.properties15
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/plugin.xml254
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/annotationHover.exsd117
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/autoEditStrategy.exsd112
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/contentProposer.exsd121
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/contextHelper.exsd111
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/documentationProvider.exsd112
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/editorActionContributions.exsd112
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/editorService.exsd109
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/entityImageDecorator.exsd109
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/entityNameLocator.exsd109
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/foldingUpdater.exsd112
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/formatter.exsd112
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/hoverHelper.exsd123
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/hyperLink.exsd112
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/imageDecorator.exsd112
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/indexContributor.exsd129
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/labelProvider.exsd112
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/languageDescription.exsd196
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/markOccurrences.exsd109
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/modelListener.exsd124
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/modelTreeBuilder.exsd112
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/outlineContentProvider.exsd112
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/outliner.exsd123
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/parser.exsd122
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/preferencesDialog.exsd136
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/preferencesSpecification.exsd166
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/refactoringContributions.exsd112
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/referenceResolvers.exsd112
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/toggleBreakpointHandler.exsd106
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/tokenColorer.exsd122
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/viewerFilter.exsd112
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/ActionMessages.java36
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/ActionMessages.properties20
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/FoldingMessages.java65
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/FoldingMessages.properties34
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/OpenAction.java196
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/OpenActionUtil.java94
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/RulerEnableDisableBreakpointAction.java68
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/SelectionDispatchAction.java248
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/BuilderBase.java535
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/BuilderUtils.java108
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/DependencyInfo.java152
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/MarkerCreator.java76
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/MarkerCreatorWithBatching.java286
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/ProblemLimit.java99
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/ProjectNatureBase.java208
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/core/Assert.java139
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/core/ErrorHandler.java93
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/core/IMPMessages.java58
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/core/core.properties2
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/AnnotationHoverBase.java210
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/EditorInputUtils.java101
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/EditorUtility.java483
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ErrorProposal.java48
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/FoldingActionGroup.java227
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/GotoAnnotationAction.java60
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/GotoMatchingFenceAction.java32
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/HoverHelper.java100
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/HyperlinkDetector.java137
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/IEditorActionDefinitionIds.java36
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/IMPOutlinePage.java236
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/IProblemChangedListener.java34
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/IRegionSelectionService.java17
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ImageImageDescriptor.java43
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/LanguageServiceManager.java249
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/MarkOccurrencesAction.java441
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ModelTreeContentProvider.java32
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ModelTreeNode.java93
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/OutlineContentProviderBase.java110
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/OutlineInformationControl.java382
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/OutlineLabelProvider.java219
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ParserScheduler.java153
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ProblemsLabelDecorator.java336
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ReferenceResolver.java71
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ServiceControllerManager.java117
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/SourceEntityImageDescriptor.java229
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/SourceProposal.java162
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/StorageLabelProvider.java133
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/StringMatcher.java386
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/StructuredSourceViewer.java337
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/TargetLink.java145
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/UniversalEditor.java1850
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/AbstractInformationControl.java1064
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/AnnotationCreator.java87
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/CompletionProcessor.java90
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/EditorErrorTickUpdater.java109
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/FoldingController.java45
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/FormattingController.java50
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/HoverHelpController.java73
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/ImageDecoratorController.java98
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/OutlineController.java121
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/PresentationController.java362
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/ProblemMarkerManager.java193
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/SourceHyperlinkController.java48
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/TextEditorActionContributor.java109
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/ToggleBreakpointsAdapter.java133
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/TreeDiffer.java49
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/messages.properties24
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/help/IMPHelp.java154
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/help/IMPHelpContext.java66
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/help/IMPHelpContextProvider.java80
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/DefinitionIndexEntry.java48
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/IndexContributorBase.java53
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/IndexEntry.java68
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/Indexer.java206
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/ReferenceIndexEntry.java42
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/CachingServiceFactory.java262
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/ILanguageService.java26
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/Language.java288
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/LanguageRegistry.java531
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/LanguageValidator.java107
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/ServiceFactory.java556
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ICompilationUnit.java36
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/IPathEntry.java55
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ISourceContainer.java17
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ISourceEntity.java35
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ISourceFolder.java17
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ISourceProject.java52
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/IWorkspaceModel.java17
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ModelFactory.java337
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/CompilationUnitRef.java209
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/PathEntry.java41
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/ResourceUtility.java41
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/SourceFolder.java116
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/SourceProject.java320
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/WorkspaceModel.java80
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/ILexer.java29
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IMessageHandler.java52
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IModelListener.java58
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IParseController.java99
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IParser.java54
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IRule.java34
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/ISourcePositionLocator.java71
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/LPGSourcePositionLocator.java102
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/MessageHandlerAdapter.java39
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/ParseControllerBase.java73
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/SimpleAnnotationTypeInfo.java40
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/SimpleLPGParseController.java285
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/SymbolTable.java57
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/AlternativePreferencesPage.java102
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/ConfigurationPreferencesTab.java131
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/DefaultPreferencesTab.java147
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/IPreferencesService.java510
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/InstancePreferencesTab.java127
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/Markings.java25
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceCache.java27
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceConstants.java70
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceErrorUtilities.java34
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceInitializer.java72
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencePage.java60
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.g501
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.java5250
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.l85
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParserprs.java386
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParsersym.java227
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencesInitializer.java34
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencesService.java1748
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencesTab.java340
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencesUtilities.java1639
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/ProjectPreferencesTab.java499
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/TabbedPreferencesPage.java309
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/BooleanFieldEditor.java630
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/ChangeButtonFieldEditor.java23
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/ColorFieldEditor.java313
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/ComboFieldEditor.java495
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/DirectoryFieldEditor.java75
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/DirectoryListFieldEditor.java243
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/DoubleFieldEditor.java159
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/FieldEditor.java957
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/FileFieldEditor.java241
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/FontFieldEditor.java574
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/IEnumValueProvider.java16
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/IntegerFieldEditor.java161
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/PreferenceDialogConstants.java59
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/RadioGroupFieldEditor.java755
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/StaticEnumValueProvider.java69
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/StringButtonFieldEditor.java249
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/StringFieldEditor.java881
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForBooleanFields.java292
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForColorFields.java325
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForComboFields.java323
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForFontFields.java324
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForRadioGroupFields.java323
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForStringFields.java335
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/IFileVisitor.java23
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/RefactoringStarter.java55
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/SourceFileFinder.java96
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/SourceRange.java49
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/SourceRangeGroup.java45
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/IPluginLog.java22
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/ImageDescriptorRegistry.java85
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/PluginBase.java106
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/PluginImages.java218
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/RuntimePlugin.java178
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/DecorationDescriptor.java60
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IASTAdapter.java142
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IASTFindReplaceTarget.java31
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IASTMatchAdapter.java36
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IAnnotationHover.java20
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IAnnotationTypeInfo.java49
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IAutoEditStrategy.java20
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IContentProposer.java38
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IDocumentationProvider.java23
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IEditorService.java26
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IEntityImageDecorator.java26
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IEntityNameLocator.java17
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IFoldingUpdater.java21
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IHelpService.java44
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IHoverHelper.java42
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IIdentityMapper.java44
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ILabelProvider.java20
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ILanguageActionsContributor.java63
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ILanguageSyntaxProperties.java72
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IOccurrenceMarker.java32
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IOutlineImage.java30
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IOutliner.java56
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IRefactoringContributor.java24
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IReferenceResolver.java61
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ISourceFormatter.java30
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ISourceHyperlinkDetector.java27
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IToggleBreakpointsHandler.java15
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ITokenColorer.java41
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/DefaultAnnotationHover.java30
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/DefaultAutoIndentStrategy.java43
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/DefaultLanguageActionsContributor.java78
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/DefaultOutlineImage.java56
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/EditorServiceBase.java63
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/FolderBase.java256
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/HoverHelperBase.java40
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/LPGASTMatchAdapterBase.java45
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/LPGFolderBase.java79
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/OutlinerBase.java462
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/TokenColorerBase.java46
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/TreeModelBuilderBase.java71
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/DefaultPartListener.java39
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/PixelConverter.java56
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/SWTUtil.java101
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/HTML2TextReader.java326
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/HTMLTextPresenter.java226
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/LineBreakingReader.java131
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/SingleCharReader.java61
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/SubstitutionTextReader.java155
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/AnnotationUtils.java140
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/ConsoleUtil.java49
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/ExtensionException.java29
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/ExtensionFactory.java395
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/HTMLPrinter.java251
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/IPositionPredicate.java28
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/MarkerUtils.java57
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/Pair.java42
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/StreamUtils.java98
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/UnimplementedError.java25
272 files changed, 47609 insertions, 0 deletions
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/.classpath b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/.classpath
new file mode 100644
index 000000000..304e86186
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/.classpath
@@ -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/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/.project b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/.project
new file mode 100644
index 000000000..6a58029a1
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.qvt.declarative.editor.imp.runtime</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/archive/org.eclipse.qvt.declarative.editor.imp.runtime/.settings/org.eclipse.jdt.core.prefs b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..e654e7848
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,74 @@
+#Sat Jul 18 16:47:53 BST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=ignore
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=ignore
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=ignore
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=ignore
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=ignore
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=ignore
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/.settings/org.eclipse.jdt.ui.prefs b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 000000000..693d9a099
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,3 @@
+#Mon Oct 09 10:50:00 EDT 2006
+eclipse.preferences.version=1
+internal.default.compliance=default
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/META-INF/MANIFEST.MF b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..dacd7012e
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/META-INF/MANIFEST.MF
@@ -0,0 +1,46 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.imp.runtime;singleton:=true
+Bundle-Version: 0.0.10100.qualifier
+Bundle-Activator: org.eclipse.imp.runtime.RuntimePlugin
+Bundle-ActivationPolicy: lazy
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Require-Bundle: com.ibm.icu,
+ lpg.runtime,
+ org.eclipse.compare,
+ org.eclipse.core.filesystem,
+ org.eclipse.core.resources,
+ org.eclipse.core.runtime,
+ org.eclipse.debug.ui,
+ org.eclipse.debug.core,
+ org.eclipse.help,
+ org.eclipse.jface.text,
+ org.eclipse.ltk.core.refactoring,
+ org.eclipse.ltk.ui.refactoring,
+ org.eclipse.ui,
+ org.eclipse.ui.console,
+ org.eclipse.ui.editors,
+ org.eclipse.ui.ide,
+ org.eclipse.ui.navigator,
+ org.eclipse.ui.views,
+ org.eclipse.ui.workbench.texteditor
+Export-Package: org.eclipse.imp.actions,
+ org.eclipse.imp.builder,
+ org.eclipse.imp.core,
+ org.eclipse.imp.editor,
+ org.eclipse.imp.indexing,
+ org.eclipse.imp.language,
+ org.eclipse.imp.model,
+ org.eclipse.imp.parser,
+ org.eclipse.imp.preferences,
+ org.eclipse.imp.preferences.fields,
+ org.eclipse.imp.preferences.fields.details,
+ org.eclipse.imp.refactoring,
+ org.eclipse.imp.runtime,
+ org.eclipse.imp.services,
+ org.eclipse.imp.services.base,
+ org.eclipse.imp.ui,
+ org.eclipse.imp.utils
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/about.html b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/about.html
new file mode 100644
index 000000000..7d5c73dfb
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/about.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>About</title>
+</head><body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>July 19, 2009</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+<h3>Third Party Content</h3>
+<p>This plugin contains a slightly modified build of org.eclipse.imp.runtime 0.1.100 SVN 21814.</p>
+<p>This plugin should be considered deprecated in that it is intended to eliminate it as soon as IMP
+runtime is promted to a non-Incubation status.</p>
+<p>The exact differences may be found in org.eclipse.imp.runtime.patch.</p>
+<p>The unpatched plugin is API compliant and so may be used instead, however the following problems may be observed:</p>
+<ul>
+ <li>BuilderBase.java - new editors may start with an NPE</li>
+ <li>AnnotationHoverBase.java - multi-line annotations are not multi-line</li>
+ <li>ParserScheduler.java - an NPE may occur when an edited file is deleted</li>
+ <li>PresentationController.java - coloring ranges may be off by one</li>
+ <li>LanguageRegistry.java - Open With offers an IMP editor that functions poorly</li>
+ <li>HTMLPrinter.java - multi-line diagnostics are not multi-line</li>
+</ul>
+
+</body></html> \ No newline at end of file
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/about_files/LICENSE-2.0.txt b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/about_files/LICENSE-2.0.txt
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/about_files/LICENSE-2.0.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/build.properties b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/build.properties
new file mode 100644
index 000000000..9ed8958aa
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/build.properties
@@ -0,0 +1,8 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ icons/,\
+ plugin.properties
+src.includes = icons/
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/IMP-editor.gif b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/IMP-editor.gif
new file mode 100644
index 000000000..34fb3c9d8
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/IMP-editor.gif
Binary files differ
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/alphab_sort_co.gif b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/alphab_sort_co.gif
new file mode 100644
index 000000000..6311cc00f
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/alphab_sort_co.gif
Binary files differ
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/error_co.gif b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/error_co.gif
new file mode 100644
index 000000000..119dcccd5
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/error_co.gif
Binary files differ
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/file.GIF b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/file.GIF
new file mode 100644
index 000000000..d6dc70c9b
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/file.GIF
Binary files differ
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/folder.GIF b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/folder.GIF
new file mode 100644
index 000000000..50169cba9
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/folder.GIF
Binary files differ
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/mark_occurrences.gif b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/mark_occurrences.gif
new file mode 100644
index 000000000..fd7c1751c
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/mark_occurrences.gif
Binary files differ
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/outline_item.gif b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/outline_item.gif
new file mode 100644
index 000000000..34fb3c9d8
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/outline_item.gif
Binary files differ
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/project.GIF b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/project.GIF
new file mode 100644
index 000000000..02fcdc4a9
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/project.GIF
Binary files differ
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/view_menu.gif b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/view_menu.gif
new file mode 100644
index 000000000..5d13485ed
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/view_menu.gif
Binary files differ
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/warning_co.gif b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/warning_co.gif
new file mode 100644
index 000000000..ee2dac4a9
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/icons/warning_co.gif
Binary files differ
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/org.eclipse.imp.runtime.patch b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/org.eclipse.imp.runtime.patch
new file mode 100644
index 000000000..99d39a625
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/org.eclipse.imp.runtime.patch
@@ -0,0 +1,499 @@
+Index: plugin.properties
+===================================================================
+--- plugin.properties (revision 0)
++++ plugin.properties (revision 0)
+@@ -0,0 +1,15 @@
++###############################################################################
++# Copyright (c) 2009 Eclipse Modeling Project and others.
++# All rights reserved. This program and the accompanying materials
++# are made available under the terms of the Eclipse Public License v1.0
++# which accompanies this distribution, and is available at
++# http://www.eclipse.org/legal/epl-v10.html
++#
++# Contributors:
++# E.D.Willink - initial API and implementation
++#
++# $Id: org.eclipse.imp.runtime.patch,v 1.2 2009/08/16 11:01:04 ewillink Exp $
++###############################################################################
++
++pluginName = QVT Declarative Editor variant of IMP Runtime
++providerName = Eclipse Modeling Project
+Index: META-INF/MANIFEST.MF
+===================================================================
+--- META-INF/MANIFEST.MF (revision 21816)
++++ META-INF/MANIFEST.MF (working copy)
+@@ -1,12 +1,12 @@
+ Manifest-Version: 1.0
+ Bundle-ManifestVersion: 2
+-Bundle-Name: IMP Runtime (Incubation)
+-Bundle-SymbolicName: org.eclipse.imp.runtime; singleton:=true
+-Bundle-Version: 0.1.100
++Bundle-Name: %pluginName
++Bundle-SymbolicName: org.eclipse.imp.runtime;singleton:=true
++Bundle-Version: 0.0.10100.qualifier
+ Bundle-Activator: org.eclipse.imp.runtime.RuntimePlugin
+ Bundle-ActivationPolicy: lazy
+-Eclipse-LazyStart: true
+-Bundle-Vendor: rfuhrer@watson.ibm.com
++Bundle-Vendor: %providerName
++Bundle-Localization: plugin
+ Require-Bundle: com.ibm.icu,
+ lpg.runtime,
+ org.eclipse.compare,
+Index: build.properties
+===================================================================
+--- build.properties (revision 21816)
++++ build.properties (working copy)
+@@ -3,5 +3,6 @@
+ bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+- icons/
++ icons/,\
++ plugin.properties
+ src.includes = icons/
+Index: src/org/eclipse/imp/language/LanguageRegistry.java
+===================================================================
+--- src/org/eclipse/imp/language/LanguageRegistry.java (revision 21816)
++++ src/org/eclipse/imp/language/LanguageRegistry.java (working copy)
+@@ -22,6 +22,7 @@
+ import java.util.Map;
+
+ import org.eclipse.core.runtime.IConfigurationElement;
++import org.eclipse.core.runtime.IExtension;
+ import org.eclipse.core.runtime.IExtensionPoint;
+ import org.eclipse.core.runtime.IPath;
+ import org.eclipse.core.runtime.InvalidRegistryObjectException;
+@@ -39,6 +40,7 @@
+ import org.eclipse.swt.widgets.Display;
+ import org.eclipse.ui.IEditorDescriptor;
+ import org.eclipse.ui.IEditorInput;
++import org.eclipse.ui.IEditorMatchingStrategy;
+ import org.eclipse.ui.IFileEditorMapping;
+ import org.eclipse.ui.PlatformUI;
+ import org.eclipse.ui.internal.registry.EditorDescriptor;
+@@ -404,6 +406,24 @@
+ break;
+ }
+ }
++ if (!gotIt) {
++ for (IEditorDescriptor editor : mapping.getEditors()) { // Search for an implicit copy of a derived UniversalEditor
++ EditorDescriptor editorDescriptor = (EditorDescriptor) editor;
++ String className = editorDescriptor.getClassName();
++ IConfigurationElement configurationElement = editorDescriptor.getConfigurationElement();
++ IExtension declaringExtension = configurationElement.getDeclaringExtension();
++ String namespaceIdentifier = declaringExtension.getNamespaceIdentifier();
++ Bundle bundle = Platform.getBundle(namespaceIdentifier);
++ try {
++ Class<?> editorClass = bundle.loadClass(className);
++ if (UniversalEditor.class.isAssignableFrom(editorClass)) {
++ gotIt = true;
++ break;
++ }
++ } catch (ClassNotFoundException e) {
++ }
++ }
++ }
+ if (!gotIt)
+ ((FileEditorMapping) mapping).addEditor((EditorDescriptor) sUniversalEditor);
+ }
+Index: src/org/eclipse/imp/parser/SymbolTable.java
+===================================================================
+--- src/org/eclipse/imp/parser/SymbolTable.java (revision 21816)
++++ src/org/eclipse/imp/parser/SymbolTable.java (working copy)
+@@ -11,7 +11,11 @@
+ * represent lexical nesting of scopes.
+ */
+ public class SymbolTable<T> extends HashMap<String,T> {
+- private final SymbolTable<T> parent;
++ /**
++ *
++ */
++ private static final long serialVersionUID = 5447807516246616283L;
++ private final SymbolTable<T> parent;
+
+ public SymbolTable() { this(null); }
+ public SymbolTable(SymbolTable<T> parent) { this.parent = parent; }
+Index: src/org/eclipse/imp/utils/HTMLPrinter.java
+===================================================================
+--- src/org/eclipse/imp/utils/HTMLPrinter.java (revision 21816)
++++ src/org/eclipse/imp/utils/HTMLPrinter.java (working copy)
+@@ -212,19 +212,19 @@
+ * Formats several messages as HTML text.
+ */
+ public static String formatMultipleMessages(List/*<String>*/ messages) {
+- if (true) { // until we hook in the HTML-enabled hover viewer
+- StringBuffer buff= new StringBuffer();
+- buff.append("Multiple messages:\n");
+- for(Iterator iter= messages.iterator(); iter.hasNext();) {
+- String msg= (String) iter.next();
+- buff.append(" ");
+- buff.append(msg);
+- if (iter.hasNext())
+- buff.append('\n');
+- }
+- return buff.toString();
+- }
+- StringBuffer buffer= new StringBuffer();
++// if (true) { // until we hook in the HTML-enabled hover viewer
++// StringBuffer buff= new StringBuffer();
++// buff.append("Multiple messages:\n");
++// for(Iterator iter= messages.iterator(); iter.hasNext();) {
++// String msg= (String) iter.next();
++// buff.append(" ");
++// buff.append(msg);
++// if (iter.hasNext())
++// buff.append('\n');
++// }
++// return buff.toString();
++// }
++ StringBuffer buffer= new StringBuffer();
+ addPageProlog(buffer);
+ addParagraph(buffer, convertToHTMLContent("There are multiple markers on this line."));
+ startBulletList(buffer);
+@@ -240,8 +240,8 @@
+ * Formats a message as HTML text.
+ */
+ public static String formatSingleMessage(String message) {
+- if (true) // until we hook in the HTML-enabled hover viewer
+- return message;
++// if (true) // until we hook in the HTML-enabled hover viewer
++// return message;
+ StringBuffer buffer= new StringBuffer();
+ addPageProlog(buffer);
+ addParagraph(buffer, convertToHTMLContent(message));
+Index: src/org/eclipse/imp/builder/BuilderBase.java
+===================================================================
+--- src/org/eclipse/imp/builder/BuilderBase.java (revision 21816)
++++ src/org/eclipse/imp/builder/BuilderBase.java (working copy)
+@@ -116,9 +116,15 @@
+
+ private final IResourceDeltaVisitor fDeltaVisitor= new SourceDeltaVisitor();
+
+- protected IPreferencesService fPrefService= new PreferencesService(null, getPlugin().getLanguageID());
++ private IPreferencesService fPrefService= null;
++
++ protected IPreferencesService getPreferencesService() {
++ if (fPrefService == null)
++ fPrefService= new PreferencesService(null, getPlugin().getLanguageID());
++ return fPrefService;
++ }
+
+- protected DependencyInfo fDependencyInfo;
++ protected DependencyInfo fDependencyInfo;
+
+ private final Collection<IFile> fChangedSources= new HashSet<IFile>();
+
+@@ -184,8 +190,9 @@
+
+ @SuppressWarnings("unchecked")
+ protected IProject[] build(int kind, Map args, IProgressMonitor monitor) {
+- if (fPrefService.getProject() == null) {
+- fPrefService.setProject(getProject());
++ IPreferencesService preferencesService = getPreferencesService();
++ if (preferencesService.getProject() == null) {
++ preferencesService.setProject(getProject());
+ }
+
+ fChangedSources.clear();
+Index: src/org/eclipse/imp/editor/AnnotationHoverBase.java
+===================================================================
+--- src/org/eclipse/imp/editor/AnnotationHoverBase.java (revision 21816)
++++ src/org/eclipse/imp/editor/AnnotationHoverBase.java (working copy)
+@@ -159,8 +159,8 @@
+ * Formats a message as HTML text.
+ */
+ public static String formatSingleMessage(String message) {
+- if (true) // until we hook in the HTML-enabled hover viewer
+- return message;
++// if (true) // until we hook in the HTML-enabled hover viewer
++// return message;
+ StringBuffer buffer= new StringBuffer();
+ HTMLPrinter.addPageProlog(buffer);
+ HTMLPrinter.addParagraph(buffer, HTMLPrinter.convertToHTMLContent(message));
+@@ -173,18 +173,18 @@
+ */
+ public static String formatMultipleMessages(List<String> messages) {
+ // TODO Hook in the HTML-enabled hover viewer
+- if (true) { // until we hook in the HTML-enabled hover viewer
+- StringBuilder sb= new StringBuilder();
+-
+- sb.append("Multiple messages:\n");
+- int idx= 0;
+- for(String msg: messages) {
+- if (idx++ > 0) { sb.append('\n'); }
+- sb.append(" ");
+- sb.append(msg);
+- }
+- return sb.toString();
+- }
++// if (true) { // until we hook in the HTML-enabled hover viewer
++// StringBuilder sb= new StringBuilder();
++//
++// sb.append("Multiple messages:\n");
++// int idx= 0;
++// for(String msg: messages) {
++// if (idx++ > 0) { sb.append('\n'); }
++// sb.append(" ");
++// sb.append(msg);
++// }
++// return sb.toString();
++// }
+ StringBuffer buffer= new StringBuffer();
+ HTMLPrinter.addPageProlog(buffer);
+ HTMLPrinter.addParagraph(buffer, HTMLPrinter.convertToHTMLContent("Multiple messages at this line"));
+Index: src/org/eclipse/imp/editor/internal/PresentationController.java
+===================================================================
+--- src/org/eclipse/imp/editor/internal/PresentationController.java (revision 21816)
++++ src/org/eclipse/imp/editor/internal/PresentationController.java (working copy)
+@@ -13,6 +13,8 @@
+
+ import java.io.PrintStream;
+ import java.util.ArrayList;
++import java.util.Collections;
++import java.util.Comparator;
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Stack;
+@@ -160,16 +162,19 @@
+ if (offset <= prevEnd && end >= prevOffset) {
+ continue;
+ }
+- changeTokenPresentation(parseController, presentation, token, locator);
++ else {
++ TextAttribute attribute= fColorer.getColoring(parseController, token);
++ if (attribute != null) {
++ changeTokenPresentation(parseController, presentation, offset, attribute, end);
++ }
++ }
+ prevOffset= offset;
+ prevEnd= end;
+ }
+ }
+
+- private void changeTokenPresentation(IParseController controller, TextPresentation presentation, Object token, ISourcePositionLocator locator) {
+- TextAttribute attribute= fColorer.getColoring(controller, token);
+-
+- StyleRange styleRange= new StyleRange(locator.getStartOffset(token), locator.getEndOffset(token) - locator.getStartOffset(token) + 1,
++ private void changeTokenPresentation(IParseController controller, TextPresentation presentation, int startOffset, TextAttribute attribute, int endOffset) {
++ StyleRange styleRange= new StyleRange(startOffset, endOffset - startOffset + 1,
+ attribute == null ? null : attribute.getForeground(),
+ attribute == null ? null : attribute.getBackground(),
+ attribute == null ? SWT.NORMAL : attribute.getStyle());
+@@ -182,17 +187,27 @@
+ }
+ }
+
+- private void submitTextPresentation(final TextPresentation presentation) {
+-
++ private void submitTextPresentation(final TextPresentation uncheckedPresentation) {
++ int charCount = 0;
++ if (fSourceViewer != null) {
++ IDocument document = fSourceViewer.getDocument();
++ if (document != null) // EDW 27 Sep 2008 May be null after file deleted
++ charCount = document.getLength();
++ }
++ final TextPresentation presentation;
++ if (!checkPresentation(uncheckedPresentation, charCount))
++ presentation = correctPresentation(uncheckedPresentation, charCount);
++ else
++ presentation = uncheckedPresentation;
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+
+ // SMS 16 Sep 2008
+- int charCount;
+- if (fSourceViewer != null) {
+- charCount = fSourceViewer.getDocument().getLength();
+- } else {
+- charCount = 0;
++ int charCount = 0;
++ if (fSourceViewer != null) {
++ IDocument document = fSourceViewer.getDocument();
++ if (document != null) // EDW 27 Sep 2008 May be null after file deleted
++ charCount = document.getLength();
+ }
+
+ // Attempt to head off exception due to final range extending beyond
+@@ -206,7 +221,7 @@
+ Iterator presIt = presentation.getAllStyleRangeIterator();
+ while (presIt.hasNext()) {
+ StyleRange nextRange = (StyleRange) presIt.next();
+- if (nextRange.start + nextRange.length < charCount)
++ if (nextRange.start + nextRange.length <= charCount)
+ newPresentation.addStyleRange(nextRange);
+ }
+ } else {
+@@ -270,4 +285,78 @@
+ }
+ });
+ }
++
++ private boolean checkPresentation(TextPresentation presentation, int charCount) { // EDW
++ Iterator presIt = presentation.getAllStyleRangeIterator();
++ int end = -1;
++ while (presIt.hasNext()) {
++ StyleRange nextRange = (StyleRange) presIt.next();
++ int start = nextRange.start;
++ int length = nextRange.length;
++ if (start < end) {
++ System.out.println("Unexpected style start " + start + ":" + length + ":" + (start + length) + "/" + charCount);
++ return false;
++ }
++ if (length < 1) {
++ System.out.println("Unexpected style length " + start + ":" + length + ":" + (start + length) + "/" + charCount);
++ return false;
++ }
++ end = start + length;
++ if (end > charCount) {
++ System.out.println("Unexpected style end " + start + ":" + length + ":" + (start + length) + "/" + charCount);
++ return false;
++ }
++ }
++ return true;
++ }
++
++ private TextPresentation correctPresentation(TextPresentation presentation, int charCount) { // EDW
++ List<StyleRange> ranges = new ArrayList<StyleRange>();
++ Iterator presIt = presentation.getAllStyleRangeIterator();
++ for (int styleNumber = 0; presIt.hasNext(); styleNumber++) {
++ StyleRange range = (StyleRange) presIt.next();
++ int start = range.start;
++ int length = range.length;
++ if (length <= 0)
++ System.out.println("Ignored -ve length style " + styleNumber + ": " + range.start + ":" + range.length + ":" + (range.start + range.length) + "/" + charCount);
++ else if (start >= charCount)
++ System.out.println("Ignored past-end style " + styleNumber + ": " + range.start + ":" + range.length + ":" + (range.start + range.length) + "/" + charCount);
++ else {
++ int end = start + length;
++ if (end > charCount) {
++ System.out.println("Truncated over-end style " + styleNumber + ": " + range.start + ":" + range.length + ":" + (range.start + range.length) + "/" + charCount);
++ range.length = charCount - start;
++ }
++ ranges.add(range);
++ }
++ }
++ Collections.sort(ranges, new Comparator<StyleRange>()
++ {
++ public int compare(StyleRange o1, StyleRange o2) {
++ return o1.start - o2.start;
++ }
++ });
++ IDocument document = fSourceViewer.getDocument();
++ TextPresentation newPresentation = new TextPresentation();
++ int iMax = ranges.size();
++ for (int i = 0; i < iMax; i++) {
++ StyleRange thisRange = ranges.get(i);
++ if ((i+1) < iMax) {
++ StyleRange nextRange = ranges.get(i+1);
++ int end = thisRange.start + thisRange.length;
++ if (end > nextRange.start) {
++ try {
++ System.out.println("Truncated over-lap style " + i + " " +
++ thisRange.start + ":" + thisRange.length + ":" + (thisRange.start + thisRange.length) + ":'" + document.get(thisRange.start, thisRange.length) + "' " +
++ nextRange.start + ":" + nextRange.length + ":" + (nextRange.start + nextRange.length) + ":'" + document.get(nextRange.start, nextRange.length) + "'");
++ } catch (BadLocationException e) {
++ e.printStackTrace();
++ }
++ thisRange.length = nextRange.start - thisRange.start;
++ }
++ }
++ newPresentation.addStyleRange(thisRange);
++ }
++ return newPresentation;
++ }
+ }
+Index: src/org/eclipse/imp/editor/ParserScheduler.java
+===================================================================
+--- src/org/eclipse/imp/editor/ParserScheduler.java (revision 21816)
++++ src/org/eclipse/imp/editor/ParserScheduler.java (working copy)
+@@ -72,6 +72,10 @@
+ IEditorInput editorInput= fEditorPart.getEditorInput();
+ try {
+ IDocument document= fDocumentProvider.getDocument(editorInput);
++ if (document == null) { // EDW 29 Sep 2008
++ /* Editor was deleted */
++ return Status.OK_STATUS;
++ }
+
+ if (PreferenceCache.emitMessages /* fPrefService.getBooleanPreference(PreferenceConstants.P_EMIT_MESSAGES) */) {
+ RuntimePlugin.getInstance().writeInfoMsg(
+Index: .settings/org.eclipse.jdt.core.prefs
+===================================================================
+--- .settings/org.eclipse.jdt.core.prefs (revision 21816)
++++ .settings/org.eclipse.jdt.core.prefs (working copy)
+@@ -1,4 +1,4 @@
+-#Wed Oct 18 15:08:27 EDT 2006
++#Sat Jul 18 16:47:53 BST 2009
+ eclipse.preferences.version=1
+ org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+ org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+@@ -7,6 +7,68 @@
+ org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+ org.eclipse.jdt.core.compiler.debug.localVariable=generate
+ org.eclipse.jdt.core.compiler.debug.sourceFile=generate
++org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+ org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
++org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
++org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
++org.eclipse.jdt.core.compiler.problem.deadCode=ignore
++org.eclipse.jdt.core.compiler.problem.deprecation=ignore
++org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
++org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
++org.eclipse.jdt.core.compiler.problem.discouragedReference=ignore
++org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+ org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
++org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
++org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
++org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
++org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
++org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
++org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
++org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
++org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
++org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
++org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
++org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
++org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
++org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
++org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
++org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
++org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
++org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning
++org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
++org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
++org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
++org.eclipse.jdt.core.compiler.problem.nullReference=warning
++org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
++org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
++org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
++org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
++org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
++org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
++org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
++org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
++org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=ignore
++org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
++org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
++org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
++org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=ignore
++org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
++org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
++org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
++org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
++org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
++org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
++org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
++org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
++org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
++org.eclipse.jdt.core.compiler.problem.unusedImport=ignore
++org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
++org.eclipse.jdt.core.compiler.problem.unusedLocal=ignore
++org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
++org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
++org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
++org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
++org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=ignore
++org.eclipse.jdt.core.compiler.problem.unusedWarningToken=ignore
++org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+ org.eclipse.jdt.core.compiler.source=1.5
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/plugin.properties b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/plugin.properties
new file mode 100644
index 000000000..b2040cdb3
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/plugin.properties
@@ -0,0 +1,15 @@
+###############################################################################
+# Copyright (c) 2009 Eclipse Modeling Project and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# E.D.Willink - initial API and implementation
+#
+# $Id: plugin.properties,v 1.1 2009/07/19 12:07:35 ewillink Exp $
+###############################################################################
+
+pluginName = QVT Declarative Editor variant of IMP Runtime
+providerName = Eclipse Modeling Project
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/plugin.xml b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/plugin.xml
new file mode 100644
index 000000000..a3e3a7bef
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/plugin.xml
@@ -0,0 +1,254 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin>
+ <extension-point id="annotationHover" name="Annotation Hover" schema="schema/annotationHover.exsd"/>
+ <extension-point id="autoEditStrategy" name="Auto-Edit Strategy" schema="schema/autoEditStrategy.exsd"/>
+ <extension-point id="contentProposer" name="IMP Content Proposer" schema="schema/contentProposer.exsd"/>
+ <extension-point id="contextHelper" name="Context Helper" schema="schema/contextHelper.exsd"/>
+ <extension-point id="documentationProvider" name="Documentation Provider" schema="schema/documentationProvider.exsd"/>
+ <extension-point id="editorActionContributions" name="Editor Action Contributions" schema="schema/editorActionContributions.exsd"/>
+ <extension-point id="editorService" name="IMP Editor Service" schema="schema/editorService.exsd"/>
+ <extension-point id="entityImageDecorator" name="Entity Image Decorator" schema="schema/entityImageDecorator.exsd"/>
+ <extension-point id="entityNameLocator" name="Entity Name Locator" schema="schema/entityNameLocator.exsd"/>
+ <extension-point id="foldingUpdater" name="IMP Source Folding Updater" schema="schema/foldingUpdater.exsd"/>
+ <extension-point id="formatter" name="IMP Source Code Formatter" schema="schema/formatter.exsd"/>
+ <extension-point id="hoverHelper" name="IMP Hover Helper" schema="schema/hoverHelper.exsd"/>
+ <extension-point id="hyperLink" name="IMP Hyperlink Detector" schema="schema/hyperLink.exsd"/>
+ <extension-point id="imageDecorator" name="Image Decorator" schema="schema/imageDecorator.exsd"/>
+ <extension-point id="indexContributor" name="Shared index of language-specific items, such as types" schema="schema/indexContributor.exsd"/>
+ <extension-point id="labelProvider" name="Label Provider" schema="schema/labelProvider.exsd"/>
+ <extension-point id="languageDescription" name="Description of a programming language" schema="schema/languageDescription.exsd"/>
+ <extension-point id="markOccurrences" name="Mark Occurrences" schema="schema/markOccurrences.exsd"/>
+ <extension-point id="modelListener" name="Listener for model changes" schema="schema/modelListener.exsd"/>
+ <extension-point id="modelTreeBuilder" name="Model Tree Builder" schema="schema/modelTreeBuilder.exsd"/>
+ <extension-point id="outlineContentProvider" name="Outline Content Provider" schema="schema/outlineContentProvider.exsd"/>
+ <extension-point id="outliner" name="IMP Outliner" schema="schema/outliner.exsd"/>
+ <extension-point id="parser" name="Language-specific parser" schema="schema/parser.exsd"/>
+ <extension-point id="refactoringContributions" name="Refactoring Contributions" schema="schema/refactoringContributions.exsd"/>
+ <extension-point id="referenceResolvers" name="IMP Reference Resolver" schema="schema/referenceResolvers.exsd"/>
+ <extension-point id="toggleBreakpointHandler" name="Toggle Breakpoint Handler" schema="schema/toggleBreakpointHandler.exsd"/>
+ <extension-point id="tokenColorer" name="IMP Token Colorer" schema="schema/tokenColorer.exsd"/>
+ <extension-point id="viewerFilter" name="Program Entity Viewer Filter" schema="schema/viewerFilter.exsd"/>
+
+ <extension
+ point="org.eclipse.ui.editors">
+ <editor
+ name="IMP Editor"
+ icon="icons/IMP-editor.gif"
+ extensions="txt"
+ contributorClass="org.eclipse.imp.editor.internal.TextEditorActionContributor"
+ class="org.eclipse.imp.editor.UniversalEditor"
+ id="org.eclipse.imp.runtime.impEditor">
+ </editor>
+ </extension>
+ <extension
+ id="org.eclipse.imp.startup"
+ name="IMP Runtime Startup"
+ point="org.eclipse.ui.startup">
+ </extension>
+ <extension
+ point="org.eclipse.ui.editorActions">
+ <editorContribution
+ targetID="org.eclipse.imp.runtime.impEditor"
+ id="imp.rulerActions">
+ <action
+ label="Not Used"
+ class="org.eclipse.debug.ui.actions.RulerToggleBreakpointActionDelegate"
+ style="push"
+ actionID="RulerDoubleClick"
+ id="imp.doubleClickBreakpointAction"/>
+ </editorContribution>
+ </extension>
+ <extension
+ point="org.eclipse.ui.editors.annotationTypes">
+ <type
+ markerSeverity="1"
+ name="org.eclipse.imp.editor.parseAnnotation"
+ super="org.eclipse.ui.workbench.texteditor.error"/>
+ <type
+ markerSeverity="1"
+ name="org.eclipse.imp.runtime.occurrenceAnnotation"
+ super="org.eclipse.ui.workbench.texteditor.error"/>
+ </extension>
+ <extension
+ point="org.eclipse.ui.editors.markerAnnotationSpecification">
+ <specification
+ annotationType="org.eclipse.imp.editor.parseAnnotation"
+ colorPreferenceKey="parseAnnotationColor"
+ colorPreferenceValue="255,128,147"
+ contributesToHeader="false"
+ highlightPreferenceKey="parseAnnotationHighlightKey"
+ highlightPreferenceValue="false"
+ includeOnPreferencePage="true"
+ isGoToNextNavigationTarget="true"
+ isGoToNextNavigationTargetKey="parseAnnotationIsGotoNextKey"
+ isGoToPreviousNavigationTarget="true"
+ isGoToPreviousNavigationTargetKey="parseAnnotationIsGotoPrevKey"
+ label="IMP Parser Annotation"
+ overviewRulerPreferenceKey="parseAnnotationOverviewKey"
+ overviewRulerPreferenceValue="true"
+ presentationLayer="2"
+ showInNextPrevDropdownToolbarAction="true"
+ symbolicIcon="error"
+ textPreferenceKey="parseAnnotationTextKey"
+ textPreferenceValue="true"
+ textStylePreferenceKey="parseAnnotationTextStyleKey"
+ textStylePreferenceValue="SQUIGGLES"
+ verticalRulerPreferenceKey="parseAnnotationVerticalKey"
+ verticalRulerPreferenceValue="false"/>
+ </extension>
+ <!--
+ <extension
+ point="org.eclipse.ui.preferencePages">
+ <page
+ class="org.eclipse.imp.preferences.PreferencePage"
+ id="org.eclipse.imp.runtime.preferencePage"
+ name="IMP"/>
+ </extension>
+ <extension
+ point="org.eclipse.core.runtime.preferences">
+ <initializer class="org.eclipse.imp.preferences.PreferenceInitializer"/>
+ </extension>
+ -->
+ <extension
+ point="org.eclipse.ui.bindings">
+ <key
+ commandId="org.eclipse.imp.runtime.editor.showOutline"
+ contextId="org.eclipse.ui.textEditorScope"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ sequence="M1+O"/>
+ <key
+ commandId="org.eclipse.imp.runtime.editor.toggleComment"
+ contextId="org.eclipse.ui.contexts.window"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ sequence="M1+/"/>
+ <key
+ commandId="org.eclipse.imp.runtime.editor.indentSelection"
+ contextId="org.eclipse.ui.contexts.window"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ sequence="M1+I"/>
+ <key
+ commandId="org.eclipse.imp.runtime.editor.formatSource"
+ contextId="org.eclipse.ui.textEditorScope"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ sequence="M1+M2+F"/>
+ <key
+ sequence="M1+M3+P"
+ contextId="org.eclipse.ui.textEditorScope"
+ commandId="org.eclipse.imp.runtime.editor.gotoMatchingFence"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/>
+ </extension>
+ <extension
+ point="org.eclipse.ui.commands">
+ <command
+ categoryId="org.eclipse.ui.category.navigate"
+ description="Show the quick outline for the editor input"
+ id="org.eclipse.imp.runtime.editor.showOutline"
+ name="Show Outline"/>
+ <command
+ name="Collapse Members"
+ description="Collapses all members in the current source file"
+ categoryId="org.eclipse.ui.category.textEditor"
+ id="org.eclipse.imp.runtime.editor.folding.collapseMembers">
+ </command>
+ <command
+ name="Collapse Comments"
+ description="Collapses all multi-line comments in the current source file"
+ categoryId="org.eclipse.ui.category.textEditor"
+ id="org.eclipse.jdt.ui.edit.text.java.folding.collapseComments">
+ </command>
+ <command
+ categoryId="org.eclipse.imp.runtime.source"
+ description="Comments/uncomments the current selection or the current source line"
+ id="org.eclipse.imp.runtime.editor.toggleComment"
+ name="Toggle Comment"/>
+ <command
+ categoryId="org.eclipse.imp.runtime.source"
+ description="Format the source code"
+ id="org.eclipse.imp.runtime.editor.formatSource"
+ name="Format"/>
+ <command
+ name="Go to Matching Fence"
+ description="Moves the cursor to the matching fence character, if any"
+ categoryId="org.eclipse.ui.category.navigate"
+ id="org.eclipse.imp.runtime.editor.gotoMatchingFence">
+ </command>
+ <command
+ categoryId="org.eclipse.imp.runtime.source"
+ description="Re-indent the selected text"
+ id="org.eclipse.imp.runtime.editor.indentSelection"
+ name="Indent Selection">
+ </command>
+ <category
+ id="org.eclipse.imp.runtime.source"
+ name="Source"/>
+ </extension>
+ <extension
+ point="org.eclipse.ui.actionSets">
+ <actionSet
+ id="org.eclipse.imp.runtime.refactoringActions"
+ label="IMP Refactoring Actions"
+ visible="true">
+ <menu
+ id="org.eclipse.imp.refactoring"
+ label="Refactor">
+ <separator name="org.eclipse.imp.refactoring"/>
+ </menu>
+ <action
+ class="org.eclipse.imp.editor.MarkOccurrencesAction"
+ icon="icons/mark_occurrences.gif"
+ id="org.eclipse.imp.runtime.actions.markOccurrencesAction"
+ label="&amp;Toggle Mark Occurrences"
+ state="false"
+ style="toggle"
+ toolbarPath="sampleGroup"
+ tooltip="Toggles marking occurrences of the given entity"/>
+ </actionSet>
+ </extension>
+ <extension
+ point="org.eclipse.ui.editors.markerAnnotationSpecification">
+ <specification
+ annotationType="org.eclipse.imp.runtime.occurrenceAnnotation"
+ colorPreferenceKey="occurrenceColorPreference"
+ colorPreferenceValue="0,255,128"
+ contributesToHeader="false"
+ highlightPreferenceKey="occurrenceHighlightKey"
+ highlightPreferenceValue="true"
+ includeOnPreferencePage="true"
+ isGoToNextNavigationTarget="true"
+ isGoToNextNavigationTargetKey="occurrenceAnnotationIsGotoNextKey"
+ isGoToPreviousNavigationTarget="true"
+ isGoToPreviousNavigationTargetKey="occurrenceAnnotationIsGotoPrevKey"
+ label="Occurrences"
+ overviewRulerPreferenceKey="occurrenceOverviewRulerPreference"
+ overviewRulerPreferenceValue="true"
+ presentationLayer="4"
+ showInNextPrevDropdownToolbarAction="true"
+ textPreferenceKey="occurrenceTextPreference"
+ textPreferenceValue="true"
+ textStylePreferenceKey="parseAnnotationTextStyleKey"
+ textStylePreferenceValue="UNDERLINE"
+ verticalRulerPreferenceKey="occurrenceVerticalRulerPreference"
+ verticalRulerPreferenceValue="true"/>
+ </extension>
+ <extension
+ point="org.eclipse.ui.perspectiveExtensions">
+ <perspectiveExtension targetID="org.eclipse.jdt.ui.JavaPerspective">
+ <showInPart id="org.eclipse.imp.runtime.projectExplorerView"/>
+ </perspectiveExtension>
+ </extension>
+ <extension
+ point="org.eclipse.core.runtime.preferences">
+ <initializer
+ class="org.eclipse.imp.preferences.PreferenceInitializer">
+ </initializer>
+ </extension>
+ <extension
+ point="org.eclipse.ui.preferencePages">
+ <page
+ name="IMP"
+ class="org.eclipse.imp.preferences.PreferencePage"
+ id="org.eclipse.imp.runtime.preferencePage">
+ </page>
+ </extension>
+</plugin>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/annotationHover.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/annotationHover.exsd
new file mode 100644
index 000000000..e31815144
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/annotationHover.exsd
@@ -0,0 +1,117 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="annotationHover" name="Annotation Hover"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="annotationHover"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="annotationHover">
+ <annotation>
+ <documentation>
+ Defines an &quot;annotation hover&quot; language service for source file editing that is responsible for producing textual information to be shown in a pop-up hover helper when the mouse hovers over a textual annotation.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully-qualified name of the class that will be generated to serve as the implementation of this extension. This class will be assigned the given name and located in the given package in the currently selected project. (The package will be created if it does not already exist.)
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.jface.text.source.IAnnotationHover"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of the language to which this service applies. There must be a corresponding &quot;language description&quot; extension whose name matches this attribute&apos;s value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/autoEditStrategy.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/autoEditStrategy.exsd
new file mode 100644
index 000000000..323218ebe
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/autoEditStrategy.exsd
@@ -0,0 +1,112 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="autoEditStrategy" name="Auto-Edit Strategy"/>
+ </appInfo>
+ <documentation>
+ Implementors of this extension provide an &quot;auto-edit strategy&quot;, which is used to do things like automatically indenting a new line when a newline is entered.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="autoEditStrategy"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="autoEditStrategy">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully-qualified name of the class that provides the language-specific implementation of this extension. This class will be assigned the given name and located in the given package in the currently selected project. (The package will be created if it does not already exist.)
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="IAutoEditStrategy"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of the language to which this service applies. There must be a corresponding &quot;language description&quot; extension whose name matches this attribute&apos;s value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/contentProposer.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/contentProposer.exsd
new file mode 100644
index 000000000..fc943ad37
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/contentProposer.exsd
@@ -0,0 +1,121 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.metatooling">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.metatooling" id="contentProposer" name="IMP IDE Content Proposer"/>
+ </appInfo>
+ <documentation>
+ The org.eclips.imp.editor.contentProposer extension point allows contributors to provide content assist proposals. The provider specifies what languages it can provide content proposals for. The provider has to implement the IContentProposer interface. The proposer will be presented with an IModel and a location, and from this combination returns a list of relevant content proposals.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="proposer"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="proposer">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully-qualified name of the class that will be generated to serve as the implementation of this extension. This class will be assigned the given name and located in the given package in the currently selected project. (The package will be created if it does not already exist.)
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.services.IContentProposer"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of the language to which this service applies. There must be a corresponding &quot;language description&quot; extension whose name matches this attribute&apos;s value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ The following contribution adds a content proposer that can
+consume ASTs created for the Common Lisp language.
+&lt;pre&gt;
+ &lt;extension point=&quot;org.common.lisp.ContentProposer&quot;&gt;
+ &lt;proposer
+ class=&quot;org.common.lisp.ContentProposer&quot;
+ language=&quot;Common Lisp&quot;
+ name=&quot;Common Lisp Content Proposer&quot;
+ id=&quot;org.common.lisp.proposer&quot;&gt;
+ &lt;/proposer&gt;
+ &lt;/extension&gt;
+&lt;/pre&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ Contributor should implemnet IContentProposer.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ See org.eclipse.imp.DefaultContentProposer.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Licensed Materials - Property of IBM,
+ (c) Copyright IBM Corp. 1998, 2004 All Rights Reserved
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/contextHelper.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/contextHelper.exsd
new file mode 100644
index 000000000..9d4560903
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/contextHelper.exsd
@@ -0,0 +1,111 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="contextHelper" name="Context Helper"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="contextHelper">
+ <complexType>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.imp.services.IHelpService"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/documentationProvider.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/documentationProvider.exsd
new file mode 100644
index 000000000..1a8719e0d
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/documentationProvider.exsd
@@ -0,0 +1,112 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="documentationProvider" name="Documentation Provider"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="docProvider"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="docProvider">
+ <complexType>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="IDocumentationProvider"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/editorActionContributions.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/editorActionContributions.exsd
new file mode 100644
index 000000000..f66d7ff39
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/editorActionContributions.exsd
@@ -0,0 +1,112 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="editorActionContributions" name="Editor Action Contributions"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="editorActionContributor"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="editorActionContributor">
+ <complexType>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.services.ILanguageActionsContributor"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/editorService.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/editorService.exsd
new file mode 100644
index 000000000..833e0600a
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/editorService.exsd
@@ -0,0 +1,109 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="editorServiceController" name="IMP Editor Service"/>
+ </appinfo>
+ <documentation>
+ Implementors of this extension point perform some service on behalf of a language-specific editor, typically based on the AST of the currently edited source file.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="editorService"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="editorService">
+ <complexType>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.imp.parser.IModelListener"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiInfo"/>
+ </appinfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/entityImageDecorator.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/entityImageDecorator.exsd
new file mode 100644
index 000000000..22681dc8c
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/entityImageDecorator.exsd
@@ -0,0 +1,109 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="entityImageDecorator" name="Entity Image Decorator"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="entityImageDecorator">
+ <complexType>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.imp.services.IEntityImageDecorator"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/entityNameLocator.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/entityNameLocator.exsd
new file mode 100644
index 000000000..7bfd5c4e6
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/entityNameLocator.exsd
@@ -0,0 +1,109 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="entityNameLocator" name="Entity Name Locator"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="entityNameLocator">
+ <complexType>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.imp.services.IEntityNameLocator"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/foldingUpdater.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/foldingUpdater.exsd
new file mode 100644
index 000000000..5be451a1a
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/foldingUpdater.exsd
@@ -0,0 +1,112 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="foldingUpdater" name="IMP IDE Source Folding Updater"/>
+ </appInfo>
+ <documentation>
+ Implementors of this extension point identify the AST nodes that should be foldable.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="foldingUpdater"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="foldingUpdater">
+ <complexType>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of the language to which this service applies. There must be a corresponding &quot;language description&quot; extension whose name matches this attribute&apos;s value.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully-qualified name of the class that will be generated to serve as the implementation of this extension. This class will be assigned the given name and located in the given package in the currently selected project. (The package will be created if it does not already exist.)
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.services.IFoldingUpdater"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/formatter.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/formatter.exsd
new file mode 100644
index 000000000..300018b82
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/formatter.exsd
@@ -0,0 +1,112 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="formatter" name="IMP Source Code Formatter"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="formatter"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="formatter">
+ <complexType>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of the language to which this service applies. There must be a corresponding &quot;language description&quot; extension whose name matches this attribute&apos;s value.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully-qualified name of the class that will be generated to serve as the implementation of this extension. This class will be assigned the given name and located in the given package in the currently selected project. (The package will be created if it does not already exist.)
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.services.ISourceFormatter"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/hoverHelper.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/hoverHelper.exsd
new file mode 100644
index 000000000..4636242b1
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/hoverHelper.exsd
@@ -0,0 +1,123 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.metatooling" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.imp.metatooling" id="HoverHelper" name="IMP IDE Hover Helper"/>
+ </appinfo>
+ <documentation>
+ The org.eclips.imp.editor.hoverHelper extension point allows providers to provide hover help. The provider specifies what languages it can provide hover help for. The provider has to implement the IHoverHelper interface. It will be presented with an IModel and a location, and from this combination
+returns the appropriate context-sensitive hover help.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="hoverHelper"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="hoverHelper">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully-qualified name of the class that will be generated to serve as the implementation of this extension. This class will be assigned the given name and located in the given package in the currently selected project. (The package will be created if it does not already exist.)
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.services.IHoverHelper"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of the language to which this service applies. There must be a corresponding &quot;language description&quot; extension whose name matches this attribute&apos;s value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ &lt;extension
+ point=&quot;org.eclipse.imp.hoverHelper&quot;&gt;
+ &lt;hoverhelper
+ class=&quot;org.eclipse.imp.DefaultHoverHelper&quot;
+ language=&quot;*&quot;
+ name=&quot;Default Hover Helper&quot;
+ id=&quot;org.eclipse.imp.hoverhelper.default&quot;/&gt;
+ &lt;/extension&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiInfo"/>
+ </appinfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ See org.eclipse.imp.DefaultHoverHelper.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="copyright"/>
+ </appinfo>
+ <documentation>
+ Licensed Materials - Property of IBM,
+ (c) Copyright IBM Corp. 1998, 2004 All Rights Reserved
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/hyperLink.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/hyperLink.exsd
new file mode 100644
index 000000000..c3a02c067
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/hyperLink.exsd
@@ -0,0 +1,112 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="hyperLink" name="IMP IDE Hyperlink Detector"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="hyperlinkDetector"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="hyperlinkDetector">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully-qualified name of the class that will be generated to serve as the implementation of this extension. This class will be assigned the given name and located in the given package in the currently selected project. (The package will be created if it does not already exist.)
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.services.ISourceHyperlinkDetector"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of the language to which this service applies. There must be a corresponding &quot;language description&quot; extension whose name matches this attribute&apos;s value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/imageDecorator.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/imageDecorator.exsd
new file mode 100644
index 000000000..5b0a28669
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/imageDecorator.exsd
@@ -0,0 +1,112 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="imageDecorator" name="Image Decorator"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="imageDecorator"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="imageDecorator">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully-qualified name of the class that will be generated to serve as the implementation of this extension. This class will be assigned the given name and located in the given package in the currently selected project. (The package will be created if it does not already exist.)
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.runtime.OutlineLabelProvider.IElementImageProvider"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of the language to which this service applies. There must be a corresponding &quot;language description&quot; extension whose name matches this attribute&apos;s value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/indexContributor.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/indexContributor.exsd
new file mode 100644
index 000000000..0f17287a3
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/indexContributor.exsd
@@ -0,0 +1,129 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.metatooling">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.metatooling" id="index" name="IMP Index of shared artifacts"/>
+ </appInfo>
+ <documentation>
+ The org.eclipse.imp.indexContributor extension point allows contributors to define and share artifacts through a central index. What is kept in the index, and how to access it, is left up to the implementors of the programming language.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <documentation>
+ Provide an implementation of an index of shared artifact of programs written for a given language. The actual contents is diverse and depends on the lanuage used.
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="indexContributor"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="indexContributor">
+ <annotation>
+ <documentation>
+ &lt;p&gt;
+Index -- an alphabetical listing of names and topics along with locations where they are discussed -- Wordnet Search
+&lt;br&gt;
+
+&lt;p&gt;
+Defines a shared index for a given programming language. Depending on the nature of the programming language, the index contains widely varying items, such as classes and interfaces (in the case of Java) and macros (in the case of C).
+&lt;p&gt;
+Support for persistence is provided, but the information discovery for the index is very much language specific and is unsupported.
+Furthermore, the actual contents specification is also left up to the language contributor.
+&lt;p&gt;
+The extension point serves mostly as a central registration location for language-specific indices.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of the language to which this service applies. There must be a corresponding &quot;language description&quot; extension whose name matches this attribute&apos;s value.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully-qualified name of the class that will be generated to serve as the implementation of this extension. This class will be assigned the given name and located in the given package in the currently selected project. (The package will be created if it does not already exist.)
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.indexing.IndexContributorBase"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 1.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ Contributor should implement the &lt;tt&gt;org.eclipse.imp.Index&lt;/tt&gt; class.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ org.eclipse.imp.Index
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/labelProvider.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/labelProvider.exsd
new file mode 100644
index 000000000..b50c6a268
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/labelProvider.exsd
@@ -0,0 +1,112 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="labelProvider" name="Label Provider"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="labelProvider"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="labelProvider">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully-qualified name of the class that will be generated to serve as the implementation of this extension. This class will be assigned the given name and located in the given package in the currently selected project. (The package will be created if it does not already exist.)
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.jface.viewers.ILabelProvider"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of the language to which this service applies. There must be a corresponding &quot;language description&quot; extension whose name matches this attribute&apos;s value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/languageDescription.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/languageDescription.exsd
new file mode 100644
index 000000000..5944f344a
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/languageDescription.exsd
@@ -0,0 +1,196 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="languageDescription" name="IMP Programming Language Description"/>
+ </appInfo>
+ <documentation>
+ The org.eclipse.imp.runtime.languageDescription extension points allows contributors to describe a programming language by providing attributes such as a name for the language, synonyms, a description, and a URL with more information on the programming language.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="language"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="language">
+ <annotation>
+ <documentation>
+ Defines a programming language name and associates with it a set of file-name extensions and other meta-data.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ The case-insensitive canonical name for this programming language, used in part to identify language service implementations intended to support this language. Examples:
+&lt;ul&gt;
+&lt;li&gt;Java
+&lt;li&gt;FORTRAN
+&lt;li&gt;Lisp
+&lt;li&gt;C
+&lt;li&gt;C#
+&lt;li&gt;Oberon
+&lt;li&gt;...
+&lt;/ul&gt;
+&lt;p&gt;
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="description" type="string" use="required">
+ <annotation>
+ <documentation>
+ The human-readable description of the language. Examples:
+&lt;ul&gt;
+&lt;li&gt;If the language is &quot;Python&quot;, the description might be &quot;The script language designed by Guido van Rossum&quot;
+&lt;li&gt;If the language is &quot;ActiveJava&quot;, the description might be &quot;An extension of Java with Actors&quot;
+&lt;/ul&gt;
+Descriptions are not directly used by the IMP IDE, but can be used by humans to resolve ambiguities for common programming language names.
+&lt;p&gt;
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="extensions" type="string" use="required">
+ <annotation>
+ <documentation>
+ A comma-separated list identifying the file name extensions for source files in this language, excluding any leading &quot;.&quot;. For C++, the extensions could be &quot;hpp,cpp,hxx,cxx&quot;. For a parser generator, it could be &quot;g&quot;. For ant scripts, it would be &quot;xml&quot;.
+
+In the latter two cases, the input could be ambiguous; multiple languages use the extension &quot;g&quot; and &quot;xml&quot;. See the validator attribute to define a user-defined validation class to verify the contents of the file actually corresponds to the programming language being defined.
+&lt;p&gt;
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="derivedFrom" type="string">
+ <annotation>
+ <documentation>
+ The canonical name of the language from which this language is derived, if any. Examples:
+&lt;ul&gt;
+&lt;li&gt;&quot;XJ&quot; (Java with embedded XML syntax) would be derived from &quot;Java&quot;
+&lt;li&gt;&quot;LotusScript&quot; is derived from &quot;JavaScript&quot;
+&lt;li&gt;&quot;PHP&quot; is derived from &quot;HTML&quot;
+&lt;li&gt;&quot;HTML&quot; is derived from &quot;XML&quot;
+&lt;/ul&gt;
+&lt;p&gt;
+Derivation is used in determining inheritance relationships when locating language service implementations for a given language.
+For example, suppose a PHP source file is opened, but no PHP editor is available. Given the inheritance relationships above, IMP attempts to locate an HTML editor, and if none is found, an XML editor is located; failing that, a simple text editor is used.
+&lt;p&gt;
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="icon" type="string">
+ <annotation>
+ <documentation>
+ The file path to the icon that will appear in various views that display source file entities (e.g. the Package Explorer). The icon must reside in the plugin containing the language descriptor, and the path must be a valid resource location in that plugin.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="url" type="string">
+ <annotation>
+ <documentation>
+ The url for a web site that contains more information about this language.
+&lt;p&gt;
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="validatorClass" type="string">
+ <annotation>
+ <documentation>
+ The fully-qualified name of a class that can determine whether a given input file actually contains text in the given programming language. Useful for languages such as XML that have many dialects (e.g. Ant build scripts, Eclipse plugin descriptors, or DTD&apos;s). Examples:
+&lt;ul&gt;
+&lt;li&gt;A validator for the Ant script dialect of &quot;.xml&quot; files
+&lt;li&gt;A validator for JikesPG &quot;.g&quot; grammar files (&quot;.g&quot; extensions are used for the grammar files of several parser generators, including JikesPG, Yacc and Antlr).
+&lt;/ul&gt;
+The class must extend the LanguageValidator class. The validate method will be called with a project and a file to check whether the file&apos;s content is indeed in the expected programming language. Some validators may simply check that the project has the corresponding nature. Others may read a portion of the file&apos;s contents to check for some well-specified unique signature.
+&lt;p&gt;
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.language.LanguageValidator"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="natureID" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ Optionally, users can extend the LanguageValidator class. Its validate method will be called with a project and file
+before it is opened in an editor
+to verify compliance to the expected programming language. Some validators may want to check and see
+if the project has a given nature enabled. Others will want to open the file and the read the first line to
+check for a given unique signature.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ org.eclipse.imp.code.LanguageValidator
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/markOccurrences.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/markOccurrences.exsd
new file mode 100644
index 000000000..38dd7afd8
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/markOccurrences.exsd
@@ -0,0 +1,109 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="occurrenceIdentifier" name="Occurrence Identifier"/>
+ </appinfo>
+ <documentation>
+ This IDE service provides a detector for some definition of a kind of &quot;occurrence&quot;, along with the necessary meta-information needed to present it in the IDE user interface. There may be more than one implementation of this service for a given language.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="occurrenceIdentifier"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="occurrenceIdentifier">
+ <complexType>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.services.IOccurrenceMarker"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiInfo"/>
+ </appinfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/modelListener.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/modelListener.exsd
new file mode 100644
index 000000000..47f6ef3f3
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/modelListener.exsd
@@ -0,0 +1,124 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.metatooling">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.metatooling" id="modelListener" name="IMP IDE Model Listener"/>
+ </appInfo>
+ <documentation>
+ The org.eclipse.imp.modelListener extension point allows providers to provide a model listener.
+Each time the text being edited is parsed and a new model is computed, the contributor will be notified.
+Contributor has to implement the IModelListener interface.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="listener"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="listener">
+ <annotation>
+ <documentation>
+ A user-defined listener that responds to a new model that has been computed for a given program.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully-qualified name of the class that will be generated to serve as the implementation of this extension. This class will be assigned the given name and located in the given package in the currently selected project. (The package will be created if it does not already exist.)
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.parser.IModelListener"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of the language to which this service applies. There must be a corresponding &quot;language description&quot; extension whose name matches this attribute&apos;s value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 1.0.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ &lt;extension
+ point=&quot;org.eclipse.imp.parser&quot;&gt;
+ &lt;parser
+ class=&quot;org.eclipse.imp.DefaultParser&quot;
+ language=&quot;*&quot;
+ name=&quot;Default Parser&quot;
+ id=&quot;org.eclipse.imp.parser.default&quot;/&gt;
+ &lt;/extension&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ See org.eclipse.imp.DefaultParser.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Licensed Materials - Property of IBM,
+ (c) Copyright IBM Corp. 1998, 2004 All Rights Reserved
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/modelTreeBuilder.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/modelTreeBuilder.exsd
new file mode 100644
index 000000000..0b23df759
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/modelTreeBuilder.exsd
@@ -0,0 +1,112 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="modelTreeBuilder" name="Model Tree Builder"/>
+ </appInfo>
+ <documentation>
+ Implementors of this extension point build a language-specific tree consisting of ModelTreeNodes that typically describes a portion of the structure of a given compilation unit, e.g., the portion that should presented in a structural outline view.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="treeBuilder"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="treeBuilder">
+ <complexType>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.services.base.TreeModelBuilderBase"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/outlineContentProvider.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/outlineContentProvider.exsd
new file mode 100644
index 000000000..8f5cc5e6e
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/outlineContentProvider.exsd
@@ -0,0 +1,112 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="outlineContentProvider" name="Outline Content Provider"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="outlineContentProvider"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="outlineContentProvider">
+ <complexType>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of the language to which this service applies. There must be a corresponding &quot;language description&quot; extension whose name matches this attribute&apos;s value.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully-qualified name of the class that will be generated to serve as the implementation of this extension. This class will be assigned the given name and located in the given package in the currently selected project. (The package will be created if it does not already exist.)
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.services.base.TreeModelBuilderBase"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/outliner.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/outliner.exsd
new file mode 100644
index 000000000..5f37134d9
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/outliner.exsd
@@ -0,0 +1,123 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.metatooling">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.metatooling" id="Outliner" name="IMP IDE Outliner"/>
+ </appInfo>
+ <documentation>
+ The org.eclips.imp.editor.outliner extension point allows providers to provide outline view contents. The provider specifies what languages it can provide an outline for. The provider has to implement the IOutliner interface. It will be presented with an IModel, and from this update the Outline view to show the appropriate outline.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="outliner"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="outliner">
+ <annotation>
+ <documentation>
+ Defines a &quot;source outliner&quot; language service for the given language, responsible for populating the &quot;Outline View&quot; with items taken from the source program&apos;s structure.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully-qualified name for the class that implements IOutliner.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.services.IOutliner"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ The programming language for which this outliner can generate an outline. There must be a corresponding &quot;language description&quot; extension whose name matches this attribute&apos;s value.
+Examples: &quot;C&quot;, &quot;php&quot;, &quot;Java&quot;, &quot;Lisp&quot;, etc
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ &lt;extension
+ point=&quot;org.eclipse.imp.outliner&quot;&gt;
+ &lt;outliner
+ class=&quot;org.eclipse.imp.DefaultOutliner&quot;
+ language=&quot;*&quot;
+ name=&quot;Default Outliner&quot;
+ id=&quot;org.eclipse.imp.outliner.default&quot;/&gt;
+ &lt;/extension&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ See org.eclipse.imp.DefaultOutliner.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Licensed Materials - Property of IBM,
+ (c) Copyright IBM Corp. 1998, 2004 All Rights Reserved
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/parser.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/parser.exsd
new file mode 100644
index 000000000..da5b49038
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/parser.exsd
@@ -0,0 +1,122 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.metatooling" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.imp.metatooling" id="parser" name="IMP IDE Parser"/>
+ </appinfo>
+ <documentation>
+ The org.eclipse.imp.parser extension point allows providers to provide a language parser and lexer. The provider specifies what languages it can parse. The provider must implement the IParseController interface. It will be presented with an IDocument and is responsible for producing an AST (abstract syntax tree) of some sort.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="parser"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="parser">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully-qualified name of the class that will be generated to serve as the implementation of this extension. This class will be assigned the given name and located in the given package in the currently selected project. (The package will be created if it does not already exist.)
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.parser.IParseController"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of the language to which this service applies. There must be a corresponding &quot;language description&quot; extension whose name matches this attribute&apos;s value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 1.0.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ &lt;extension
+ point=&quot;org.eclipse.imp.parser&quot;&gt;
+ &lt;parser
+ class=&quot;org.eclipse.imp.DefaultParser&quot;
+ language=&quot;*&quot;
+ name=&quot;Default Parser&quot;
+ id=&quot;org.eclipse.imp.parser.default&quot;/&gt;
+ &lt;/extension&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiInfo"/>
+ </appinfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ See org.eclipse.imp.DefaultParser.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="copyright"/>
+ </appinfo>
+ <documentation>
+ Licensed Materials - Property of IBM,
+ (c) Copyright IBM Corp. 1998, 2004 All Rights Reserved
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/preferencesDialog.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/preferencesDialog.exsd
new file mode 100644
index 000000000..c7746bb45
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/preferencesDialog.exsd
@@ -0,0 +1,136 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="preferencesDialog" name="Preferences Dialog"/>
+ </appInfo>
+ <documentation>
+ An extension point for adding preferences pages for specific IMP-based IDEs.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="preferencesDialog"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ An id for the preferences page that is used internally to refer to the page. For instance, the id of this page will be referenced by any pages that are nested under it in the preferences menu
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string" use="required">
+ <annotation>
+ <documentation>
+ A human-sensible name for the page; will be displayed as the title of the page
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="preferencesDialog">
+ <complexType>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of the language to which this service applies. There must be a corresponding &quot;language description&quot; extension whose name matches this attribute&apos;s value.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully-qualified name of the class that will be generated to serve as the implementation of this extension. This class will be assigned the given name and located in the given package in the currently selected project. (The package will be created if it does not already exist.)
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.preferences.IMPTabbedPreferencesPage"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="fields" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of a &apos;prefspecs&apos; (.pfsp) file that contains a specification of the preferences fields that are to be put onto this page. If left blank then the page will be empty. [NOTE: Features to make use of this field are still under development.]
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.wizards.ExtensionPointWizardPage.FileBrowse"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="category" type="string">
+ <annotation>
+ <documentation>
+ The category in the preferences menu under which the new preferences page will be listed, if any. To nest the new page under an existing page, provide the id of the existing page; to have the new page listed at the top level, leave blank. (If you provide a category that does not exist, you will receive a runtime error message.)
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="alternative" type="string">
+ <annotation>
+ <documentation>
+ Use this to generate a simple page with a brief message entered here.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/preferencesSpecification.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/preferencesSpecification.exsd
new file mode 100644
index 000000000..cee74a654
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/preferencesSpecification.exsd
@@ -0,0 +1,166 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="preferencesSpecification" name="Preferences Specification"/>
+ </appInfo>
+ <documentation>
+ An extension point for adding specifications for preferences for IMP-based IDEs. Preferences specifications are written in the prefspecs language.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="preferencesSpecification"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ Omitted
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string" use="required">
+ <annotation>
+ <documentation>
+ Omitted
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="preferencesSpecification">
+ <complexType>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of the language to which this service applies. There must be a corresponding &quot;language description&quot; extension whose name matches this attribute&apos;s value.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="template" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully-qualified name of the template file from which the skeleton preferences specification will be generated. Predefined templates are provided org.eclipse.imp.preferences/templates.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.wizards.ExtensionPointWizardPage$FileBrowse"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="fileName" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name to give to the preferences-specification file.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="pagePackage" type="string" use="required">
+ <annotation>
+ <documentation>
+ The package in the IDE plugin project into which the preferences-specification file will be generated. This will also be the package in which preferences-related classes that are based on the specification will be generated.
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.wizards.ExtensionPointWizardPage$PackageBrowse"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="pageClassNameBase" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name to be used as the basis for naming the preferences-related classes that will be generated. For example, if the name base is &quot;MylangPreferences&quot;, then classes will be generated with names such as &quot;MylangPreferencesInitializer&quot;, &quot;MylangPreferencesConstants&quot;, etc.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="pageName" type="string" use="required">
+ <annotation>
+ <documentation>
+ A human-suitable name for the preferences page that will be generated. This name will be the basis for the name of the preferences specification (as used in the specification file), the name that appears in the preferences menu, and the name on the preferences page.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="pageId" type="string" use="required">
+ <annotation>
+ <documentation>
+ An id for programmatic reference to the preference page that will be generated. Ids of preference pages are used, for example, in organizing the hierarchy of items in the preferences menu.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="category" type="string">
+ <annotation>
+ <documentation>
+ The category in the preferences menu under which the new preferences page will be listed, if any. To nest the new page under an existing page, provide the id of the existing page; to have the new page listed at the top level, leave blank. (If you provide a category that does not exist, you will receive a runtime error message.)
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="alternative" type="string">
+ <annotation>
+ <documentation>
+ Use this to generate a simple page with a brief message entered here.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/refactoringContributions.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/refactoringContributions.exsd
new file mode 100644
index 000000000..e5d32cd59
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/refactoringContributions.exsd
@@ -0,0 +1,112 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="refactoringContributions" name="Refactoring Contributions"/>
+ </appInfo>
+ <documentation>
+ Contributors provide refactorings (behavior-preserving source-to-source transformations) for the given language.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="refactoringContributor"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="refactoringContributor">
+ <complexType>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.services.IRefactoringContributor"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/referenceResolvers.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/referenceResolvers.exsd
new file mode 100644
index 000000000..ad8159e25
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/referenceResolvers.exsd
@@ -0,0 +1,112 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="referenceResolvers" name="IMP Reference Resolver"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="referenceResolver"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="referenceResolver">
+ <complexType>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.services.IReferenceResolver"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/toggleBreakpointHandler.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/toggleBreakpointHandler.exsd
new file mode 100644
index 000000000..0c64eeead
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/toggleBreakpointHandler.exsd
@@ -0,0 +1,106 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="toggleBreakpointHandler" name="Toggle Breakpoint Handler"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="toggleBreakpointHandler">
+ <complexType>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.imp.services.IToggleBreakpointsHandler"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/tokenColorer.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/tokenColorer.exsd
new file mode 100644
index 000000000..c09684a5f
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/tokenColorer.exsd
@@ -0,0 +1,122 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.metatooling">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.metatooling" id="tokenColorer" name="IMP IDE Token Colorer"/>
+ </appInfo>
+ <documentation>
+ This extension point allows providers to provide coloring hints for syntax-driven coloring of a document. The provider specifies what languages it can provide colorings for. The provider has to implement the ITokenColorer interface. It will be presented with a token, and should return its suggested text color and font.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="tokenColorer"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="tokenColorer">
+ <annotation>
+ <documentation>
+ The org.eclips.imp.editor.tokenColorer allowes contributors to provide coloring advise for a given set of tokens.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully-qualified name of the class that will be generated to serve as the implementation of this extension. This class will be assigned the given name and located in the given package in the currently selected project. (The package will be created if it does not already exist.)
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.imp.services.ITokenColorer"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of the language to which this service applies. There must be a corresponding &quot;language description&quot; extension whose name matches this attribute&apos;s value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ &lt;extension
+ point=&quot;org.eclipse.imp.outliner&quot;&gt;
+ &lt;outliner
+ class=&quot;org.eclipse.imp.DefaultOutliner&quot;
+ language=&quot;*&quot;
+ name=&quot;Default Outliner&quot;
+ id=&quot;org.eclipse.imp.outliner.default&quot;/&gt;
+ &lt;/extension&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ See org.eclipse.imp.DefaultOutliner.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Licensed Materials - Property of IBM,
+ (c) Copyright IBM Corp. 1998, 2004 All Rights Reserved
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/viewerFilter.exsd b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/viewerFilter.exsd
new file mode 100644
index 000000000..b3789dc33
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/schema/viewerFilter.exsd
@@ -0,0 +1,112 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.imp.runtime">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.imp.runtime" id="viewerFilter" name="Program Entity Viewer Filter"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="viewerFilter"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="viewerFilter">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully-qualified name of the class that will be generated to serve as the implementation of this extension. This class will be assigned the given name and located in the given package in the currently selected project. (The package will be created if it does not already exist.)
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.jface.viewers.ViewerFilter"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="language" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of the language to which this service applies. There must be a corresponding &quot;language description&quot; extension whose name matches this attribute&apos;s value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/ActionMessages.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/ActionMessages.java
new file mode 100644
index 000000000..b0cb25d67
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/ActionMessages.java
@@ -0,0 +1,36 @@
+package org.eclipse.imp.actions;
+
+import org.eclipse.osgi.util.NLS;
+
+public class ActionMessages extends NLS {
+ private static final String BUNDLE_NAME= "org.eclipse.imp.actions.ActionMessages"; //$NON-NLS-1$
+
+ public static String OpenAction_label;
+ public static String OpenAction_tooltip;
+ public static String OpenAction_description;
+ public static String OpenAction_declaration_label;
+ public static String OpenAction_select_element;
+
+ public static String OpenAction_error_messageBadSelection;
+ public static String OpenAction_error_title;
+ public static String OpenAction_error_problem_opening_editor;
+ public static String OpenAction_error_message;
+ public static String OpenAction_error_messageProblems;
+ public static String OpenAction_error_messageArgs;
+ public static String OpenAction_multistatus_message;
+
+ public static String RulerEnableDisableBreakpointAction_0;
+ public static String RulerEnableDisableBreakpointAction_1;
+ public static String RulerEnableDisableBreakpointAction_2;
+ public static String RulerEnableDisableBreakpointAction_3;
+
+ public static String NewWizardsActionGroup_new;
+
+ private ActionMessages() {
+ // no instance
+ }
+
+ static {
+ NLS.initializeMessages(BUNDLE_NAME, ActionMessages.class);
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/ActionMessages.properties b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/ActionMessages.properties
new file mode 100644
index 000000000..891bfb48c
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/ActionMessages.properties
@@ -0,0 +1,20 @@
+OpenAction_label=Open Declaration
+OpenAction_tooltip=Opens the declaration of the entity reference under the cursor
+OpenAction_description=Opens the declaration of the entity reference under the cursor
+OpenAction_declaration_label=&Open Declaration
+OpenAction_select_element=&Select or enter the element to open:
+
+OpenAction_error_title=Open
+OpenAction_error_message=Problems opening an editor.
+OpenAction_error_messageArgs= Cannot open default editor on {0}: \n{1}
+OpenAction_error_messageProblems= Problems Opening Editor
+OpenAction_multistatus_message=See details for editors that could not be opened.
+OpenAction_error_messageBadSelection=Current text selection does not resolve to a declaration
+OpenAction_error_problem_opening_editor=Problem opening editor for ''{0}'': ''{1}''
+
+RulerEnableDisableBreakpointAction_0=Error
+RulerEnableDisableBreakpointAction_1=Failed to toggle breakpoint enablement
+RulerEnableDisableBreakpointAction_2=&Disable Breakpoint
+RulerEnableDisableBreakpointAction_3=&Enable Breakpoint
+
+NewWizardsActionGroup_new=New...
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/FoldingMessages.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/FoldingMessages.java
new file mode 100644
index 000000000..7470149b0
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/FoldingMessages.java
@@ -0,0 +1,65 @@
+package org.eclipse.imp.actions;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class FoldingMessages {
+ private static final String BUNDLE_NAME= "org.eclipse.imp.actions.FoldingMessages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE= ResourceBundle.getBundle(BUNDLE_NAME);
+
+ private FoldingMessages() {
+ // no instance
+ }
+
+ /**
+ * Returns the resource string associated with the given key in the resource bundle. If there isn't
+ * any value under the given key, the key is returned.
+ *
+ * @param key the resource key
+ * @return the string
+ */
+ public static String getString(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+
+ /**
+ * Returns the resource bundle managed by the receiver.
+ *
+ * @return the resource bundle
+ */
+ public static ResourceBundle getResourceBundle() {
+ return RESOURCE_BUNDLE;
+ }
+
+ /**
+ * Returns the formatted resource string associated with the given key in the resource bundle.
+ * <code>MessageFormat</code> is used to format the message. If there isn't any value
+ * under the given key, the key is returned.
+ *
+ * @param key the resource key
+ * @param arg the message argument
+ * @return the string
+ */
+ public static String getFormattedString(String key, Object arg) {
+ return getFormattedString(key, new Object[] { arg });
+ }
+
+ /**
+ * Returns the formatted resource string associated with the given key in the resource bundle.
+ * <code>MessageFormat</code> is used to format the message. If there isn't any value
+ * under the given key, the key is returned.
+ *
+ * @param key the resource key
+ * @param args the message arguments
+ * @return the string
+ */
+ public static String getFormattedString(String key, Object[] args) {
+ return MessageFormat.format(getString(key), args);
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/FoldingMessages.properties b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/FoldingMessages.properties
new file mode 100644
index 000000000..1c6e95e50
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/FoldingMessages.properties
@@ -0,0 +1,34 @@
+Projection.ExpandAll.label= Expand &All
+Projection.ExpandAll.tooltip= Expands All Collapsed Regions
+Projection.ExpandAll.description= Expands any collapsed regions in the current editor
+Projection.ExpandAll.image=
+
+Projection.Expand.label= E&xpand
+Projection.Expand.tooltip= Expands the Current Collapsed Region
+Projection.Expand.description= Expands the collapsed region at the current selection
+Projection.Expand.image=
+
+Projection.CollapseAll.label= Collapse A&ll
+Projection.CollapseAll.tooltip= Collapses All Expanded Regions
+Projection.CollapseAll.description= Collapse any expanded regions in the current editor
+Projection.CollapseAll.image=
+
+Projection.Collapse.label= Colla&pse
+Projection.Collapse.tooltip= Collapses the Current Region
+Projection.Collapse.description= Collapses the Current Region
+Projection.Collapse.image=
+
+Projection.Restore.label= &Reset Structure
+Projection.Restore.tooltip= Restore the Original Folding Structure
+Projection.Restore.description= Restores the original folding structure
+Projection.Restore.image=
+
+Projection.CollapseComments.label= Collapse &Comments
+Projection.CollapseComments.tooltip= Collapses All Comments
+Projection.CollapseComments.description= Collapses all comments
+Projection.CollapseComments.image=
+
+Projection.CollapseMembers.label= Collapse &Members
+Projection.CollapseMembers.tooltip= Collapses All Members
+Projection.CollapseMembers.description= Collapses all members
+Projection.CollapseMembers.image=
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/OpenAction.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/OpenAction.java
new file mode 100644
index 000000000..a4b47c88b
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/OpenAction.java
@@ -0,0 +1,196 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.actions;
+
+import java.util.Iterator;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.imp.core.IMPMessages;
+import org.eclipse.imp.editor.EditorUtility;
+import org.eclipse.imp.editor.UniversalEditor;
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.language.ServiceFactory;
+import org.eclipse.imp.model.ICompilationUnit;
+import org.eclipse.imp.model.ISourceEntity;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.parser.ISourcePositionLocator;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.imp.services.IReferenceResolver;
+import org.eclipse.imp.actions.ActionMessages;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.util.OpenStrategy;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchSite;
+import org.eclipse.ui.PartInitException;
+
+/**
+ * This action opens a Java editor on a Java element or file.
+ * <p>
+ * The action is applicable to selections containing elements of type <code>ICompilationUnit</code>, <code>IMember</code> or <code>IFile</code>.
+ *
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ *
+ * @since 2.0
+ */
+public class OpenAction extends SelectionDispatchAction {
+ private UniversalEditor fEditor;
+
+ /**
+ * Creates a new <code>OpenAction</code>. The action requires that the selection provided by the site's selection provider is of type <code>
+ * org.eclipse.jface.viewers.IStructuredSelection</code>.
+ *
+ * @param site
+ * the site providing context information for this action
+ */
+ public OpenAction(IWorkbenchSite site) {
+ super(site);
+ setText(ActionMessages.OpenAction_label);
+ setToolTipText(ActionMessages.OpenAction_tooltip);
+ setDescription(ActionMessages.OpenAction_description);
+// PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.OPEN_ACTION);
+ }
+
+ /**
+ * Note: This constructor is for internal use only. Clients should not call this constructor.
+ *
+ * @param editor
+ * the Java editor
+ */
+ public OpenAction(UniversalEditor editor) {
+ this(editor.getEditorSite());
+ fEditor= editor;
+ setText(ActionMessages.OpenAction_declaration_label);
+ setEnabled(EditorUtility.getEditorInputModelElement(fEditor, false) != null);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on SelectionDispatchAction.
+ */
+ public void selectionChanged(ITextSelection selection) {
+ }
+
+ /*
+ * (non-Javadoc) Method declared on SelectionDispatchAction.
+ */
+ public void selectionChanged(IStructuredSelection selection) {
+ setEnabled(checkEnabled(selection));
+ }
+
+ private boolean checkEnabled(IStructuredSelection selection) {
+ if (selection.isEmpty())
+ return false;
+ for(Iterator iter= selection.iterator(); iter.hasNext();) {
+ Object element= iter.next();
+ if (element instanceof ISourceEntity)
+ continue;
+ if (element instanceof IFile)
+ continue;
+ if (element instanceof IStorage)
+ continue;
+ return false;
+ }
+ return true;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on SelectionDispatchAction.
+ */
+ public void run(ITextSelection selection) {
+ if (!isProcessable())
+ return;
+
+ IParseController parseCtlr= fEditor.getParseController();
+ ISourcePositionLocator locator= parseCtlr.getSourcePositionLocator();
+ int offset= selection.getOffset();
+ int endOffset= selection.getOffset() + selection.getLength() - 1;
+ Object node= locator.findNode(parseCtlr.getCurrentAst(), offset, endOffset);
+
+ if (node != null) {
+ Language lang= parseCtlr.getLanguage();
+ IReferenceResolver resolver= ServiceFactory.getInstance().getReferenceResolver(lang);
+
+ if (resolver != null) {
+ Object target= resolver.getLinkTarget(node, parseCtlr);
+ if (target != null && target != node) {
+ IPath path= locator.getPath(target);
+ int targetOffset= locator.getStartOffset(target);
+ int targetLength= locator.getLength(target);
+
+ try {
+ IEditorPart editor= EditorUtility.openInEditor(path);
+ EditorUtility.revealInEditor(editor, targetOffset, targetLength);
+ } catch (PartInitException e) {
+ RuntimePlugin.getInstance().logException("Unable to open declaration", e);
+ }
+ }
+ }
+ }
+ }
+
+ private boolean isProcessable() {
+ ISourceEntity se= EditorUtility.getEditorInputModelElement(fEditor, false);
+ if (fEditor != null) {
+ if (se instanceof ICompilationUnit /*&& !JavaModelUtil.isPrimary((ICompilationUnit) se)*/)
+ return true; // can process non-primary working copies
+ }
+ return false;
+ }
+
+
+ /*
+ * (non-Javadoc) Method declared on SelectionDispatchAction.
+ */
+ public void run(IStructuredSelection selection) {
+ if (!checkEnabled(selection))
+ return;
+ run(selection.toArray());
+ }
+
+ /**
+ * Note: this method is for internal use only. Clients should not call this method.
+ *
+ * @param elements
+ * the elements to process
+ */
+ public void run(Object[] elements) {
+ if (elements == null)
+ return;
+ for(int i= 0; i < elements.length; i++) {
+ Object element= elements[i];
+ try {
+ boolean activateOnOpen= fEditor != null ? true : OpenStrategy.activateOnOpen();
+ OpenActionUtil.open(element, activateOnOpen);
+ } catch (PartInitException x) {
+ String name= null;
+ if (element instanceof ISourceEntity) {
+ name= ((ISourceEntity) element).getName();
+ } else if (element instanceof IStorage) {
+ name= ((IStorage) element).getName();
+ } else if (element instanceof IResource) {
+ name= ((IResource) element).getName();
+ }
+ if (name != null) {
+ MessageDialog.openError(getShell(), ActionMessages.OpenAction_error_messageProblems, IMPMessages.format(
+ ActionMessages.OpenAction_error_messageArgs, new String[] { name, x.getMessage() }));
+ }
+ }
+ }
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/OpenActionUtil.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/OpenActionUtil.java
new file mode 100644
index 000000000..f8f674591
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/OpenActionUtil.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+package org.eclipse.imp.actions;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.imp.editor.EditorUtility;
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.language.ServiceFactory;
+import org.eclipse.imp.model.ISourceEntity;
+import org.eclipse.imp.services.ILabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.dialogs.ElementListSelectionDialog;
+
+public class OpenActionUtil {
+ private OpenActionUtil() {
+ // no instance.
+ }
+
+ /**
+ * Opens the editor on the given element and subsequently selects it.
+ */
+ public static void open(Object element) throws PartInitException {
+ open(element, true);
+ }
+
+ /**
+ * Opens the editor on the given element and subsequently selects it.
+ */
+ public static void open(Object element, boolean activate) throws PartInitException {
+ IEditorPart part= EditorUtility.openInEditor(element, activate);
+
+ if (element instanceof ISourceEntity) {
+ EditorUtility.revealInEditor(part, (ISourceEntity) element);
+ }
+ }
+
+ /**
+ * Filters out source references from the given code resolve results. A utility method that can be called by subclasses.
+ */
+ public static List<ISourceEntity> filterResolveResults(ISourceEntity[] codeResolveResults) {
+ int nResults= codeResolveResults.length;
+ List<ISourceEntity> refs= new ArrayList<ISourceEntity>(nResults);
+
+ for(int i= 0; i < nResults; i++) {
+// if (codeResolveResults[i] instanceof ISourceReference) {
+ refs.add(codeResolveResults[i]);
+// }
+ }
+ return refs;
+ }
+
+ /**
+ * Shows a dialog for resolving an ambiguous source entity. Utility method that can be called by subclasses.
+ */
+ public static ISourceEntity selectSourceEntity(ISourceEntity[] entities, Shell shell, String title, String message,
+ Language lang) {
+ int nResults= entities.length;
+ if (nResults == 0)
+ return null;
+ if (nResults == 1)
+ return entities[0];
+ ILabelProvider labelProvider= ServiceFactory.getInstance().getLabelProvider(lang);
+// int flags= JavaElementLabelProvider.SHOW_DEFAULT | JavaElementLabelProvider.SHOW_QUALIFIED | JavaElementLabelProvider.SHOW_ROOT;
+ ElementListSelectionDialog dialog= new ElementListSelectionDialog(shell, labelProvider);
+ dialog.setTitle(title);
+ dialog.setMessage(message);
+ dialog.setElements(entities);
+ if (dialog.open() == Window.OK) {
+ Object[] selection= dialog.getResult();
+ if (selection != null && selection.length > 0) {
+ nResults= selection.length;
+ for(int i= 0; i < nResults; i++) {
+ Object current= selection[i];
+ if (current instanceof ISourceEntity) {
+ return (ISourceEntity) current;
+ }
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/RulerEnableDisableBreakpointAction.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/RulerEnableDisableBreakpointAction.java
new file mode 100644
index 000000000..c1c2a6366
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/RulerEnableDisableBreakpointAction.java
@@ -0,0 +1,68 @@
+package org.eclipse.imp.actions;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.ui.actions.RulerBreakpointAction;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.text.source.IVerticalRulerInfo;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.IUpdate;
+
+public class RulerEnableDisableBreakpointAction extends RulerBreakpointAction implements IUpdate, MouseListener {
+ private IBreakpoint fBreakpoint;
+
+ public RulerEnableDisableBreakpointAction(ITextEditor editor, IVerticalRulerInfo info) {
+ super(editor, info);
+ setText(ActionMessages.RulerEnableDisableBreakpointAction_2);
+ update();
+
+ Control control= info.getControl();
+
+ if (control != null && !control.isDisposed())
+ control.addMouseListener(this);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ if (fBreakpoint != null) {
+ try {
+ fBreakpoint.setEnabled(!fBreakpoint.isEnabled());
+ } catch (CoreException e) {
+ ErrorDialog.openError(getEditor().getSite().getShell(), ActionMessages.RulerEnableDisableBreakpointAction_0, ActionMessages.RulerEnableDisableBreakpointAction_1, e.getStatus());
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.texteditor.IUpdate#update()
+ */
+ public void update() {
+ fBreakpoint = getBreakpoint();
+ setEnabled(fBreakpoint != null);
+ if (fBreakpoint != null) {
+ try {
+ if (fBreakpoint.isEnabled()) {
+ setText(ActionMessages.RulerEnableDisableBreakpointAction_2);
+ } else {
+ setText(ActionMessages.RulerEnableDisableBreakpointAction_3);
+ }
+ } catch (CoreException e) {
+ }
+ } else {
+ setText(ActionMessages.RulerEnableDisableBreakpointAction_2);
+ }
+ }
+
+ public void mouseDoubleClick(MouseEvent e) { }
+
+ public void mouseDown(MouseEvent e) {
+ update();
+ }
+
+ public void mouseUp(MouseEvent e) { }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/SelectionDispatchAction.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/SelectionDispatchAction.java
new file mode 100644
index 000000000..8d902646d
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/actions/SelectionDispatchAction.java
@@ -0,0 +1,248 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.actions;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchSite;
+
+/**
+ * Action that dispatches the <code>IAction#run()</code> and the <code>ISelectionChangedListener#selectionChanged</code> according to the type of the
+ * selection.
+ *
+ * <ul>
+ * <li>if selection is of type <code>ITextSelection</code> then <code>run(ITextSelection)</code> and <code>selectionChanged(ITextSelection)</code> is
+ * called.</li>
+ * <li>if selection is of type <code>IStructuredSelection</code> then <code>run(IStructuredSelection)</code> and <code>
+ * selectionChanged(IStructuredSelection)</code>
+ * is called.</li>
+ * <li>default is to call <code>run(ISelection)</code> and <code>
+ * selectionChanged(ISelection)</code>.</li>
+ * </ul>
+ *
+ * <p>
+ * Note: This class is not intended to be subclassed outside the JDT UI plug-in.
+ * </p>
+ *
+ * @since 2.0
+ */
+public abstract class SelectionDispatchAction extends Action implements ISelectionChangedListener {
+ private IWorkbenchSite fSite;
+
+ private ISelectionProvider fSpecialSelectionProvider;
+
+ /**
+ * Creates a new action with no text and no image.
+ * <p>
+ * Configure the action later using the set methods.
+ * </p>
+ *
+ * @param site
+ * the site this action is working on
+ */
+ protected SelectionDispatchAction(IWorkbenchSite site) {
+ Assert.isNotNull(site);
+ fSite= site;
+ }
+
+ /**
+ * Creates a new action with no text and no image
+ *
+ * <p>
+ * Configure the action later using the set methods.
+ * </p>
+ *
+ * @param site
+ * the site this action is working on
+ * @param provider
+ * a special selection provider which is used instead of the site's selection provider or <code>null</code> to use the site's selection
+ * provider. Clients can for example use a {@link ConvertingSelectionProvider} to first convert a selection before passing it to the action.
+ *
+ * @since 3.2
+ * @deprecated Use {@link #setSpecialSelectionProvider(ISelectionProvider)} instead. This constructor will be removed after 3.2 M5.
+ */
+ protected SelectionDispatchAction(IWorkbenchSite site, ISelectionProvider provider) {
+ this(site);
+ setSpecialSelectionProvider(provider);
+ }
+
+ /**
+ * Returns the site owning this action.
+ *
+ * @return the site owning this action
+ */
+ public IWorkbenchSite getSite() {
+ return fSite;
+ }
+
+ /**
+ * Returns the selection provided by the site owning this action.
+ *
+ * @return the site's selection
+ */
+ public ISelection getSelection() {
+ ISelectionProvider selectionProvider= getSelectionProvider();
+ if (selectionProvider != null)
+ return selectionProvider.getSelection();
+ else
+ return null;
+ }
+
+ /**
+ * Returns the shell provided by the site owning this action.
+ *
+ * @return the site's shell
+ */
+ public Shell getShell() {
+ return fSite.getShell();
+ }
+
+ /**
+ * Returns the selection provider managed by the site owning this action or the selection provider explicitly set in
+ * {@link #setSpecialSelectionProvider(ISelectionProvider)}.
+ *
+ * @return the site's selection provider
+ */
+ public ISelectionProvider getSelectionProvider() {
+ if (fSpecialSelectionProvider != null) {
+ return fSpecialSelectionProvider;
+ }
+ return fSite.getSelectionProvider();
+ }
+
+ /**
+ * Sets a special selection provider which will be used instead of the site's selection provider. This method should be used directly after constructing the
+ * action and before the action is registered as a selection listener. The invocation will not a perform a selection change notification.
+ *
+ * @param provider
+ * a special selection provider which is used instead of the site's selection provider or <code>null</code> to use the site's selection
+ * provider. Clients can for example use a {@link ConvertingSelectionProvider} to first convert a selection before passing it to the action.
+ *
+ * @since 3.2
+ */
+ public void setSpecialSelectionProvider(ISelectionProvider provider) {
+ fSpecialSelectionProvider= provider;
+ }
+
+ /**
+ * Updates the action's enablement state according to the given selection. This default implementation calls one of the <code>selectionChanged</code>
+ * methods depending on the type of the passed selection.
+ *
+ * @param selection
+ * the selection this action is working on
+ */
+ public void update(ISelection selection) {
+ dispatchSelectionChanged(selection);
+ }
+
+ /**
+ * Notifies this action that the given structured selection has changed. This default implementation calls
+ * <code>selectionChanged(ISelection selection)</code>.
+ *
+ * @param selection
+ * the new selection
+ */
+ public void selectionChanged(IStructuredSelection selection) {
+ selectionChanged((ISelection) selection);
+ }
+
+ /**
+ * Executes this actions with the given structured selection. This default implementation calls <code>run(ISelection selection)</code>.
+ *
+ * @param selection
+ * the selection
+ */
+ public void run(IStructuredSelection selection) {
+ run((ISelection) selection);
+ }
+
+ /**
+ * Notifies this action that the given text selection has changed. This default implementation calls <code>selectionChanged(ISelection selection)</code>.
+ *
+ * @param selection
+ * the new selection
+ */
+ public void selectionChanged(ITextSelection selection) {
+ selectionChanged((ISelection) selection);
+ }
+
+ /**
+ * Executes this actions with the given text selection. This default implementation calls <code>run(ISelection selection)</code>.
+ *
+ * @param selection
+ * the selection
+ */
+ public void run(ITextSelection selection) {
+ run((ISelection) selection);
+ }
+
+ /**
+ * Notifies this action that the given selection has changed. This default implementation sets the action's enablement state to <code>false</code>.
+ *
+ * @param selection
+ * the new selection
+ */
+ public void selectionChanged(ISelection selection) {
+ setEnabled(false);
+ }
+
+ /**
+ * Executes this actions with the given selection. This default implementation does nothing.
+ *
+ * @param selection
+ * the selection
+ */
+ public void run(ISelection selection) {
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IAction.
+ */
+ public void run() {
+ dispatchRun(getSelection());
+ }
+
+ /*
+ * (non-Javadoc) Method declared on ISelectionChangedListener.
+ */
+ public void selectionChanged(SelectionChangedEvent event) {
+ dispatchSelectionChanged(event.getSelection());
+ }
+
+ private void dispatchSelectionChanged(ISelection selection) {
+ if (selection instanceof IStructuredSelection) {
+ selectionChanged((IStructuredSelection) selection);
+ } else if (selection instanceof ITextSelection) {
+ selectionChanged((ITextSelection) selection);
+ } else {
+ selectionChanged(selection);
+ }
+ }
+
+ private void dispatchRun(ISelection selection) {
+ if (selection instanceof IStructuredSelection) {
+ run((IStructuredSelection) selection);
+ } else if (selection instanceof ITextSelection) {
+ run((ITextSelection) selection);
+ } else {
+ run(selection);
+ }
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/BuilderBase.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/BuilderBase.java
new file mode 100644
index 000000000..e55852db0
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/BuilderBase.java
@@ -0,0 +1,535 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.builder;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferenceConstants;
+import org.eclipse.imp.preferences.PreferencesService;
+import org.eclipse.imp.runtime.PluginBase;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.imp.utils.UnimplementedError;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.IConsoleManager;
+import org.eclipse.ui.console.MessageConsole;
+import org.eclipse.ui.console.MessageConsoleStream;
+
+public abstract class BuilderBase extends IncrementalProjectBuilder {
+ /**
+ * The name of the console used for any builders that don't provide an override
+ * of getConsoleName() to use their own unique console
+ */
+ public static final String IMP_BUILDER_CONSOLE= "IMP Builders";
+
+ /**
+ * @return the plugin associated with this builder instance
+ */
+ protected abstract PluginBase getPlugin();
+
+ /**
+ * @return the extension ID of this builder
+ */
+ public String getBuilderID() {
+ throw new UnimplementedError("Not implemented for builder for plug-in " + getPlugin().getID());
+ }
+
+ /**
+ * @return true iff the given file is a source file that this builder should compile.
+ */
+ protected abstract boolean isSourceFile(IFile file);
+
+ /**
+ * @return true iff the given file is a source file that this builder should scan
+ * for dependencies, but not compile as a top-level compilation unit.<br>
+ * <code>isNonRootSourceFile()</code> and <code>isSourceFile()</code> should never
+ * return true for the same file.
+ */
+ protected abstract boolean isNonRootSourceFile(IFile file);
+
+ /**
+ * @return true iff the given resource is an output folder
+ */
+ protected abstract boolean isOutputFolder(IResource resource);
+
+ /**
+ * Does whatever is necessary to "compile" the given "source file".
+ * @param file the "source file" to compile
+ * @param monitor used to indicate progress in the UI
+ */
+ protected abstract void compile(IFile file, IProgressMonitor monitor);
+
+ /**
+ * Collects compilation-unit dependencies for the given file, and records
+ * them via calls to <code>fDependency.addDependency()</code>.
+ */
+ protected abstract void collectDependencies(IFile file);
+
+ /**
+ * @return the ID of the marker type to be used to indicate compiler errors
+ */
+ protected abstract String getErrorMarkerID();
+
+ /**
+ * @return the ID of the marker type to be used to indicate compiler warnings
+ */
+ protected abstract String getWarningMarkerID();
+
+ /**
+ * @return the ID of the marker type to be used to indicate compiler information
+ * messages
+ */
+ protected abstract String getInfoMarkerID();
+
+ private final IResourceVisitor fResourceVisitor= new SourceCollectorVisitor();
+
+ private final IResourceDeltaVisitor fDeltaVisitor= new SourceDeltaVisitor();
+
+ private IPreferencesService fPrefService= null;
+
+ protected IPreferencesService getPreferencesService() {
+ if (fPrefService == null)
+ fPrefService= new PreferencesService(null, getPlugin().getLanguageID());
+ return fPrefService;
+ }
+
+ protected DependencyInfo fDependencyInfo;
+
+ private final Collection<IFile> fChangedSources= new HashSet<IFile>();
+
+ private final Collection<IFile> fSourcesToCompile= new HashSet<IFile>();
+
+ private final Collection<IFile> fSourcesForDeps= new HashSet<IFile>();
+
+ private final class SourceDeltaVisitor implements IResourceDeltaVisitor {
+ public boolean visit(IResourceDelta delta) throws CoreException {
+ return processResource(delta.getResource());
+ }
+ }
+
+ private class SourceCollectorVisitor implements IResourceVisitor {
+ public boolean visit(IResource res) throws CoreException {
+ return processResource(res);
+ }
+ }
+
+ private boolean processResource(IResource resource) {
+ if (resource instanceof IFile) {
+ IFile file= (IFile) resource;
+
+ if (file.exists()) {
+ if (isSourceFile(file) || isNonRootSourceFile(file)) {
+ fChangedSources.add(file);
+ }
+ }
+ return false;
+ } else if (isOutputFolder(resource)) {
+ return false;
+ }
+ return true;
+ }
+
+ private class AllSourcesVisitor implements IResourceVisitor {
+ private final Collection<IFile> fResult;
+
+ public AllSourcesVisitor(Collection<IFile> result) {
+ fResult= result;
+ }
+
+ public boolean visit(IResource resource) throws CoreException {
+ if (resource instanceof IFile) {
+ IFile file= (IFile) resource;
+
+ if (file.exists()) {
+ if (isSourceFile(file) || isNonRootSourceFile(file)) {
+ fResult.add(file);
+ }
+ }
+ return false;
+ } else if (isOutputFolder(resource)) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ protected DependencyInfo createDependencyInfo(IProject project) {
+ return new DependencyInfo(project);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected IProject[] build(int kind, Map args, IProgressMonitor monitor) {
+ IPreferencesService preferencesService = getPreferencesService();
+ if (preferencesService.getProject() == null) {
+ preferencesService.setProject(getProject());
+ }
+
+ fChangedSources.clear();
+ fSourcesForDeps.clear();
+ fSourcesToCompile.clear();
+
+ boolean partialDeps= true;
+ Collection<IFile> allSources= new ArrayList<IFile>();
+
+ if (fDependencyInfo == null || kind == FULL_BUILD || kind == CLEAN_BUILD) {
+ fDependencyInfo= createDependencyInfo(getProject());
+ try {
+ getProject().accept(new AllSourcesVisitor(allSources));
+ } catch (CoreException e) {
+ getPlugin().getLog().log(new Status(IStatus.ERROR, getPlugin().getID(), e.getLocalizedMessage(), e));
+ }
+ fSourcesForDeps.addAll(allSources);
+ // Collect deps now, so we can compile everything necessary in the case where
+ // we have no dep info yet (e.g. first build for this Eclipse invocation --
+ // we don't persist the dep info yet) but we've been asked to do an auto build
+ // b/c of workspace changes.
+ collectDependencies(monitor);
+ partialDeps= false;
+ }
+
+ if (kind == FULL_BUILD || kind == CLEAN_BUILD) {
+ clearMarkersOn(allSources);
+ }
+
+ try {
+ collectSourcesToCompile(monitor);
+ clearDependencyInfoForChangedFiles();
+ if (partialDeps) {
+ fSourcesForDeps.addAll(fSourcesToCompile);
+ fSourcesForDeps.addAll(fChangedSources);
+ collectDependencies(monitor);
+ }
+ compileNecessarySources(monitor);
+ // TODO Diagnostic output should be made conditional on the value of a language-specific preference
+ getConsoleStream().print(fDependencyInfo.toString());
+ } catch (CoreException e) {
+ getPlugin().writeErrorMsg("Build failed: " + e.getMessage());
+ }
+ return new IProject[0];
+ }
+
+ protected void compileNecessarySources(IProgressMonitor monitor) {
+ for(Iterator<IFile> iter= fSourcesToCompile.iterator(); iter.hasNext(); ) {
+ IFile srcFile= iter.next();
+
+ clearMarkersOn(srcFile);
+ if (isSourceFile(srcFile)) {
+ compile(srcFile, monitor);
+ }
+ }
+ }
+
+ protected void collectDependencies(IProgressMonitor monitor) {
+ for(IFile srcFile: fSourcesForDeps) {
+ collectDependencies(srcFile);
+ }
+ }
+
+ /**
+ * Clears all problem markers (all markers whose type derives from IMarker.PROBLEM)
+ * from the given file. A utility method for the use of derived builder classes.
+ */
+ protected void clearMarkersOn(IFile file) {
+ try {
+ // SMS 28 Mar 2007
+ // Clear the markers for this builder only (and clear all of them)
+ // (may be a simpler way to do this, given a more complex set up of
+ // marker types)
+ //file.deleteMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
+ file.deleteMarkers(getErrorMarkerID(), true, IResource.DEPTH_INFINITE);
+ file.deleteMarkers(getWarningMarkerID(), true, IResource.DEPTH_INFINITE);
+ file.deleteMarkers(getInfoMarkerID(), true, IResource.DEPTH_INFINITE);
+ } catch (CoreException e) {
+ }
+ }
+
+ protected void clearMarkersOn(Collection<IFile> files) {
+ for(IFile file: files) {
+ clearMarkersOn(file);
+ }
+ }
+
+ private void dumpSourceList(Collection<IFile> sourcesToCompile) {
+ MessageConsoleStream consoleStream= getConsoleStream();
+
+ for(Iterator<IFile> iter= sourcesToCompile.iterator(); iter.hasNext(); ) {
+ IFile srcFile= iter.next();
+
+ consoleStream.println(" " + srcFile.getFullPath());
+ }
+ }
+
+ /**
+ * Clears the dependency information maintained for all files marked as
+ * having changed (i.e. in <code>fSourcesToCompile</code>).
+ */
+ private void clearDependencyInfoForChangedFiles() {
+ for(Iterator<IFile> iter= fSourcesToCompile.iterator(); iter.hasNext(); ) {
+ IFile srcFile= iter.next();
+
+ fDependencyInfo.clearDependenciesOf(srcFile.getFullPath().toString());
+ }
+ }
+
+ protected boolean getDiagPreference() {
+ final IPreferencesService builderPrefSvc= getPlugin().getPreferencesService();
+ final IPreferencesService impPrefSvc= RuntimePlugin.getInstance().getPreferencesService();
+
+ boolean msgs= builderPrefSvc.isDefined(PreferenceConstants.P_EMIT_BUILDER_DIAGNOSTICS) ?
+ builderPrefSvc.getBooleanPreference(PreferenceConstants.P_EMIT_BUILDER_DIAGNOSTICS) :
+ impPrefSvc.getBooleanPreference(PreferenceConstants.P_EMIT_BUILDER_DIAGNOSTICS);
+ return msgs;
+ }
+
+ /**
+ * Visits the project delta, if any, or the entire project, and determines the set
+ * of files needed recompilation, and adds them to <code>fSourcesToCompile</code>.
+ * @param monitor
+ * @throws CoreException
+ */
+ private void collectSourcesToCompile(IProgressMonitor monitor) throws CoreException {
+ IResourceDelta delta= getDelta(getProject());
+ boolean emitDiags= getDiagPreference();
+
+ if (delta != null) {
+ if (emitDiags)
+ getConsoleStream().println("==> Scanning resource delta for project '" + getProject().getName() + "'... <==");
+ delta.accept(fDeltaVisitor);
+ if (emitDiags)
+ getConsoleStream().println("Delta scan completed for project '" + getProject().getName() + "'...");
+ } else {
+ if (emitDiags)
+ getConsoleStream().println("==> Scanning for source files in project '" + getProject().getName() + "'... <==");
+ getProject().accept(fResourceVisitor);
+ if (emitDiags)
+ getConsoleStream().println("Source file scan completed for project '" + getProject().getName() + "'...");
+ }
+ collectChangeDependents();
+ if (emitDiags) {
+ getConsoleStream().println("All files to compile:");
+ dumpSourceList(fSourcesToCompile);
+ }
+ }
+
+ // TODO This really *shouldn't* be transitive; the real problem w/ the LPGBuilder is that it
+ // doesn't account for transitive includes itself when computing its dependency info. That is,
+ // when file A includes B includes C, A should be marked as a dependent of C.
+ private void collectChangeDependents() {
+ if (fChangedSources.size() == 0) return;
+ Collection<IFile> changeDependents= new HashSet<IFile>();
+
+ changeDependents.addAll(fChangedSources);
+ // TODO RMF 1/28/2008 - Should enable the following messages based on a debugging flag visible in a prefs page
+ getConsoleStream().println("Changed files:");
+ dumpSourceList(changeDependents);
+
+ boolean changed= false;
+ do {
+ Collection<IFile> additions= new HashSet<IFile>();
+ scanSourceList(changeDependents, additions);
+ changed= changeDependents.addAll(additions);
+ } while (changed);
+
+ for(IFile f: changeDependents) {
+ if (isSourceFile(f)) {
+ fSourcesToCompile.add(f);
+ }
+ }
+// getConsoleStream().println("Changed files + dependents:");
+// dumpSourceList(fSourcesToCompile);
+ }
+
+ private boolean scanSourceList(Collection<IFile> srcList, Collection<IFile> changeDependents) {
+ boolean result= false;
+ for(Iterator<IFile> iter= srcList.iterator(); iter.hasNext(); ) {
+ IFile srcFile= iter.next();
+ Set<String> fileDependents= fDependencyInfo.getDependentsOf(srcFile.getFullPath().toString());
+
+ if (fileDependents != null) {
+ for(Iterator<String> iterator= fileDependents.iterator(); iterator.hasNext(); ) {
+ String depPath= iterator.next();
+ IFile depFile= getProject().getWorkspace().getRoot().getFile(new Path(depPath));
+
+ result= result || changeDependents.add(depFile);
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Refreshes all resources in the entire project tree containing the given resource.
+ * Crude but effective.
+ */
+ protected void doRefresh(final IResource resource) {
+ new Thread() {
+ public void run() {
+ try {
+ resource.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
+ } catch (CoreException e) {
+ e.printStackTrace();
+ }
+ }
+ }.start();
+ }
+
+ /**
+ * @return the ID of the marker type for the given marker severity (one of
+ * <code>IMarker.SEVERITY_*</code>). If the severity is unknown/invalid,
+ * returns <code>getInfoMarkerID()</code>.
+ */
+ protected String getMarkerIDFor(int severity) {
+ switch(severity) {
+ case IMarker.SEVERITY_ERROR: return getErrorMarkerID();
+ case IMarker.SEVERITY_WARNING: return getWarningMarkerID();
+ case IMarker.SEVERITY_INFO: return getInfoMarkerID();
+ default: return getInfoMarkerID();
+ }
+ }
+
+ /**
+ * Utility method to create a marker on the given resource using the given
+ * information.
+ * @param errorResource
+ * @param startLine the line with which the error is associated
+ * @param charStart the offset of the first character with which the error is associated
+ * @param charEnd the offset of the last character with which the error is associated
+ * @param message a human-readable text message to appear in the "Problems View"
+ * @param severity the message severity, one of <code>IMarker.SEVERITY_*</code>
+ */
+ public void createMarker(IResource errorResource, int startLine, int charStart, int charEnd, String message, int severity) {
+ try {
+ // TODO: Address this situation properly after demo
+ // Issue is resources that are templates and not in user's workspace
+ if (!errorResource.exists())
+ return;
+
+ IMarker m = errorResource.createMarker(getMarkerIDFor(severity));
+
+ String[] attributeNames = new String[] {IMarker.LINE_NUMBER, IMarker.MESSAGE, IMarker.PRIORITY, IMarker.SEVERITY};
+ Object[] values = new Object[] {startLine, message, IMarker.PRIORITY_HIGH, severity};
+ m.setAttributes(attributeNames, values);
+
+ if (charStart >= 0 && charEnd >= 0) {
+ attributeNames = new String[] {IMarker.CHAR_START, IMarker.CHAR_END};
+ values = new Object[] {charStart, charEnd};
+ m.setAttributes(attributeNames, values);
+ } else if (charStart >= 0) {
+ m.setAttribute(IMarker.CHAR_START, charStart);
+ } else if (charEnd >= 0)
+ m.setAttribute(IMarker.CHAR_END, charEnd);
+ } catch (CoreException e) {
+ getPlugin().writeErrorMsg("Unable to create marker: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Posts a dialog displaying the given message as soon as "conveniently possible".
+ * This is not a synchronous call, since this method will get called from a
+ * different thread than the UI thread, which is the only thread that can
+ * post the dialog box.
+ */
+ protected void postMsgDialog(final String title, final String msg) {
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ Shell shell= RuntimePlugin.getInstance().getWorkbench().getActiveWorkbenchWindow().getShell();
+
+ MessageDialog.openInformation(shell, title, msg);
+ }
+ });
+ }
+
+ /**
+ * Posts a dialog displaying the given message as soon as "conveniently possible".
+ * This is not a synchronous call, since this method will get called from a
+ * different thread than the UI thread, which is the only thread that can
+ * post the dialog box.
+ */
+ protected void postQuestionDialog(final String title, final String query, final Runnable runIfYes, final Runnable runIfNo) {
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ Shell shell= RuntimePlugin.getInstance().getWorkbench().getActiveWorkbenchWindow().getShell();
+ boolean response= MessageDialog.openQuestion(shell, title, query);
+
+ if (response)
+ runIfYes.run();
+ else if (runIfNo != null)
+ runIfNo.run();
+ }
+ });
+ }
+
+ /**
+ * Derived classes may override to specify a unique name for a separate console;
+ * otherwise, all IMP builders share a single console. @see IMP_BUILDER_CONSOLE.
+ * @return the name of the console to use for diagnostic output, if any
+ */
+ protected String getConsoleName() {
+ return IMP_BUILDER_CONSOLE;
+ }
+
+ /**
+ * If you want your builder to have its own console, be sure to override
+ * getConsoleName().
+ * @return the console whose name is returned by getConsoleName()
+ */
+ protected MessageConsoleStream getConsoleStream() {
+ return findConsole(getConsoleName()).newMessageStream();
+ }
+
+ /**
+ * Find or create the console with the given name
+ * @param consoleName
+ */
+ protected MessageConsole findConsole(String consoleName) {
+ if (consoleName == null) {
+ RuntimePlugin.getInstance().getLog().log(new Status(IStatus.ERROR, RuntimePlugin.IMP_RUNTIME, "BuilderBase.findConsole() called with a null console name; substituting default console"));
+ consoleName= IMP_BUILDER_CONSOLE;
+ }
+ MessageConsole myConsole= null;
+ final IConsoleManager consoleManager= ConsolePlugin.getDefault().getConsoleManager();
+ IConsole[] consoles= consoleManager.getConsoles();
+ for(int i= 0; i < consoles.length; i++) {
+ IConsole console= consoles[i];
+ if (console.getName().equals(consoleName))
+ myConsole= (MessageConsole) console;
+ }
+ if (myConsole == null) {
+ myConsole= new MessageConsole(consoleName, null);
+ consoleManager.addConsoles(new IConsole[] { myConsole });
+ }
+// consoleManager.showConsoleView(myConsole);
+ return myConsole;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/BuilderUtils.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/BuilderUtils.java
new file mode 100644
index 000000000..5be0af71a
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/BuilderUtils.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.builder;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.imp.utils.StreamUtils;
+
+
+public class BuilderUtils {
+
+
+ /**
+ * Operates on a file with contents that have a textual representation
+ * and returns the contents in the form of a String.
+ *
+ * @param inFileName Name of a file that contains some content suitable
+ * for a String representation. Used as given (whether
+ * absolute or relative)
+ */
+ static public String extractContentsToString(String inFileName)
+ {
+ // Check the given file name
+ if ((inFileName == null) || (inFileName.length() == 0)) {
+ throw new IllegalArgumentException(
+ "BuilderUtils.extractContentsToString(): file name is null or empty");
+ }
+
+ // Check that the inFile exists and can be read
+ File inFile= new File(inFileName);
+
+ if (!inFile.exists() || !inFile.canRead()) {
+ throw new IllegalArgumentException(
+ "BuilderUtils.extractContentsToString(): file does not exist or cannot be read " +
+ "(name = " + inFileName + ")");
+ }
+ return getFileContents(inFile);
+
+ }
+
+ /**
+ * @return the text contents of the given file as a String, without
+ * translating line terminating characters.
+ */
+ public static String getFileContents(IFile file) {
+ try {
+ return StreamUtils.readStreamContents(file.getContents());
+ } catch (CoreException e) {
+ System.err.println(e.getMessage());
+ return "";
+ }
+ }
+
+ public static String getFileContents(File file) {
+ InputStream fileStream = null;
+ try {
+ fileStream = new FileInputStream(file);
+ } catch(FileNotFoundException fnf) {
+ System.err.println(fnf.getMessage());
+ return "";
+ }
+ return StreamUtils.readStreamContents(fileStream);
+ }
+
+ /**
+ * @return the text contents of the given Reader, without translating
+ * line terminating characters.
+ */
+ public static String getFileContents(Reader reader) {
+
+
+
+ // In this case we don't know the length in advance, so we have to
+ // accumulate the reader's contents one buffer at a time.
+ StringBuilder sb= new StringBuilder(4096);
+ char[] buff= new char[4096];
+ int len;
+
+ while(true) {
+ try {
+ len= reader.read(buff);
+ } catch (IOException e) {
+ break;
+ }
+ if (len < 0)
+ break;
+ sb.append(buff, 0, len);
+ }
+ return sb.toString();
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/DependencyInfo.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/DependencyInfo.java
new file mode 100644
index 000000000..ed139038b
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/DependencyInfo.java
@@ -0,0 +1,152 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.builder;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+
+/**
+ * Tracks dependencies among compilation units in a given project.<br>
+ * @author rfuhrer@watson.ibm.com
+ */
+public class DependencyInfo {
+ protected final Map<String /*unitPath*/, Set<String /*unitPath*/>> fDependsUpon= new HashMap<String,Set<String>>();
+ protected final Map<String /*unitPath*/, Set<String /*unitPath*/>> fIsDependedUponBy= new HashMap<String,Set<String>>();
+ protected final IProject fProject;
+ protected final String fWorkspacePath;
+
+ public DependencyInfo(IProject project) {
+ fProject= project;
+ fWorkspacePath= fProject.getProject().getWorkspace().getRoot().getLocation().toString();
+ }
+
+ protected Set<String /*unitPath*/> getEntry(Map<String /*unitPath*/, Set<String /*unitPath*/>> map, String unitPath) {
+ Set<String> result;
+
+ if (!map.containsKey(unitPath))
+ result= Collections.emptySet();
+ else
+ result= map.get(unitPath);
+ return result;
+ }
+
+ protected Set<String> getOrCreateEntry(Map<String,Set<String>> map, String unitPath) {
+ Set<String> result;
+
+ if (!map.containsKey(unitPath))
+ map.put(unitPath, result= new HashSet<String>());
+ else
+ result= (Set<String>) map.get(unitPath);
+ return result;
+ }
+
+ /**
+ * Records a dependency between the two compilation units.
+ * @param fromPath a compilation unit path; should be workspace-relative
+ * @param uponPath a compilation unit path; should be workspace-relative
+ */
+ public void addDependency(String fromPath, String uponPath) {
+ Set<String> fwdEntry= getOrCreateEntry(fDependsUpon, fromPath);
+
+ fwdEntry.add(uponPath);
+
+ Set<String> bkwdEntry= getOrCreateEntry(fIsDependedUponBy, uponPath);
+
+ bkwdEntry.add(fromPath);
+ }
+
+ /**
+ * Clears the memory of all dependencies among all compilation units tracked by
+ * this DependencyInfo instance.
+ */
+ public void clearAllDependencies() {
+ fDependsUpon.clear();
+ fIsDependedUponBy.clear();
+ }
+
+ /**
+ * Clears any dependencies related to the given compilation unit
+ * @param unitPath should be workspace-relative
+ */
+ public void clearDependenciesOf(String unitPath) {
+ Set<String> entry= getEntry(fDependsUpon, unitPath);
+
+ fDependsUpon.put(unitPath, new HashSet<String>());
+ for(Iterator<String> iter= entry.iterator(); iter.hasNext(); ) {
+ String uponPath= (String) iter.next();
+ Set<String> uponSet= getEntry(fIsDependedUponBy, uponPath);
+
+ uponSet.remove(unitPath);
+ }
+ }
+
+ /**
+ * @return a Map from workspace-relative unit paths to Sets of dependent
+ * workspace-relative unit paths
+ */
+ public Map<String /*path*/, Set<String /*path*/>> getDependencies() {
+ return Collections.unmodifiableMap(fDependsUpon);
+ }
+
+ /**
+ * @param unitPath should be workspace-relative
+ * @return a Set of dependent workspace--relative unit paths
+ */
+ public Set<String /*path*/> getDependentsOf(String unitPath) {
+ return (Set) fIsDependedUponBy.get(unitPath);
+ }
+
+ public void dump() {
+ System.out.print(toString());
+// System.out.println("*** Dependencies ***:");
+// for(Iterator<String> iter= fDependsUpon.keySet().iterator(); iter.hasNext(); ) {
+// String unit= iter.next();
+// Set<String /*path*/> dependents= (Set) fDependsUpon.get(unit);
+//
+// System.out.println("Unit " + unit + ": ");
+// for(Iterator<String> iterator= dependents.iterator(); iterator.hasNext(); ) {
+// String uponUnit= iterator.next();
+// System.out.print(" ");
+// System.out.print(uponUnit);
+// if (iterator.hasNext()) System.out.print(", ");
+// }
+// System.out.println();
+// }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb= new StringBuilder();
+ sb.append("*** Dependencies ***:\n");
+ for(Iterator<String> iter= fDependsUpon.keySet().iterator(); iter.hasNext(); ) {
+ String unit= iter.next();
+ Set<String /*path*/> dependents= (Set) fDependsUpon.get(unit);
+
+ sb.append("Unit " + unit + ": \n");
+ for(Iterator<String> iterator= dependents.iterator(); iterator.hasNext(); ) {
+ String uponUnit= iterator.next();
+ sb.append(" ");
+ sb.append(uponUnit);
+ if (iterator.hasNext()) sb.append(", ");
+ }
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/MarkerCreator.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/MarkerCreator.java
new file mode 100644
index 000000000..4b4358cfe
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/MarkerCreator.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.builder;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.imp.parser.IMessageHandler;
+import org.eclipse.imp.parser.IParseController;
+
+/**
+ * This class provides a message handler that creates markers in
+ * response to received messages.
+ *
+ * MarkerCreators are instantiated with a file (IFile) and a parse
+ * controller (IParseController). The parse controller should
+ * be parsing the file and generating the messages that are
+ * received by the MarkerCreator. The MarkerCreator, in turn,
+ * creates a problem marker for each error message received,
+ * uses the parse controller to compute a line number for the
+ * token provided with each message, and attaches the marker to
+ * the given file at the computed line.
+ */
+public class MarkerCreator implements IMessageHandler {
+
+ protected IParseController parseController;
+ protected IFile file;
+ protected String problemType;
+
+ public MarkerCreator(IFile file, IParseController parseController) {
+ this(file, parseController, IMarker.PROBLEM);
+ }
+
+ public MarkerCreator(IFile file, IParseController parseController, String problemType) {
+ this.file = file;
+ this.parseController = parseController;
+ this.problemType = problemType;
+ }
+
+ public void clearMessages() {
+ // TODO Clear markers on this file?
+ }
+
+ public void handleSimpleMessage(String msg, int startOffset, int endOffset,
+ int startCol, int endCol,
+ int startLine, int endLine)
+ {
+ try {
+ // Based closely on the Eclipse "FAQ How do I create problem markers for my compiler?"
+ IMarker m = file.createMarker(problemType);
+
+ String[] attributeNames = new String[] {IMarker.LINE_NUMBER, IMarker.CHAR_START, IMarker.CHAR_END, IMarker.MESSAGE, IMarker.PRIORITY, IMarker.SEVERITY};
+ Object[] values = new Object[] {startLine, startOffset, endOffset, msg, IMarker.PRIORITY_HIGH, IMarker.SEVERITY_ERROR};
+ m.setAttributes(attributeNames, values);
+
+ } catch (CoreException e) {
+ System.err.println("MarkerCreator.handleMessage: CoreException trying to create marker");
+ } catch (Exception e) {
+ System.err.println("MarkerCreator.handleMessage: Exception trying to create marker");
+ }
+ }
+
+ public void endMessageGroup() { }
+
+ public void startMessageGroup(String groupName) { }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/MarkerCreatorWithBatching.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/MarkerCreatorWithBatching.java
new file mode 100644
index 000000000..cbea7a0b6
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/MarkerCreatorWithBatching.java
@@ -0,0 +1,286 @@
+/*******************************************************************************
+* Copyright (c) 2008 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Stan Sutton (suttons@us.ibm.com) - initial API and implementation
+* Copied liberally and adapted from an implementation provided by
+* E. D. Willink as an attachment to Eclipse bugzilla bug #245296 (and
+* copyrighted 2008 under EPL v. 1.0 http://www.eclipse.org/legal/epl-v10.html).
+*
+*******************************************************************************/
+
+package org.eclipse.imp.builder;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.imp.builder.ProblemLimit.LimitExceededException;
+import org.eclipse.imp.core.ErrorHandler;
+import org.eclipse.imp.parser.IParseController;
+
+/**
+ * An implementation of IMessageHandler for collecting messages over time
+ * and then creating a group of corresponding markers in one batch using
+ * a single workspace operation.
+ *
+ * Copied liberally from a MarkerProblemHandler implementation provided by
+ * E. D. Willink as an attachment to Eclipse bugzilla bug #245296 (and
+ * copyrighted 2008 under EPL v. 1.0 http://www.eclipse.org/legal/epl-v10.html).
+ *
+ * @author Stan Sutton (suttons@us.ibm.com)
+ */
+public class MarkerCreatorWithBatching extends MarkerCreator {
+ protected String page = null;
+ protected Map<Integer, List<Map<String, Object>>> entries = null; // Map of line number to list of marker attributes for line
+ protected ProblemLimit problemLimit = null;
+ protected BuilderBase builder = null;
+
+ /*
+ * NOTE: The parse controller that is provided in constructing an instance of this
+ * type is used to obtain a parse stream that is used in processing error messages
+ * received by the instance. In particular, error messages are associated with positions
+ * in the text, those positions are used to identify corresponding parse tokens, and
+ * those parse tokens are used in determining positions for error markers. For that
+ * reason, the given parse controller should provide a parse stream that is consistent
+ * with (if not identical to) the one obtained when the error messages were generated.
+ * Also for that reason, no additional parsing is done within the marker creator.
+ * Violation of this assumption can lead to markers (and marker annotations) that are
+ * not correctly located with respect to the underling error in the text.
+ */
+
+
+ /**
+ * Constructor to use when you want to create markers that are not related to a
+ * particular builder and that will have the marker type provided here.
+ *
+ * @param resource The resource (e.g., file) on which markers are to be placed
+ * @param parseController The source of the parse stream to which error messages will
+ * be related
+ * @param problemType The type of problem marker (i.e., the problem marker id)
+ */
+ public MarkerCreatorWithBatching(
+ IFile file,
+ IParseController parseController,
+ String problemType)
+ {
+ super(file, parseController, problemType);
+ PROBLEM_MARKER_ID = problemType;
+ }
+
+
+ /**
+ * Constructor to use when you want to create markers that are related to a
+ * particular builder and that will have a marker type and builder id based
+ * on that builder.
+ *
+ * @param file The file on which markers are to be placed
+ * @param parseController The source of the parse stream to which error messages will
+ * be related
+ * @param builder The builder that is presumably driving the creation of
+ * markers and that defines the type of marker and builder id
+ * that will be used here
+ */
+ public MarkerCreatorWithBatching(
+ IFile file,
+ IParseController parseController,
+ BuilderBase builder)
+ {
+ super(file, parseController, builder.getErrorMarkerID());
+
+ this.builder = builder;
+ initializeBuidlerID(builder);
+ initializeProblemMarkerID(builder);
+ }
+
+
+ public String BUILDER_ID;
+
+ protected void initializeBuidlerID(BuilderBase builder) {
+ if (builder != null) {
+ BUILDER_ID = builder.getBuilderID();
+ } else {
+ BUILDER_ID = parseController.getLanguage().getName() + ".builder";
+ }
+ }
+
+ public String PROBLEM_MARKER_ID;
+
+ protected void initializeProblemMarkerID(BuilderBase builder) {
+ if (builder != null) {
+ PROBLEM_MARKER_ID = builder.getErrorMarkerID();
+ } else {
+ PROBLEM_MARKER_ID = parseController.getLanguage().getName() + ".builder";
+ }
+ }
+
+
+ public Map<Integer, Integer> severityMap = new HashMap<Integer, Integer>();
+ {
+ severityMap.put(Integer.valueOf(IMarker.SEVERITY_ERROR), Integer.valueOf(IMarker.SEVERITY_ERROR));
+ severityMap.put(IMarker.SEVERITY_INFO, Integer.valueOf(IMarker.SEVERITY_INFO));
+ severityMap.put(IMarker.SEVERITY_WARNING, Integer.valueOf(IMarker.SEVERITY_WARNING));
+ }
+
+ public void setSeverityMap(Map<Integer, Integer> mapOfSeverities) {
+ // TODO: Figure out what to do about target severities that do not correspond
+ // to marker severities
+ severityMap = mapOfSeverities;
+ }
+
+ public Map<Integer, Integer> getSeverityMap() {
+ return severityMap;
+ }
+
+ public void addMarker(int severity, String message, int lineNumber, int charStart, int charEnd)
+ throws ProblemLimit.LimitExceededException
+ {
+ String adjustedMessage = message;
+ if (problemLimit != null) {
+ adjustedMessage = problemLimit.check(severity, message);
+ if (adjustedMessage == null)
+ return;
+ }
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(IMarker.MESSAGE, adjustedMessage);
+ attributes.put(IMarker.SEVERITY, Integer.valueOf(severity));
+ if (lineNumber == -1) {
+ lineNumber = 1;
+ }
+ Integer lineKey = Integer.valueOf(lineNumber);
+ attributes.put(IMarker.LINE_NUMBER, lineKey);
+ if (charStart <= charEnd) {
+ attributes.put(IMarker.CHAR_START, Integer.valueOf(charStart));
+ attributes.put(IMarker.CHAR_END, Integer.valueOf(charEnd));
+ }
+// attributes.put(BUILDER_ID, creationFactory.getBuilderId());
+ if (builder != null)
+ attributes.put(BUILDER_ID, builder.getBuilderID());
+ if (entries == null)
+ entries = new HashMap<Integer, List<Map<String, Object>>>();
+ List<Map<String, Object>> lineEntries = entries.get(lineKey);
+ if (lineEntries == null) {
+ lineEntries = new ArrayList<Map<String, Object>>();
+ entries.put(lineKey, lineEntries);
+ }
+ lineEntries.add(attributes);
+ if (adjustedMessage != message)
+ throw new ProblemLimit.LimitExceededException(adjustedMessage);
+ }
+
+
+ public void clearMessages() {
+ // TODO Auto-generated method stub
+ }
+
+
+ public void endMessageGroup() { }
+
+
+ public void flush(IProgressMonitor monitor) {
+ // Re-use existing markers wherever possible
+ // a) since many rebuilds generate the same errors
+ // b) to avoid a marker being deleted by a refreshMarkers on editor entry before
+ // gotoMarker is invoked to go to a pre-existing context.
+ if (file.exists()) {
+ IWorkspaceRunnable action = new IWorkspaceRunnable() {
+ public void run(IProgressMonitor monitor) throws CoreException {
+ String markerId = PROBLEM_MARKER_ID;
+ if (entries != null) {
+ IMarker[] oldMarkers = file.findMarkers(markerId, false, IFile.DEPTH_ZERO);
+ for (IMarker oldMarker : oldMarkers) {
+ Map<?, ?> oldAttributes = oldMarker.getAttributes();
+ List<Map<String, Object>> lineEntries = entries.get(oldAttributes.get(IMarker.LINE_NUMBER));
+ if (lineEntries != null) {
+ for (Map<String, Object> newAttributes : lineEntries) {
+ if (isSameMarker(oldAttributes, newAttributes)) {
+ lineEntries.remove(newAttributes);
+ oldMarker = null;
+ break;
+ }
+ }
+ }
+ if (oldMarker != null)
+ oldMarker.delete();
+ }
+ for (List<Map<String, Object>> lineEntries : entries.values()) {
+ for (Map<String, Object> entry : lineEntries) {
+ IMarker marker = file.createMarker(markerId);
+ marker.setAttributes(entry);
+ }
+ }
+ } else
+ file.deleteMarkers(markerId, false, IFile.DEPTH_ZERO);
+ }
+ };
+ try {
+ // TODO: Allow for the introduction of a non-null progress monitor
+// IProgressMonitor progressMonitor = monitor != null ? BasicMonitor.toIProgressMonitor(monitor) : new NullProgressMonitor();
+ IProgressMonitor progressMonitor = new NullProgressMonitor();
+ file.getWorkspace().run(action, file, IWorkspace.AVOID_UPDATE, progressMonitor);
+ } catch (CoreException e) {
+ ErrorHandler.logError("Failed to update file markers", e);
+ }
+ }
+ }
+
+ public void handleSimpleMessage(
+ String msg, int startOffset, int endOffset,
+ int startCol, int endCol, int startLine, int endLine)
+ {
+ try {
+ addMarker(IMarker.SEVERITY_ERROR, msg, startLine, startOffset, endOffset+1);
+ } catch (LimitExceededException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Return true if newAttributes and oldAttributes provide the same marker description.
+ */
+ public boolean isSameMarker(Map<?, ?> oldAttributes, Map<String, Object> newAttributes) {
+ Set<?> oldKeys = oldAttributes.keySet();
+ Set<String> newKeys = newAttributes.keySet();
+ if (oldKeys.size() != newKeys.size())
+ return false;
+ for (String key : newKeys) {
+ if (!oldAttributes.containsKey(key))
+ return false;
+ Object oldValue = oldAttributes.get(key);
+ Object newValue = newAttributes.get(key);
+ if (oldValue == newValue)
+ continue;
+ if (oldValue == null)
+ return false;
+ if (newValue == null)
+ return false;
+ if (!oldValue.equals(newValue))
+ return false;
+ }
+ return true;
+ }
+
+ public void setProblemLimit(ProblemLimit problemLimit) {
+ this.problemLimit = problemLimit;
+ }
+
+ public void setPage(String page) {
+ this.page = page;
+ }
+
+ public void startMessageGroup(String groupName) { }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/ProblemLimit.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/ProblemLimit.java
new file mode 100644
index 000000000..6948f0aef
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/ProblemLimit.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+* Copyright (c) 2008 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Stan Sutton (suttons@us.ibm.com) - initial API and implementation
+* based on usage proposed by E. D. Willink (Eclipse bug report #245296)
+*
+*******************************************************************************/
+
+package org.eclipse.imp.builder;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A utility class for recording limits on the number of errors, of various levels
+ * of severity, that should be processed by a client such as a marker creator or
+ * other form of error-message handler.
+ *
+ * Developed to support org.eclipse.imp.builder.MarkerCreatorWithBatching.
+ */
+public class ProblemLimit
+{
+ // TODO: Consider updating preliminary implementation
+
+ Map<Integer, Integer> limitsBySeverity = new HashMap<Integer, Integer>();
+ Map<Integer, String> messagesBySeverity = new HashMap<Integer, String>();
+
+
+ public String check(int severity, String message) {
+ return message;
+ }
+
+
+ public void setLimit(int severity, int limit, String message) {
+ if (severity < 0)
+ throw new IllegalArgumentException("Given severity is less than 0--must be 0 or greater");
+ if (limit < 0)
+ throw new IllegalArgumentException("Given limit is less than 0--must be 0 or greater");
+ if (message == null)
+ throw new IllegalArgumentException("Given memssage is null; must not be null");
+
+ limitsBySeverity.remove(severity);
+ limitsBySeverity.put(severity, limit);
+
+ messagesBySeverity.remove(severity);
+ messagesBySeverity.put(severity, message);
+ }
+
+
+ public void clearLimit(int severity) {
+ limitsBySeverity.remove(severity);
+ messagesBySeverity.remove(severity);
+ }
+
+
+ public void clearAllLimits() {
+ limitsBySeverity.clear();
+ messagesBySeverity.clear();
+ }
+
+
+ public boolean isLimited(int severity) {
+ return limitsBySeverity.containsKey(severity);
+ }
+
+
+ public int getLimit(int severity, int defaultLimit) {
+ if (!isLimited(severity))
+ return defaultLimit;
+ else
+ return limitsBySeverity.get(severity);
+ }
+
+
+ public String getMessage(int severity, String defaultMessage) {
+ if (!isLimited(severity))
+ return defaultMessage;
+ else
+ return messagesBySeverity.get(severity);
+ }
+
+
+ public static class LimitExceededException extends Exception {
+ /*
+ * TODO: treat this seriously, if warranted
+ */
+ private static final long serialVersionUID = 1L;
+
+ LimitExceededException(String message) {
+ super(message);
+ }
+ }
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/ProjectNatureBase.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/ProjectNatureBase.java
new file mode 100644
index 000000000..9bf1173ee
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/ProjectNatureBase.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+/*
+ * Created on Nov 1, 2005
+ */
+package org.eclipse.imp.builder;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.ICommand;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IProjectNature;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.imp.runtime.IPluginLog;
+
+public abstract class ProjectNatureBase implements IProjectNature {
+ private IProject fProject;
+
+ public ProjectNatureBase() {}
+
+ public abstract String getNatureID();
+
+ public abstract String getBuilderID();
+
+ public abstract IPluginLog getLog();
+
+ /**
+ * Refresh the preferences, to make sure the project settings are up to date.
+ * Derived classes must implement.
+ */
+ protected abstract void refreshPrefs();
+
+ /**
+ * Returns the ID of the builder that processes the artifacts that this
+ * nature's builder produces. If there is no such dependency, returns null.
+ */
+ // TODO this should be a property of the builder itself...
+ protected String getDownstreamBuilderID() {
+ return null; // by default, no such dependency
+ }
+
+ /**
+ * Returns the ID of the builder that produces artifacts that this nature's
+ * builder consumes. If there is no such dependency, returns null.
+ */
+ // TODO this should be a property of the builder itself...
+ protected String getUpstreamBuilderID() {
+ return null; // by default, no such dependency
+ }
+
+ public void addToProject(IProject project) {
+ String natureID= getNatureID();
+
+ refreshPrefs();
+ // SMS 16 Apr 2007
+ // You can find log null here if the plugin hasn't been started yet.
+ // It is intended that the manifest file for the IDE plugin should have autostart
+ // set to true, in which case the log should not come back null, but if the
+ // manifest file has been corrupted (which can happen if you regenerate services
+ // over prior implementations) then the autostart property may be lost and the
+ // pluin may not be started yet.
+ IPluginLog log = getLog();
+ log.maybeWriteInfoMsg("Attempting to add nature " + natureID);
+
+ try {
+ IProjectDescription description= project.getDescription();
+ String[] natures= description.getNatureIds();
+ String[] newNatures= new String[natures.length + 1];
+
+ System.arraycopy(natures, 0, newNatures, 0, natures.length);
+ newNatures[natures.length]= natureID;
+
+ description.setNatureIds(newNatures);
+ project.setDescription(description, null);
+
+ // At this point, this nature's builder should be in the project description,
+ // but since the description holds only nature ID's, the Eclipse framework ends
+ // up instantiating the nature itself and calling configure() on that instance.
+ // It uses the default (no-arg) ctor to do this, so that instance won't have
+ // enough info to properly populate the builder arguments, if any. So: we need
+ // to find the builder now and set its arguments using getBuilderArguments().
+ // N.B.: As an added twist, we have to ask Eclipse for the project description
+ // again, rather than using the one we got above, since the latter won't have
+ // the builder in it.
+ IProjectDescription newDesc= project.getDescription();
+ ICommand[] builders= newDesc.getBuildSpec();
+ String builderID= getBuilderID();
+
+ for(int i= 0; i < builders.length; i++) {
+ if (builders[i].getBuilderName().equals(builderID)) {
+ builders[i].setArguments(getBuilderArguments());
+ }
+ }
+ newDesc.setBuildSpec(builders);
+ project.setDescription(newDesc, null);
+ getLog().maybeWriteInfoMsg("Added nature " + natureID);
+ } catch (CoreException e) {
+ // Something went wrong
+ getLog().writeErrorMsg("Failed to add nature " + natureID + ": " + e.getMessage());
+ }
+ }
+
+ public void configure() throws CoreException {
+ IProjectDescription desc= getProject().getDescription();
+ String builderID= getBuilderID();
+ ICommand[] cmds= desc.getBuildSpec();
+
+ // Check: is the builder already in this project?
+ for(int i=0; i < cmds.length; i++) {
+ if (cmds[i].getBuilderName().equals(builderID))
+ return; // relevant command is already in there...
+ }
+
+ int beforeWhere= cmds.length;
+ String downstreamBuilderID= getDownstreamBuilderID();
+
+ if (downstreamBuilderID != null) {
+ // Since this builder produces artifacts that another one will
+ // post-process, it needs to run *before* that one.
+ // So, find the right spot (in front of that builder) to put this one.
+ for(beforeWhere--; beforeWhere >= 0; beforeWhere--) {
+ if (cmds[beforeWhere].getBuilderName().equals(downstreamBuilderID))
+ break; // found it
+ }
+ if (beforeWhere < 0)
+ getLog().writeErrorMsg("Unable to find downstream builder '" + downstreamBuilderID + "' for builder '" + builderID + "'.");
+ }
+
+ int afterWhere= -1;
+ String upstreamBuilderID= getUpstreamBuilderID();
+
+ if (upstreamBuilderID != null) {
+ // This builder consumes artifacts that another one will produce,
+ // so it needs to run *after* that one.
+ // So, find the right spot (after that builder) to put this one.
+ for(afterWhere= 0; afterWhere < cmds.length; afterWhere++) {
+ if (cmds[afterWhere].getBuilderName().equals(upstreamBuilderID))
+ break; // found it
+ }
+ if (afterWhere == cmds.length)
+ getLog().writeErrorMsg("Unable to find upstream builder '" + upstreamBuilderID + "' for builder '" + builderID + "'.");
+ }
+
+ if (beforeWhere <= afterWhere)
+ getLog().writeErrorMsg("Error: builder '" + builderID + "' needs to be before downstream builder '" + downstreamBuilderID + "' but after builder " + upstreamBuilderID + ", but " + downstreamBuilderID + " comes after " + upstreamBuilderID + "!");
+ if (beforeWhere == cmds.length && afterWhere >= 0)
+ beforeWhere= afterWhere + 1;
+
+ ICommand compilerCmd= desc.newCommand();
+
+ compilerCmd.setBuilderName(builderID);
+ // RMF 8/9/2006 - Don't bother trying to set the builder arguments here; this instance of
+ // the nature will have been constructed with the no-arg ctor (by the Eclipse framework),
+ // and won't have enough info to compute the builder arguments. Do it later, in addToProject(),
+ // which will hopefully be executed by a nature instance that does have the necessary info.
+ // compilerCmd.setArguments(getBuilderArguments());
+
+ ICommand[] newCmds= new ICommand[cmds.length+1];
+
+ System.arraycopy(cmds, 0, newCmds, 0, beforeWhere);
+ newCmds[beforeWhere] = compilerCmd;
+ System.arraycopy(cmds, beforeWhere, newCmds, beforeWhere+1, cmds.length-beforeWhere);
+ desc.setBuildSpec(newCmds);
+ getProject().setDescription(desc, null);
+ }
+
+ protected Map getBuilderArguments() {
+ return new HashMap();
+ }
+
+ public void deconfigure() throws CoreException {
+ IProjectDescription desc= getProject().getDescription();
+ String builderID= getBuilderID();
+ ICommand[] cmds= desc.getBuildSpec();
+
+ for(int i=0; i < cmds.length; ++i) {
+ if (cmds[i].getBuilderName().equals(builderID)) {
+ ICommand[] newCmds= new ICommand[cmds.length - 1];
+
+ System.arraycopy(cmds, 0, newCmds, 0, i);
+ System.arraycopy(cmds, i + 1, newCmds, i, cmds.length - i - 1);
+ desc.setBuildSpec(newCmds);
+ getProject().setDescription(desc, null);
+ return;
+ }
+ }
+ }
+
+ public IProject getProject() {
+ return fProject;
+ }
+
+ public void setProject(IProject project) {
+ fProject= project;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/core/Assert.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/core/Assert.java
new file mode 100644
index 000000000..9de055e22
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/core/Assert.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.core;
+
+/**
+ * <code>Assert</code> is useful for for embedding runtime sanity checks in code. The static predicate methods all
+ * test a condition and throw some type of unchecked exception if the condition does not hold.
+ * <p>
+ * Assertion failure exceptions, like most runtime exceptions, are thrown when something is misbehaving. Assertion
+ * failures are invariably unspecified behavior; consequently, clients should never rely on these being thrown (or not
+ * thrown). <b>If you find yourself in the position where you need to catch an assertion failure, you have most
+ * certainly written your program incorrectly.</b>
+ * </p>
+ * <p>
+ * Note that an <code>assert</code> statement is slated to be added to the Java language in JDK 1.4, rending this
+ * class obsolete.
+ * </p>
+ */
+public final class Assert {
+
+ /**
+ * <code>AssertionFailedException</code> is a runtime exception thrown by some of the methods in
+ * <code>Assert</code>.
+ * <p>
+ * This class is not declared public to prevent some misuses; programs that catch or otherwise depend on assertion
+ * failures are susceptible to unexpected breakage when assertions in the code are added or removed.
+ * </p>
+ */
+ private static class AssertionFailedException extends RuntimeException {
+ /** This class is not intended to be serialized. */
+ private static final long serialVersionUID= 1L;
+
+ /**
+ * Constructs a new exception.
+ */
+ public AssertionFailedException() {
+ }
+
+ /**
+ * Constructs a new exception with the given message.
+ *
+ * @param detail
+ * the detail message
+ */
+ public AssertionFailedException(String detail) {
+ super(detail);
+ }
+ }
+
+ /* This class is not intended to be instantiated. */
+ private Assert() {
+ }
+
+ /**
+ * Asserts that the given object is not <code>null</code>. If this is not the case, some kind of unchecked
+ * exception is thrown.
+ * <p>
+ * As a general rule, parameters passed to API methods must not be <code>null</code> unless <b>explicitly</b>
+ * allowed in the method's specification. Similarly, results returned from API methods are never <code>null</code>
+ * unless <b>explicitly</b> allowed in the method's specification. Implementations are encouraged to make regular
+ * use of <code>Assert.isNotNull</code> to ensure that <code>null</code> parameters are detected as early as
+ * possible.
+ * </p>
+ *
+ * @param object
+ * the value to test
+ */
+ public static void isNotNull(Object object) {
+ // succeed as quickly as possible
+ if (object != null) {
+ return;
+ }
+ isNotNull(object, ""); //$NON-NLS-1$
+ }
+
+ /**
+ * Asserts that the given object is not <code>null</code>. If this is not the case, some kind of unchecked
+ * exception is thrown. The given message is included in that exception, to aid debugging.
+ * <p>
+ * As a general rule, parameters passed to API methods must not be <code>null</code> unless <b>explicitly</b>
+ * allowed in the method's specification. Similarly, results returned from API methods are never <code>null</code>
+ * unless <b>explicitly</b> allowed in the method's specification. Implementations are encouraged to make regular
+ * use of <code>Assert.isNotNull</code> to ensure that <code>null</code> parameters are detected as early as
+ * possible.
+ * </p>
+ *
+ * @param object
+ * the value to test
+ * @param message
+ * the message to include in the exception
+ */
+ public static void isNotNull(Object object, String message) {
+ if (object == null)
+ throw new AssertionFailedException(IMPMessages.Assert_null_argument + message);
+ }
+
+ /**
+ * Asserts that the given boolean is <code>true</code>. If this is not the case, some kind of unchecked exception
+ * is thrown.
+ *
+ * @param expression
+ * the outcome of the check
+ * @return <code>true</code> if the check passes (does not return if the check fails)
+ */
+ public static boolean isTrue(boolean expression) {
+ // succeed as quickly as possible
+ if (expression) {
+ return true;
+ }
+ return isTrue(expression, ""); //$NON-NLS-1$
+ }
+
+ /**
+ * Asserts that the given boolean is <code>true</code>. If this is not the case, some kind of unchecked exception
+ * is thrown. The given message is included in that exception, to aid debugging.
+ *
+ * @param expression
+ * the outcome of the check
+ * @param message
+ * the message to include in the exception
+ * @return <code>true</code> if the check passes (does not return if the check fails)
+ */
+ public static boolean isTrue(boolean expression, String message) {
+ if (!expression)
+ throw new AssertionFailedException(IMPMessages.Assert_assertion_failed + message);
+ return expression;
+ }
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/core/ErrorHandler.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/core/ErrorHandler.java
new file mode 100644
index 000000000..e2beef8a5
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/core/ErrorHandler.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.core;
+
+import org.eclipse.imp.preferences.PreferenceCache;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.ui.PlatformUI;
+
+/*
+ * Licensed Materials - Property of IBM,
+ * (c) Copyright IBM Corp. 2005 All Rights Reserved
+ */
+/**
+ * Utility class for internal error messages
+ *
+ * @author Claffra
+ */
+public class ErrorHandler {
+ private static final boolean PRINT= true;
+ private static final boolean DUMP= true;
+ private static final boolean LOG= true;
+
+ public static void reportError(String message, Throwable e) {
+ if (message == null)
+ message = "No message given";
+ reportError(message, false, e);
+ }
+
+ public static void reportError(String message, boolean showDialog, Throwable e) {
+ if (message == null)
+ message = "No message given";
+ if (PRINT)
+ System.err.println(message);
+ if (DUMP)
+ e.printStackTrace();
+ if (LOG)
+ logError(message, e);
+ if (showDialog)
+ MessageDialog.openError(null, "IMP Error", message);
+ }
+
+ public static void reportError(String message) {
+ if (message == null)
+ message = "No message given";
+ reportError(message, false);
+ }
+
+ public static void reportError(String message, boolean showDialog) {
+ if (message == null)
+ message = "No message given";
+ reportError(message, showDialog, DUMP);
+ }
+
+ public static void reportError(final String message, boolean showDialog, boolean noDump) {
+ final String checkedMessage = message != null ? message : "No message given";
+ if (PRINT)
+ System.err.println(checkedMessage);
+ if (!noDump)
+ new Error(checkedMessage).printStackTrace();
+ if (LOG || PreferenceCache.emitMessages)
+ logError(checkedMessage, new Error(checkedMessage));
+ if (showDialog) {
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ MessageDialog.openError(PlatformUI.getWorkbench().getDisplay().getActiveShell(), "IMP Error", checkedMessage);
+ }
+ });
+ }
+ }
+
+ public static void logError(String msg, Throwable e) {
+ if (msg == null)
+ msg = "No message given";
+ RuntimePlugin.getInstance().logException(msg, e);
+ }
+
+ public static void logMessage(String msg, Throwable e) {
+ if (msg == null)
+ msg = "No message given";
+ RuntimePlugin.getInstance().logException(msg, e);
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/core/IMPMessages.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/core/IMPMessages.java
new file mode 100644
index 000000000..1f008f887
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/core/IMPMessages.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.core;
+
+import java.text.MessageFormat;
+import org.eclipse.osgi.util.NLS;
+
+public class IMPMessages extends NLS {
+
+ private static final String BUNDLE_NAME= "org.eclipse.imp.core.core";//$NON-NLS-1$
+
+ public static String Assert_assertion_failed;
+
+ public static String Assert_null_argument;
+
+ public static String manager_filesToIndex;
+
+ public static String manager_indexingInProgress;
+
+ public static String process_name;
+
+ public static String engine_searching;
+
+ public static String engine_searching_indexing;
+
+ public static String engine_searching_matching;
+
+ public static String StatusBarUpdater_num_elements_selected;
+
+ public static String OpenWithMenu_label;
+
+ public static String EditorUtility_concatModifierStrings;
+
+ private IMPMessages() {
+ }
+
+ public static String format(String message, Object object) {
+ return MessageFormat.format(message, new Object[] { object});
+ }
+
+ public static String format(String message, Object[] objects) {
+ return MessageFormat.format(message, objects);
+ }
+
+ static {
+ NLS.initializeMessages(BUNDLE_NAME, IMPMessages.class);
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/core/core.properties b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/core/core.properties
new file mode 100644
index 000000000..4a5c4c650
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/core/core.properties
@@ -0,0 +1,2 @@
+Assert_assertion_failed= Assertion failed
+Assert_null_argument=Invalid null argument
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/AnnotationHoverBase.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/AnnotationHoverBase.java
new file mode 100644
index 000000000..0cee1eadc
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/AnnotationHoverBase.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+/*
+ * Created on Oct 27, 2006
+ */
+package org.eclipse.imp.editor;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.imp.utils.HTMLPrinter;
+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;
+import org.eclipse.jface.text.source.ISourceViewerExtension2;
+import org.eclipse.jface.text.source.projection.AnnotationBag;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
+
+public class AnnotationHoverBase implements IAnnotationHover, ILanguageService {
+
+ public AnnotationHoverBase() {
+ }
+
+ protected static boolean isRulerLine(Position position, IDocument document, int line) {
+ if (position.getOffset() > -1 && position.getLength() > -1) {
+ try {
+ // RMF 11/10/2006 - This used to add 1 to the line computed by the document,
+ // which appears to be bogus. First, it didn't work right (annotation hovers
+ // never appeared); second, the line passed in comes from the Eclipse
+ // framework, so it should be consistent (wrt the index base) with what the
+ // IDocument API provides.
+ return line == document.getLineOfOffset(position.getOffset())/* + 1 */;
+ } catch (BadLocationException x) {
+ }
+ }
+ return false;
+ }
+
+ protected static IAnnotationModel getAnnotationModel(ISourceViewer viewer) {
+ if (viewer instanceof ISourceViewerExtension2) {
+ ISourceViewerExtension2 extension= (ISourceViewerExtension2) viewer;
+ return extension.getVisualAnnotationModel();
+ }
+ return viewer.getAnnotationModel();
+ }
+
+ public static List<Annotation> getSourceAnnotationsForLine(ISourceViewer viewer, int line) {
+ IAnnotationModel model= getAnnotationModel(viewer);
+ if (model == null)
+ return null;
+
+ IDocument document= viewer.getDocument();
+ List<Annotation> srcAnnotations= new ArrayList<Annotation>();
+ Iterator<?> iterator= model.getAnnotationIterator();
+
+ while (iterator.hasNext()) {
+ Annotation annotation= (Annotation) iterator.next();
+ Position position= model.getPosition(annotation);
+
+ if (position == null)
+ continue;
+
+ if (!isRulerLine(position, document, line))
+ continue;
+
+ if (annotation instanceof AnnotationBag) {
+ AnnotationBag bag= (AnnotationBag) annotation;
+ for(Iterator<?> iter= bag.iterator(); iter.hasNext(); ) {
+ Annotation bagAnnotation= (Annotation) iter.next();
+
+ position= model.getPosition(bagAnnotation);
+ if (position != null && includeAnnotation(bagAnnotation, position))
+ srcAnnotations.add(bagAnnotation);
+ }
+ } else {
+ if (includeAnnotation(annotation, position))
+ srcAnnotations.add(annotation);
+ }
+ }
+
+ return srcAnnotations;
+ }
+
+ // Following is just used for debugging to discover new annotation types to filter out
+// private static Set<String> fAnnotationTypes= new HashSet<String>();
+
+ private static Set<String> sAnnotationTypesToFilter= new HashSet<String>();
+
+ static {
+ sAnnotationTypesToFilter.add("org.eclipse.ui.workbench.texteditor.quickdiffUnchanged");
+ sAnnotationTypesToFilter.add("org.eclipse.ui.workbench.texteditor.quickdiffChange");
+ sAnnotationTypesToFilter.add("org.eclipse.debug.core.breakpoint");
+ sAnnotationTypesToFilter.add(MarkOccurrencesAction.OCCURRENCE_ANNOTATION);
+ sAnnotationTypesToFilter.add(ProjectionAnnotation.TYPE);
+ }
+
+ /**
+ * Check preferences, etc., to determine whether this annotation is actually showing.
+ * (Don't want to show a hover for a non-visible annotation.)
+ * @param annotation
+ * @param position
+ * @return
+ */
+ private static boolean includeAnnotation(Annotation annotation, Position position) {
+ String type= annotation.getType();
+// if (!fAnnotationTypes.contains(type)) {
+// fAnnotationTypes.add(type);
+// System.out.println("Annotation type: " + type);
+// }
+ return !sAnnotationTypesToFilter.contains(type);
+ }
+
+ public static String formatAnnotationList(List<Annotation> javaAnnotations) {
+ if (javaAnnotations != null) {
+ if (javaAnnotations.size() == 1) {
+ // optimization
+ Annotation annotation= (Annotation) javaAnnotations.get(0);
+ String message= annotation.getText();
+
+ if (message != null && message.trim().length() > 0)
+ return formatSingleMessage(message);
+ } else {
+ List<String> messages= new ArrayList<String>(javaAnnotations.size());
+
+ for(Annotation annotation: javaAnnotations) {
+ String message= annotation.getText();
+ if (message != null && message.trim().length() > 0)
+ messages.add(message.trim());
+ }
+
+ if (messages.size() == 1)
+ return formatSingleMessage((String) messages.get(0));
+
+ if (messages.size() > 1)
+ return formatMultipleMessages(messages);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Formats a message as HTML text.
+ */
+ public static String formatSingleMessage(String message) {
+// if (true) // until we hook in the HTML-enabled hover viewer
+// return message;
+ StringBuffer buffer= new StringBuffer();
+ HTMLPrinter.addPageProlog(buffer);
+ HTMLPrinter.addParagraph(buffer, HTMLPrinter.convertToHTMLContent(message));
+ HTMLPrinter.addPageEpilog(buffer);
+ return buffer.toString();
+ }
+
+ /**
+ * Formats several messages as HTML text.
+ */
+ public static String formatMultipleMessages(List<String> messages) {
+ // TODO Hook in the HTML-enabled hover viewer
+// if (true) { // until we hook in the HTML-enabled hover viewer
+// StringBuilder sb= new StringBuilder();
+//
+// sb.append("Multiple messages:\n");
+// int idx= 0;
+// for(String msg: messages) {
+// if (idx++ > 0) { sb.append('\n'); }
+// sb.append(" ");
+// sb.append(msg);
+// }
+// return sb.toString();
+// }
+ StringBuffer buffer= new StringBuffer();
+ HTMLPrinter.addPageProlog(buffer);
+ HTMLPrinter.addParagraph(buffer, HTMLPrinter.convertToHTMLContent("Multiple messages at this line"));
+
+ HTMLPrinter.startBulletList(buffer);
+ for(String msg: messages) {
+ HTMLPrinter.addBullet(buffer, HTMLPrinter.convertToHTMLContent(msg));
+ }
+ HTMLPrinter.endBulletList(buffer);
+
+ HTMLPrinter.addPageEpilog(buffer);
+ return buffer.toString();
+ }
+
+ /**
+ * @see IVerticalRulerHover#getHoverInfo(ISourceViewer, int)
+ */
+ public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
+ List<Annotation> javaAnnotations= getSourceAnnotationsForLine(sourceViewer, lineNumber);
+
+ return formatAnnotationList(javaAnnotations);
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/EditorInputUtils.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/EditorInputUtils.java
new file mode 100644
index 000000000..9265bf0b3
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/EditorInputUtils.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+* Copyright (c) 2008 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+import java.net.URI;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IPathEditorInput;
+import org.eclipse.ui.IStorageEditorInput;
+import org.eclipse.ui.IURIEditorInput;
+
+public class EditorInputUtils {
+ /**
+ * @return the IPath corresponding to the given input, or null if none
+ */
+ // TODO Determine whether this should always return project-relative paths when possible and document accordingly
+ public static IPath getPath(IEditorInput editorInput) {
+ IPath path= null;
+
+ if (editorInput instanceof IFileEditorInput) {
+ IFileEditorInput fileEditorInput= (IFileEditorInput) editorInput;
+ path= fileEditorInput.getFile().getProjectRelativePath();
+ } else if (editorInput instanceof IPathEditorInput) {
+ IPathEditorInput pathInput= (IPathEditorInput) editorInput;
+ path= pathInput.getPath();
+ } else if (editorInput instanceof IStorageEditorInput) {
+ IStorageEditorInput storageEditorInput= (IStorageEditorInput) editorInput;
+ try {
+ path= storageEditorInput.getStorage().getFullPath(); // can be null
+ } catch (CoreException e) {
+ // do nothing; return null;
+ }
+ } else if (editorInput instanceof IURIEditorInput) {
+ IURIEditorInput uriEditorInput= (IURIEditorInput) editorInput;
+ IWorkspaceRoot wsRoot= ResourcesPlugin.getWorkspace().getRoot();
+ path= new Path(uriEditorInput.getURI().getPath());
+ if (wsRoot.getProject(path.segment(0)).exists()) {
+ path= path.removeFirstSegments(1);
+ }
+ }
+ return path;
+ }
+
+ /**
+ * @return the IFile corresponding to the given input, or null if none
+ */
+ public static IFile getFile(IEditorInput editorInput) {
+ IFile file= null;
+
+ if (editorInput instanceof IFileEditorInput) {
+ IFileEditorInput fileEditorInput= (IFileEditorInput) editorInput;
+ file= fileEditorInput.getFile();
+ } else if (editorInput instanceof IPathEditorInput) {
+ IPathEditorInput pathInput= (IPathEditorInput) editorInput;
+ IWorkspaceRoot wsRoot= ResourcesPlugin.getWorkspace().getRoot();
+
+ if (wsRoot.getLocation().isPrefixOf(pathInput.getPath())) {
+ file= ResourcesPlugin.getWorkspace().getRoot().getFile(pathInput.getPath());
+ } else {
+ // Can't get an IFile for an arbitrary file on the file system; return null
+ }
+ } else if (editorInput instanceof IStorageEditorInput) {
+ file= null; // Can't get an IFile for an arbitrary IStorageEditorInput
+ } else if (editorInput instanceof IURIEditorInput) {
+ IURIEditorInput uriEditorInput= (IURIEditorInput) editorInput;
+ IWorkspaceRoot wsRoot= ResourcesPlugin.getWorkspace().getRoot();
+ URI uri= uriEditorInput.getURI();
+ String path= uri.getPath();
+ // Bug 526: uri.getHost() can be null for a local file URL
+ if (uri.getScheme().equals("file") && (uri.getHost() == null || uri.getHost().equals("localhost")) && !path.startsWith(wsRoot.getLocation().toOSString())) {
+ file= wsRoot.getFile(new Path(path));
+ }
+ }
+ return file;
+ }
+
+ /**
+ * @return the name extension (e.g., "java" or "cpp") corresponding to this
+ * input, if known, or the empty string if none. Does not include a leading
+ * ".".
+ */
+ public static String getNameExtension(IEditorInput editorInput) {
+ return getPath(editorInput).getFileExtension();
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/EditorUtility.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/EditorUtility.java
new file mode 100644
index 000000000..4f39cf810
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/EditorUtility.java
@@ -0,0 +1,483 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.filesystem.IFileSystem;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.imp.core.IMPMessages;
+import org.eclipse.imp.model.ICompilationUnit;
+import org.eclipse.imp.model.ISourceEntity;
+import org.eclipse.imp.model.ISourceProject;
+import org.eclipse.imp.model.ModelFactory;
+import org.eclipse.imp.model.ModelFactory.ModelException;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.eclipse.ui.ide.FileStoreEditorInput;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.ide.IGotoMarker;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+/**
+ * A number of routines for mapping editor inputs to/from model elements.
+ *
+ * Use 'isOpenInEditor' to test if an element is already open in a editor.
+ * Use 'openInEditor' to force opening an element in a editor.
+ * With 'getWorkingCopy' you get the working copy (element in the editor) of an element.
+ */
+public class EditorUtility {
+ public static boolean isEditorInput(Object element, IEditorPart editor) {
+ if (editor != null) {
+ return editor.getEditorInput().equals(getEditorInput(element));
+ }
+ return false;
+ }
+
+ /**
+ * Tests if a given input element is currently shown in an editor
+ *
+ * @return the IEditorPart if shown, null if element is not open in an editor
+ */
+ public static IEditorPart isOpenInEditor(Object inputElement) {
+ IEditorInput input= null;
+ input= getEditorInput(inputElement);
+ if (input != null) {
+ IWorkbenchPage p= PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ if (p != null) {
+ return p.findEditor(input);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Opens an editor suitable for a model element, <code>IFile</code>, or <code>IStorage</code>.
+ * The editor is activated by default.
+ *
+ * @return the IEditorPart or null if wrong element type or opening failed
+ */
+ public static IEditorPart openInEditor(Object inputElement) throws PartInitException {
+ return openInEditor(inputElement, true);
+ }
+
+ /**
+ * Opens an editor suitable for a model element, IFile, IStorage...
+ *
+ * @return the IEditorPart or null if wrong element type or opening failed
+ */
+ public static IEditorPart openInEditor(Object inputElement, boolean activate) throws PartInitException {
+ if (inputElement instanceof IFile)
+ return openInEditor((IFile) inputElement, activate);
+ if (inputElement instanceof ISourceEntity) {
+ ICompilationUnit cu= (ICompilationUnit) ((ISourceEntity) inputElement).getAncestor(ICompilationUnit.class);
+
+ if (cu != null /*&& !JavaModelUtil.isPrimary(cu) */) {
+ /*
+ * Support for non-primary working copy. Try to reveal it in the active editor.
+ */
+ IWorkbenchPage page= PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ if (page != null) {
+ IEditorPart editor= page.getActiveEditor();
+ if (editor != null) {
+ ISourceEntity editorCU= EditorUtility.getEditorInputModelElement(editor, false);
+ if (editorCU == cu) {
+ EditorUtility.revealInEditor(editor, (ISourceEntity) inputElement);
+ return editor;
+ }
+ }
+ }
+ }
+ }
+ IEditorInput input= getEditorInput(inputElement);
+ if (input != null)
+ return openInEditor(input, getEditorID(input, inputElement), activate);
+ return null;
+ }
+
+ /**
+ * Selects a Java Element in an editor
+ */
+ public static void revealInEditor(IEditorPart part, ISourceEntity element) {
+ if (element == null)
+ return;
+ if (part instanceof UniversalEditor) {
+ // TODO If/when there exist model elements for things smaller than CUs (e.g. types), need to do something here
+// ((UniversalEditor) part).setSelection(element);
+ return;
+ }
+ }
+
+ /**
+ * Selects and reveals the given region in the given editor part.
+ */
+ public static void revealInEditor(IEditorPart part, IRegion region) {
+ if (part != null && region != null)
+ revealInEditor(part, region.getOffset(), region.getLength());
+ }
+
+ /**
+ * Selects and reveals the given offset and length in the given editor part.
+ */
+ public static void revealInEditor(IEditorPart editor, final int offset, final int length) {
+ if (editor instanceof ITextEditor) {
+ ((ITextEditor) editor).selectAndReveal(offset, length);
+ return;
+ }
+ // Support for non-text editor - try IGotoMarker interface
+ if (editor instanceof IGotoMarker) {
+ final IEditorInput input= editor.getEditorInput();
+ if (input instanceof IFileEditorInput) {
+ final IGotoMarker gotoMarkerTarget= (IGotoMarker) editor;
+ WorkspaceModifyOperation op= new WorkspaceModifyOperation() {
+ protected void execute(IProgressMonitor monitor) throws CoreException {
+ IMarker marker= null;
+ try {
+ marker = ((IFileEditorInput) input).getFile().createMarker(IMarker.TEXT);
+ String [] attributeNames = new String[] {IMarker.CHAR_START, IMarker.CHAR_END};
+ Object [] values = new Object[] {offset, offset + length};
+ marker.setAttributes(attributeNames, values);
+
+ gotoMarkerTarget.gotoMarker(marker);
+ } finally {
+ if (marker != null)
+ marker.delete();
+ }
+ }
+ };
+ try {
+ op.run(null);
+ } catch (InvocationTargetException ex) {
+ // reveal failed
+ } catch (InterruptedException e) {
+ Assert.isTrue(false, "this operation can not be canceled"); //$NON-NLS-1$
+ }
+ }
+ return;
+ }
+ /*
+ * Workaround: send out a text selection XXX: Needs to be improved, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=32214
+ */
+ if (editor != null && editor.getEditorSite().getSelectionProvider() != null) {
+ IEditorSite site= editor.getEditorSite();
+ if (site == null)
+ return;
+ ISelectionProvider provider= editor.getEditorSite().getSelectionProvider();
+ if (provider == null)
+ return;
+ provider.setSelection(new TextSelection(offset, length));
+ }
+ }
+
+ private static IEditorPart openInEditor(IFile file, boolean activate) throws PartInitException {
+ if (file != null) {
+ IWorkbenchPage p= PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ if (p != null) {
+ IEditorPart editorPart= IDE.openEditor(p, file, activate);
+ initializeHighlightRange(editorPart);
+ return editorPart;
+ }
+ }
+ return null;
+ }
+
+ private static IEditorPart openInEditor(IEditorInput input, String editorID, boolean activate) throws PartInitException {
+ if (input != null) {
+ IWorkbenchPage p= PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ if (p != null) {
+ IEditorPart editorPart= p.openEditor(input, editorID, activate);
+ initializeHighlightRange(editorPart);
+ return editorPart;
+ }
+ }
+ return null;
+ }
+
+ private static void initializeHighlightRange(IEditorPart editorPart) {
+ if (editorPart instanceof ITextEditor) {
+ IAction toggleAction= editorPart.getEditorSite().getActionBars().getGlobalActionHandler(
+ ITextEditorActionDefinitionIds.TOGGLE_SHOW_SELECTED_ELEMENT_ONLY);
+ boolean enable= toggleAction != null;
+ if (enable && editorPart instanceof UniversalEditor)
+ // TODO Maybe support show segments?
+ enable= false; // RuntimePlugin.getInstance().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SHOW_SEGMENTS);
+ else
+ enable= enable && toggleAction.isEnabled() && toggleAction.isChecked();
+ if (enable) {
+ if (toggleAction instanceof TextEditorAction) {
+ // Reset the action
+ ((TextEditorAction) toggleAction).setEditor(null);
+ // Restore the action
+ ((TextEditorAction) toggleAction).setEditor((ITextEditor) editorPart);
+ } else {
+ // Un-check
+ toggleAction.run();
+ // Check
+ toggleAction.run();
+ }
+ }
+ }
+ }
+
+ /**
+ * @deprecated Made it public again for java debugger UI.
+ */
+ public static String getEditorID(IEditorInput input, Object inputObject) {
+ IEditorDescriptor editorDescriptor;
+ try {
+ if (input instanceof IFileEditorInput)
+ editorDescriptor= IDE.getEditorDescriptor(((IFileEditorInput) input).getFile());
+ else
+ editorDescriptor= IDE.getEditorDescriptor(input.getName());
+ } catch (PartInitException e) {
+ return null;
+ }
+ if (editorDescriptor != null)
+ return editorDescriptor.getId();
+ return null;
+ }
+
+ /**
+ * Returns the given editor's input as a model element.
+ *
+ * @param editor
+ * the editor
+ * @param primaryOnly
+ * if <code>true</code> only primary working copies will be returned
+ * @return the given editor's input as model element or <code>null</code> if none
+ * @since 3.2
+ */
+ public static ISourceEntity getEditorInputModelElement(IEditorPart editor, boolean primaryOnly) {
+ Assert.isNotNull(editor);
+ IEditorInput editorInput= editor.getEditorInput();
+ if (editorInput == null)
+ return null;
+ ISourceEntity se= getEditorInputModelElement(editorInput);
+ if (se != null || primaryOnly)
+ return se;
+ return null;
+// return RuntimePlugin.getInstance().getWorkingCopyManager().getWorkingCopy(editorInput, false);
+ }
+
+ private static IEditorInput getEditorInput(ISourceEntity element) {
+ while (element != null) {
+ if (element instanceof ICompilationUnit) {
+ ICompilationUnit unit= (ICompilationUnit) element;
+ IFile file= unit.getFile();
+
+ return new FileEditorInput(file);
+ }
+// if (element instanceof IClassFile)
+// return new InternalClassFileEditorInput((IClassFile) element);
+ element= element.getParent();
+ }
+ return null;
+ }
+
+ public static IEditorInput getEditorInput(Object input) {
+ if (input instanceof ISourceEntity)
+ return getEditorInput((ISourceEntity) input);
+ if (input instanceof IFile)
+ return new FileEditorInput((IFile) input);
+ if (input instanceof IPath) {
+ IPath path= (IPath) input;
+ if (path.isAbsolute()) {
+ try {
+ IFileSystem fileSystem= EFS.getFileSystem("file");
+ IFileStore fileStore= fileSystem.getStore((IPath) input);
+
+ return new FileStoreEditorInput(fileStore);
+ } catch (CoreException e) {
+ RuntimePlugin.getInstance().logException(e.getLocalizedMessage(), e);
+ }
+ } else {
+ IWorkspace ws= ResourcesPlugin.getWorkspace();
+ return new FileEditorInput(ws.getRoot().getFile(path));
+ }
+ }
+ return null;
+ }
+
+ public static ISourceEntity getEditorInputModelElement(IEditorInput editorInput) {
+ return (ISourceEntity) editorInput.getAdapter(ISourceEntity.class);
+ }
+
+ /**
+ * If the current active editor edits a java element return it, else return null
+ */
+ public static ISourceEntity getActiveEditorModelInput() {
+ IWorkbenchPage page= PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ if (page != null) {
+ IEditorPart part= page.getActiveEditor();
+ if (part != null) {
+ IEditorInput editorInput= part.getEditorInput();
+ if (editorInput != null) {
+ return getEditorInputModelElement(editorInput);
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Maps the localized modifier name to a code in the same manner as #findModifier.
+ *
+ * @param modifierName
+ * the modifier name
+ * @return the SWT modifier bit, or <code>0</code> if no match was found
+ * @since 2.1.1
+ */
+ public static int findLocalizedModifier(String modifierName) {
+ if (modifierName == null)
+ return 0;
+ if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.CTRL)))
+ return SWT.CTRL;
+ if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.SHIFT)))
+ return SWT.SHIFT;
+ if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.ALT)))
+ return SWT.ALT;
+ if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.COMMAND)))
+ return SWT.COMMAND;
+ return 0;
+ }
+
+ /**
+ * Returns the modifier string for the given SWT modifier modifier bits.
+ *
+ * @param stateMask
+ * the SWT modifier bits
+ * @return the modifier string
+ * @since 2.1.1
+ */
+ public static String getModifierString(int stateMask) {
+ String modifierString= ""; //$NON-NLS-1$
+ if ((stateMask & SWT.CTRL) == SWT.CTRL)
+ modifierString= appendModifierString(modifierString, SWT.CTRL);
+ if ((stateMask & SWT.ALT) == SWT.ALT)
+ modifierString= appendModifierString(modifierString, SWT.ALT);
+ if ((stateMask & SWT.SHIFT) == SWT.SHIFT)
+ modifierString= appendModifierString(modifierString, SWT.SHIFT);
+ if ((stateMask & SWT.COMMAND) == SWT.COMMAND)
+ modifierString= appendModifierString(modifierString, SWT.COMMAND);
+ return modifierString;
+ }
+
+ /**
+ * Appends to modifier string of the given SWT modifier bit to the given modifierString.
+ *
+ * @param modifierString
+ * the modifier string
+ * @param modifier
+ * an int with SWT modifier bit
+ * @return the concatenated modifier string
+ * @since 2.1.1
+ */
+ private static String appendModifierString(String modifierString, int modifier) {
+ if (modifierString == null)
+ modifierString= ""; //$NON-NLS-1$
+ String newModifierString= Action.findModifierString(modifier);
+ if (modifierString.length() == 0)
+ return newModifierString;
+ return IMPMessages.format(IMPMessages.EditorUtility_concatModifierStrings, new String[] { modifierString, newModifierString });
+ }
+
+ /**
+ * Returns the source project for a given editor input or <code>null</code> if no corresponding project exists.
+ *
+ * @param input
+ * the editor input
+ * @return the corresponding source project
+ */
+ public static ISourceProject getSourceProject(IEditorInput input) {
+ ISourceProject srcProject= null;
+
+ if (input instanceof IFileEditorInput) {
+ IProject project= ((IFileEditorInput) input).getFile().getProject();
+
+ if (project != null) {
+ try {
+ srcProject= ModelFactory.open(project);
+ } catch (ModelException e) {
+ RuntimePlugin.getInstance().logException("Error getting source project for " + project.getName(), e);
+ }
+ }
+// } else if (input instanceof IClassFileEditorInput) {
+// srcProject= ((IClassFileEditorInput) input).getClassFile().getJavaProject();
+ }
+ return srcProject;
+ }
+
+ /**
+ * Returns an array of all editors that have an unsaved content. If the identical content is presented in more than one editor, only one of those editor
+ * parts is part of the result.
+ *
+ * @return an array of all dirty editor parts.
+ */
+ public static IEditorPart[] getDirtyEditors() {
+ Set<IEditorInput> inputs= new HashSet<IEditorInput>();
+ List<IEditorPart> result= new ArrayList<IEditorPart>(0);
+ IWorkbench workbench= PlatformUI.getWorkbench();
+ IWorkbenchWindow[] windows= workbench.getWorkbenchWindows();
+
+ for(int i= 0; i < windows.length; i++) {
+ IWorkbenchPage[] pages= windows[i].getPages();
+
+ for(int x= 0; x < pages.length; x++) {
+ IEditorPart[] editors= pages[x].getDirtyEditors();
+
+ for(int z= 0; z < editors.length; z++) {
+ IEditorPart ep= editors[z];
+ IEditorInput input= ep.getEditorInput();
+
+ if (!inputs.contains(input)) {
+ inputs.add(input);
+ result.add(ep);
+ }
+ }
+ }
+ }
+ return result.toArray(new IEditorPart[result.size()]);
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ErrorProposal.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ErrorProposal.java
new file mode 100644
index 000000000..74e443c50
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ErrorProposal.java
@@ -0,0 +1,48 @@
+package org.eclipse.imp.editor;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Pseudo-ICompletionProposal implementation class for posting error info when proposals can't be computed.
+ * Maintains just an error message and a cursor position (so the text cursor position can be left undisturbed
+ * after this pseudo-proposal is "inserted").
+ * @author rfuhrer@watson.ibm.com
+ */
+public class ErrorProposal implements ICompletionProposal {
+ private final String fDescrip;
+
+ private final int fCursorLoc;
+
+ public ErrorProposal(String descrip, int cursorLoc) {
+ fDescrip= descrip;
+ fCursorLoc= cursorLoc;
+ }
+
+ public void apply(IDocument document) {
+ // do nothing
+ }
+
+ public String getAdditionalProposalInfo() {
+ return null;
+ }
+
+ public IContextInformation getContextInformation() {
+ return null;
+ }
+
+ public String getDisplayString() {
+ return fDescrip;
+ }
+
+ public Image getImage() {
+ return null;
+ }
+
+ public Point getSelection(IDocument document) {
+ return new Point(fCursorLoc, 0);
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/FoldingActionGroup.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/FoldingActionGroup.java
new file mode 100644
index 000000000..2337cfc87
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/FoldingActionGroup.java
@@ -0,0 +1,227 @@
+package org.eclipse.imp.editor;
+
+import java.util.ResourceBundle;
+
+import org.eclipse.imp.actions.FoldingMessages;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.source.projection.IProjectionListener;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.ui.editors.text.IFoldingCommandIds;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.IUpdate;
+import org.eclipse.ui.texteditor.ResourceAction;
+import org.eclipse.ui.texteditor.TextOperationAction;
+
+public class FoldingActionGroup extends ActionGroup {
+ private static abstract class PreferenceAction extends ResourceAction implements IUpdate {
+ PreferenceAction(ResourceBundle bundle, String prefix, int style) {
+ super(bundle, prefix, style);
+ }
+ }
+
+ /**
+ * @since 3.2
+ */
+ private class FoldingAction extends PreferenceAction {
+
+ FoldingAction(ResourceBundle bundle, String prefix) {
+ super(bundle, prefix, IAction.AS_PUSH_BUTTON);
+ }
+
+ public void update() {
+ setEnabled(FoldingActionGroup.this.isEnabled() && fViewer.isProjectionMode());
+ }
+
+ }
+
+ private ProjectionViewer fViewer;
+
+// private final PreferenceAction fToggle;
+ private final TextOperationAction fExpand;
+ private final TextOperationAction fCollapse;
+ private final TextOperationAction fExpandAll;
+ private final IProjectionListener fProjectionListener;
+
+ /* since 3.2 */
+ private final PreferenceAction fRestoreDefaults;
+ private final FoldingAction fCollapseMembers;
+ private final FoldingAction fCollapseComments;
+ private final TextOperationAction fCollapseAll;
+
+
+ /**
+ * Creates a new projection action group for <code>editor</code>. If the
+ * supplied viewer is not an instance of <code>ProjectionViewer</code>, the
+ * action group is disabled.
+ *
+ * @param editor the text editor to operate on
+ * @param viewer the viewer of the editor
+ */
+ public FoldingActionGroup(final ITextEditor editor, ITextViewer viewer) {
+ if (!(viewer instanceof ProjectionViewer)) {
+// fToggle= null;
+ fExpand= null;
+ fCollapse= null;
+ fExpandAll= null;
+ fCollapseAll= null;
+ fRestoreDefaults= null;
+ fCollapseMembers= null;
+ fCollapseComments= null;
+ fProjectionListener= null;
+ return;
+ }
+
+ fViewer= (ProjectionViewer) viewer;
+
+ fProjectionListener= new IProjectionListener() {
+
+ public void projectionEnabled() {
+ update();
+ }
+
+ public void projectionDisabled() {
+ update();
+ }
+ };
+
+ fViewer.addProjectionListener(fProjectionListener);
+
+// fToggle= new PreferenceAction(FoldingMessages.getResourceBundle(), "Projection.Toggle.", IAction.AS_CHECK_BOX) { //$NON-NLS-1$
+// public void run() {
+// IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore();
+// boolean current= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED);
+// store.setValue(PreferenceConstants.EDITOR_FOLDING_ENABLED, !current);
+// }
+//
+// public void update() {
+// ITextOperationTarget target= (ITextOperationTarget) editor.getAdapter(ITextOperationTarget.class);
+//
+// boolean isEnabled= (target != null && target.canDoOperation(ProjectionViewer.TOGGLE));
+// setEnabled(isEnabled);
+// }
+// };
+// fToggle.setChecked(true);
+// fToggle.setActionDefinitionId(IFoldingCommandIds.FOLDING_TOGGLE);
+// editor.setAction("FoldingToggle", fToggle); //$NON-NLS-1$
+
+ fExpandAll= new TextOperationAction(FoldingMessages.getResourceBundle(), "Projection.ExpandAll.", editor, ProjectionViewer.EXPAND_ALL, true); //$NON-NLS-1$
+ fExpandAll.setActionDefinitionId(IFoldingCommandIds.FOLDING_EXPAND_ALL);
+ editor.setAction("FoldingExpandAll", fExpandAll); //$NON-NLS-1$
+
+ fCollapseAll= new TextOperationAction(FoldingMessages.getResourceBundle(), "Projection.CollapseAll.", editor, ProjectionViewer.COLLAPSE_ALL, true); //$NON-NLS-1$
+ fCollapseAll.setActionDefinitionId(IFoldingCommandIds.FOLDING_COLLAPSE_ALL);
+ editor.setAction("FoldingCollapseAll", fCollapseAll); //$NON-NLS-1$
+
+ fExpand= new TextOperationAction(FoldingMessages.getResourceBundle(), "Projection.Expand.", editor, ProjectionViewer.EXPAND, true); //$NON-NLS-1$
+ fExpand.setActionDefinitionId(IFoldingCommandIds.FOLDING_EXPAND);
+ editor.setAction("FoldingExpand", fExpand); //$NON-NLS-1$
+
+ fCollapse= new TextOperationAction(FoldingMessages.getResourceBundle(), "Projection.Collapse.", editor, ProjectionViewer.COLLAPSE, true); //$NON-NLS-1$
+ fCollapse.setActionDefinitionId(IFoldingCommandIds.FOLDING_COLLAPSE);
+ editor.setAction("FoldingCollapse", fCollapse); //$NON-NLS-1$
+
+ fRestoreDefaults= new FoldingAction(FoldingMessages.getResourceBundle(), "Projection.Restore.") { //$NON-NLS-1$
+ public void run() {
+ if (editor instanceof UniversalEditor) {
+ UniversalEditor univEditor= (UniversalEditor) editor;
+// javaEditor.resetProjection();
+ }
+ }
+ };
+ fRestoreDefaults.setActionDefinitionId(IFoldingCommandIds.FOLDING_RESTORE);
+ editor.setAction("FoldingRestore", fRestoreDefaults); //$NON-NLS-1$
+
+ fCollapseMembers= new FoldingAction(FoldingMessages.getResourceBundle(), "Projection.CollapseMembers.") { //$NON-NLS-1$
+ public void run() {
+ if (editor instanceof UniversalEditor) {
+ UniversalEditor univEditor= (UniversalEditor) editor;
+ // TODO Need more API on UniversalEditor in order to enable the following
+// univEditor.collapseMembers();
+ }
+ }
+ };
+ fCollapseMembers.setActionDefinitionId(IEditorActionDefinitionIds.FOLDING_COLLAPSE_MEMBERS);
+ editor.setAction("FoldingCollapseMembers", fCollapseMembers); //$NON-NLS-1$
+
+ fCollapseComments= new FoldingAction(FoldingMessages.getResourceBundle(), "Projection.CollapseComments.") { //$NON-NLS-1$
+ public void run() {
+ if (editor instanceof UniversalEditor) {
+ UniversalEditor univEditor= (UniversalEditor) editor;
+ // TODO Need more API on UniversalEditor in order to enable the following
+// javaEditor.collapseComments();
+ }
+ }
+ };
+ fCollapseComments.setActionDefinitionId(IEditorActionDefinitionIds.FOLDING_COLLAPSE_COMMENTS);
+ editor.setAction("FoldingCollapseComments", fCollapseComments); //$NON-NLS-1$
+ }
+
+ /**
+ * Returns <code>true</code> if the group is enabled.
+ * <pre>
+ * Invariant: isEnabled() <=> fViewer and all actions are != null.
+ * </pre>
+ *
+ * @return <code>true</code> if the group is enabled
+ */
+ protected boolean isEnabled() {
+ return fViewer != null;
+ }
+
+ /*
+ * @see org.eclipse.ui.actions.ActionGroup#dispose()
+ */
+ public void dispose() {
+ if (isEnabled()) {
+ fViewer.removeProjectionListener(fProjectionListener);
+ fViewer= null;
+ }
+ super.dispose();
+ }
+
+ /**
+ * Updates the actions.
+ */
+ protected void update() {
+ if (isEnabled()) {
+// fToggle.update();
+// fToggle.setChecked(fViewer.isProjectionMode());
+ fExpand.update();
+ fExpandAll.update();
+ fCollapse.update();
+ fCollapseAll.update();
+ fRestoreDefaults.update();
+ fCollapseMembers.update();
+ fCollapseComments.update();
+ }
+ }
+
+ /**
+ * Fills the menu with all folding actions.
+ *
+ * @param manager the menu manager for the folding submenu
+ */
+ public void fillMenu(IMenuManager manager) {
+ if (isEnabled()) {
+ update();
+// manager.add(fToggle);
+ manager.add(fExpandAll);
+ manager.add(fExpand);
+ manager.add(fCollapse);
+ manager.add(fCollapseAll);
+ manager.add(fRestoreDefaults);
+ manager.add(fCollapseMembers);
+ manager.add(fCollapseComments);
+ }
+ }
+
+ /*
+ * @see org.eclipse.ui.actions.ActionGroup#updateActionBars()
+ */
+ public void updateActionBars() {
+ update();
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/GotoAnnotationAction.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/GotoAnnotationAction.java
new file mode 100644
index 000000000..4095d305b
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/GotoAnnotationAction.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+/**
+ * Essentially a clone of the class of the same name from JDT/UI, for navigating from one annotation to the
+ * next/previous in a source file.
+ *
+ * @author rfuhrer
+ */
+public class GotoAnnotationAction extends TextEditorAction {
+ public static final String JAVA_UI_ID_PLUGIN= "org.eclipse.jdt.ui";
+
+ public static final String PREFIX= JAVA_UI_ID_PLUGIN + '.';
+
+ private static final String nextAnnotationContextID= PREFIX + "goto_next_error_action";
+
+ private static final String prevAnnotationContextID= PREFIX + "goto_previous_error_action";
+
+ private boolean fForward;
+
+ public GotoAnnotationAction(String prefix, boolean forward) {
+ super(UniversalEditor.fgBundleForConstructedKeys, prefix, null);
+ fForward= forward;
+ if (forward)
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(this, nextAnnotationContextID);
+ else
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(this, prevAnnotationContextID);
+ }
+
+ public void run() {
+ UniversalEditor e= (UniversalEditor) getTextEditor();
+
+ e.gotoAnnotation(fForward);
+ }
+
+ public void setEditor(ITextEditor editor) {
+ if (editor instanceof UniversalEditor)
+ super.setEditor(editor);
+ update();
+ }
+
+ public void update() {
+ setEnabled(getTextEditor() instanceof UniversalEditor);
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/GotoMatchingFenceAction.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/GotoMatchingFenceAction.java
new file mode 100644
index 000000000..335835a92
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/GotoMatchingFenceAction.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+* Copyright (c) 2008 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.action.Action;
+
+public class GotoMatchingFenceAction extends Action {
+ private final UniversalEditor fEditor;
+
+ public GotoMatchingFenceAction(UniversalEditor editor) {
+ super("Go to Matching Fence");
+ Assert.isNotNull(editor);
+ fEditor= editor;
+ setEnabled(true);
+// PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.GOTO_MATCHING_BRACKET_ACTION);
+ }
+
+ public void run() {
+ fEditor.gotoMatchingFence();
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/HoverHelper.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/HoverHelper.java
new file mode 100644
index 000000000..55bc8a97f
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/HoverHelper.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+/*
+ * Created on Feb 9, 2006
+ */
+package org.eclipse.imp.editor;
+
+import java.util.List;
+
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.language.ServiceFactory;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.parser.ISourcePositionLocator;
+import org.eclipse.imp.services.IDocumentationProvider;
+import org.eclipse.imp.services.IHoverHelper;
+import org.eclipse.imp.services.IReferenceResolver;
+import org.eclipse.imp.utils.HTMLPrinter;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.ISourceViewer;
+
+/**
+ * Helper class for implementing "hover help" which encapsulates the process of locating
+ * the AST node under the cursor, and asking the documentation provider for the relevant
+ * information to show in the hover.<br>
+ * No longer an extension point itself, this class is instantiated directly by the
+ * HoverHelpController and initialized with a Language so that it can instantiate the
+ * correct documentation provider.
+ * @author rfuhrer
+ * TODO Fold this functionality into HoverHelpController?
+ */
+public class HoverHelper implements IHoverHelper {
+ private final Language fLanguage;
+
+ public HoverHelper(Language lang) {
+ fLanguage= lang;
+ }
+
+ public String getHoverHelpAt(IParseController parseController, ISourceViewer srcViewer, int offset) {
+ try {
+ List<Annotation> annotations= AnnotationHoverBase.getSourceAnnotationsForLine(srcViewer, srcViewer.getDocument().getLineOfOffset(offset));
+
+ if (annotations != null && annotations.size() > 0) {
+ return AnnotationHoverBase.formatAnnotationList(annotations);
+ }
+ } catch (BadLocationException e) {
+ return "???";
+ }
+
+ IReferenceResolver refResolver = ServiceFactory.getInstance().getReferenceResolver(fLanguage);
+ Object root= parseController.getCurrentAst();
+ ISourcePositionLocator nodeLocator = parseController.getSourcePositionLocator();
+
+ if (root == null) return null;
+
+ Object selNode = nodeLocator.findNode(root, offset);
+
+ if (selNode == null) return null;
+
+ // determine whether this is a reference to something else
+ Object target = (refResolver != null) ? refResolver.getLinkTarget(selNode, parseController) : selNode;
+
+ // if target is null, we're hovering over a declaration whose javadoc is right before us, but
+ // showing it can still be useful for previewing the javadoc formatting
+ // OR if target is null we're hovering over something not a decl or ref (e.g. integer literal)
+ // ==> show information if something other than the source is available:
+ // 1. if target != src, show something
+ // 2. if target == src, and docProvider gives something, then show it
+ // 3. if target == src, and docProvider doesn't give anything, don't show anything
+ //
+
+ // if this is not a reference, provide info for it anyway
+ if (target == null) target=selNode;
+
+ IDocumentationProvider docProvider= ServiceFactory.getInstance().getDocumentationProvider(fLanguage);
+ String doc= (docProvider != null) ? docProvider.getDocumentation(target, parseController) : null;
+
+ if (doc != null)
+ return doc;
+
+ if (target==selNode)
+ return null;
+
+ StringBuffer buffer= new StringBuffer();
+
+ HTMLPrinter.addSmallHeader(buffer, target.toString());
+ HTMLPrinter.addParagraph(buffer, doc);
+ return buffer.toString();
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/HyperlinkDetector.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/HyperlinkDetector.java
new file mode 100644
index 000000000..3ba80391c
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/HyperlinkDetector.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.language.ServiceFactory;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.parser.ISourcePositionLocator;
+import org.eclipse.imp.services.IEntityNameLocator;
+import org.eclipse.imp.services.IReferenceResolver;
+import org.eclipse.imp.services.ISourceHyperlinkDetector;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Provides a method to detect hyperlinks originating from a
+ * given region in the parse stream of a given parse controller.
+ */
+public class HyperlinkDetector implements ISourceHyperlinkDetector, ILanguageService {
+ private IReferenceResolver fResolver;
+ private IEntityNameLocator fEntityNameLocator;
+ private final Language fLanguage;
+
+ public HyperlinkDetector(Language lang) {
+ fLanguage= lang;
+ fEntityNameLocator= ServiceFactory.getInstance().getEntityNameLocator(fLanguage);
+ }
+
+ public IHyperlink[] detectHyperlinks(final IRegion region, ITextEditor editor, final ITextViewer textViewer, IParseController parseController) {
+ // This is the only language-specific bit ...
+ if (fResolver == null) {
+ fResolver = ServiceFactory.getInstance().getReferenceResolver(fLanguage);
+ }
+
+ // SMS 17 Aug 2007
+ if (fResolver == null)
+ return null;
+
+ if (parseController == null)
+ return null;
+
+ // Get stuff for getting link source node
+ Object ast= parseController.getCurrentAst();
+ if (ast == null) return null;
+ int offset= region.getOffset();
+ ISourcePositionLocator nodeLocator = parseController.getSourcePositionLocator();
+
+ // Get link source node
+ Object source = nodeLocator.findNode(ast, offset);
+ if (source == null) return null;
+
+ // Got a suitable link source node; get link target node
+ Object target = fResolver.getLinkTarget(source, parseController);
+ if (target == null) return null;
+
+ if (fEntityNameLocator != null) {
+ Object name= fEntityNameLocator.getName(target);
+ if (name != null) {
+ target= name;
+ }
+ }
+
+ // Link target node exists; get info for new hyperlink
+ // Note: source presumably has a legitimate starting offset
+ // and length (since they have been selected from the source file)
+ final int srcStart= nodeLocator.getStartOffset(source);
+ final int srcLength= nodeLocator.getEndOffset(source) - srcStart + 1;
+
+ // The target (depending on what--and where--the target is) may not have a
+ // legitimate location (or one within the file). In that case, set the target
+ // to the beginning of the file and give it a nominal length.
+
+ final int targetStart= (nodeLocator.getStartOffset(target) < 0) ? 0 : nodeLocator.getStartOffset(target);
+ final int targetLength= 0; // nodeLocator.getEndOffset(target) - targetStart + 1;
+
+ // Use the file path info to determine whether the target editor is the same as
+ // the source editor, and initialize the TargetLink accordingly.
+ final IPath targetPath= nodeLocator.getPath(target);
+ // SMS 10 Sep 2007
+ if (targetPath == null) {
+ //System.out.println("HyperlinkDetector.detectHyperlinks(..): targetPath == null, returning null");
+ return null;
+ }
+ final String linkText = fResolver.getLinkText(source);
+
+ IPath srcPath= ((IFileEditorInput) editor.getEditorInput()).getFile().getLocation();
+ // SMS 11 Jun 2007: default implementation of getPath in NodeLocator template returns
+ // an empty path, so test for that here and assume it means that the link target is in
+ // the same unit as the link source
+ IPath wsPath= ResourcesPlugin.getWorkspace().getRoot().getLocation();
+ boolean isSamePath= targetPath.equals(srcPath) || srcPath.removeFirstSegments(wsPath.segmentCount()).setDevice(null).makeAbsolute().equals(targetPath);
+
+ // SMS 5 Aug 2008
+ // The above test for isSamePath doesn't necessarily work because the default node
+ // locator always returns an empty path for any given node. Special customization
+ // is needed which, among our known IDEs, has only been done for X10DT (PolyglotNodeLocator)
+ // and LPG. So in cases where it might make sense, we can try relying on the node locator
+ // to return a negative offset for a node that is not in a given AST. I.e., if the target
+ // node is not in the same AST as the source node then assume their paths are different.
+ // OK, this might not be strictly true if you can get more than one AST from a single
+ // file, but it will prevent problems in the common case of one AST per source file.
+ if (!isSamePath && targetPath.segmentCount() == 0) {
+ isSamePath = nodeLocator.getStartOffset(target) >= 0;
+ }
+
+ ITextEditor targetEditor= (targetPath.segmentCount() == 0 || isSamePath) ? editor : null;
+ Object targetArg= targetEditor == null ? targetPath : target;
+
+ // If the target is exactly the same entity, don't bother with the hyperlink.
+ if (srcStart == targetStart && srcLength == targetLength && targetPath.equals(srcPath))
+ return null;
+
+ IRegionSelectionService selService= isSamePath ? (IRegionSelectionService) editor.getAdapter(IRegionSelectionService.class) : null;
+
+ IHyperlink[] result = new IHyperlink[] {
+ new TargetLink(linkText, srcStart, srcLength, targetArg, targetStart, targetLength, selService)
+ };
+
+ return result;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/IEditorActionDefinitionIds.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/IEditorActionDefinitionIds.java
new file mode 100644
index 000000000..a838aa61a
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/IEditorActionDefinitionIds.java
@@ -0,0 +1,36 @@
+package org.eclipse.imp.editor;
+
+/**
+ * This interface houses action definition IDs, which match command IDs, so that they
+ * can be bound to keystrokes in the UI.
+ * @author rfuhrer@watson.ibm.com
+ */
+public interface IEditorActionDefinitionIds {
+ /**
+ * Action definition ID of the navigate -> Show Outline action
+ * (value <code>"org.eclipse.imp.runtime.editor.showOutline"</code>).
+ *
+ * @since 0.1
+ */
+ public static final String SHOW_OUTLINE= "org.eclipse.imp.runtime.editor.showOutline"; //$NON-NLS-1$
+
+ /**
+ * Action definition id of the collapse members action
+ * (value: <code>"org.eclipse.imp.runtime.editor.folding.collapseMembers"</code>).
+ * @since 0.1
+ */
+ public static final String FOLDING_COLLAPSE_MEMBERS= "org.eclipse.imp.runtime.editor.folding.collapseMembers"; //$NON-NLS-1$
+
+ /**
+ * Action definition id of the collapse comments action
+ * (value: <code>"org.eclipse.imp.runtime.editor.folding.collapseComments"</code>).
+ * @since 0.1
+ */
+ public static final String FOLDING_COLLAPSE_COMMENTS= "org.eclipse.imp.runtime.editor.folding.collapseComments"; //$NON-NLS-1$
+
+ /**
+ * Source menu: id of standard Format global action
+ * (value <code>"org.eclipse.imp.runtime.editor.formatSource"</code>).
+ */
+ public static final String FORMAT= "org.eclipse.imp.runtime.editor.formatSource"; //$NON-NLS-1$
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/IMPOutlinePage.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/IMPOutlinePage.java
new file mode 100644
index 000000000..747dfcdcc
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/IMPOutlinePage.java
@@ -0,0 +1,236 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.imp.editor.OutlineLabelProvider.IElementImageProvider;
+import org.eclipse.imp.editor.internal.TreeDiffer;
+import org.eclipse.imp.parser.IModelListener;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.parser.ISourcePositionLocator;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.imp.services.base.TreeModelBuilderBase;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ITreeSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.IPageSite;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
+
+public class IMPOutlinePage extends ContentOutlinePage implements IModelListener {
+ private final OutlineContentProviderBase fContentProvider;
+ private final TreeModelBuilderBase fModelBuilder;
+ private final ILabelProvider fLabelProvider;
+ private final IElementImageProvider fImageProvider;
+ private final IParseController fParseController;
+ private final IRegionSelectionService regionSelector;
+
+ public IMPOutlinePage(IParseController parseController,
+ TreeModelBuilderBase modelBuilder,
+ ILabelProvider labelProvider, IElementImageProvider imageProvider,
+ IRegionSelectionService regionSelector) {
+ fParseController= parseController;
+ fModelBuilder= modelBuilder;
+ fLabelProvider= labelProvider;
+ fImageProvider= imageProvider;
+
+ // SMS 21 Aug 2008
+ if (regionSelector != null)
+ this.regionSelector = regionSelector;
+ else {
+ this.regionSelector = new IRegionSelectionService() {
+ public void selectAndReveal(int startOffset, int length) {
+ IEditorPart activeEditor= PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
+ ITextEditor textEditor= (ITextEditor) activeEditor;
+
+ textEditor.selectAndReveal(startOffset, length);
+ }
+ };
+ }
+
+ fContentProvider= new OutlineContentProviderBase(null) {
+ private ModelTreeNode fOldTree= null;
+
+ public Object[] getChildren(Object element) {
+ ModelTreeNode node= (ModelTreeNode) element;
+ return node.getChildren();
+ }
+ public Object getParent(Object element) {
+ ModelTreeNode node= (ModelTreeNode) element;
+ return node.getParent();
+ }
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ super.inputChanged(viewer, oldInput, newInput);
+ if (fOldTree != null) {
+ TreeDiffer treeDiffer= new TreeDiffer((TreeViewer) viewer, fLabelProvider);
+ treeDiffer.diff((ModelTreeNode) oldInput, (ModelTreeNode) newInput);
+ }
+ fOldTree= (ModelTreeNode) newInput;
+ }
+ };
+ }
+
+ public AnalysisRequired getAnalysisRequired() {
+ return IModelListener.AnalysisRequired.SYNTACTIC_ANALYSIS;
+ }
+
+ public void update(final IParseController parseController, IProgressMonitor monitor) {
+ if (getTreeViewer() != null && !getTreeViewer().getTree().isDisposed()) {
+ getTreeViewer().getTree().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ if (getTreeViewer() != null && !getTreeViewer().getTree().isDisposed())
+ getTreeViewer().setInput(fModelBuilder.buildTree(fParseController.getCurrentAst()));
+ }
+ });
+ }
+ }
+
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ super.selectionChanged(event);
+ ITreeSelection sel= (ITreeSelection) event.getSelection();
+
+ if (sel.isEmpty())
+ return;
+
+ ModelTreeNode first= (ModelTreeNode) sel.getFirstElement();
+ ISourcePositionLocator locator= fParseController.getSourcePositionLocator();
+ Object node= first.getASTNode();
+ int startOffset= locator.getStartOffset(node);
+ int endOffset= locator.getEndOffset(node);
+ int length= endOffset - startOffset + 1;
+
+ regionSelector.selectAndReveal(startOffset, length);
+// IEditorPart activeEditor= PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
+// AbstractTextEditor textEditor= (AbstractTextEditor) activeEditor;
+//
+// textEditor.selectAndReveal(startOffset, length);
+ }
+
+ public void createControl(Composite parent) {
+ super.createControl(parent);
+ TreeViewer viewer= getTreeViewer();
+ viewer.setContentProvider(fContentProvider);
+ if (fLabelProvider != null) {
+ viewer.setLabelProvider(fLabelProvider);
+ }
+ viewer.addSelectionChangedListener(this);
+ ModelTreeNode rootNode= fModelBuilder.buildTree(fParseController.getCurrentAst());
+ viewer.setInput(rootNode);
+ viewer.setAutoExpandLevel(2);
+
+ IPageSite site= getSite();
+ IActionBars actionBars= site.getActionBars();
+
+ registerToolbarActions(actionBars);
+ }
+
+ class LexicalSortingAction extends Action {
+ // TODO Need to introduce some API to provide language-specific "categories" that get used for sorting and filtering; perhaps on ModelTreeNode?
+ private ViewerComparator fElementComparator= new ViewerComparator() {
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ ModelTreeNode t1= (ModelTreeNode) e1;
+ ModelTreeNode t2= (ModelTreeNode) e2;
+ int cat1= t1.getCategory();
+ int cat2= t2.getCategory();
+
+ if (cat1 == cat2) {
+ return fLabelProvider.getText(t1).compareTo(fLabelProvider.getText(t2));
+ }
+ return cat1 - cat2;
+ }
+ };
+ private ISourcePositionLocator fLocator= fParseController.getSourcePositionLocator();
+
+ private ViewerComparator fPositionComparator= new ViewerComparator() {
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ int pos1= fLocator.getStartOffset(e1);
+ int pos2= fLocator.getStartOffset(e2);
+
+ return pos1 - pos2;
+ }
+ };
+
+ public LexicalSortingAction() {
+ super();
+// PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.LEXICAL_SORTING_OUTLINE_ACTION);
+ setText("Sort");
+ setToolTipText("Sort by name");
+ setDescription("Sort entries lexically by name");
+
+ ImageDescriptor desc= RuntimePlugin.getImageDescriptor("icons/alphab_sort_co.gif"); //$NON-NLS-1$
+ this.setHoverImageDescriptor(desc);
+ this.setImageDescriptor(desc);
+
+ boolean checked= RuntimePlugin.getInstance().getPreferenceStore().getBoolean("LexicalSortingAction.isChecked"); //$NON-NLS-1$
+ valueChanged(checked, false);
+ }
+
+ public void run() {
+ valueChanged(isChecked(), true);
+ }
+
+ private void valueChanged(final boolean on, boolean store) {
+ final TreeViewer outlineViewer= getTreeViewer();
+ setChecked(on);
+ BusyIndicator.showWhile(outlineViewer.getControl().getDisplay(), new Runnable() {
+ public void run() {
+ if (on)
+ outlineViewer.setComparator(fElementComparator);
+ else
+ outlineViewer.setComparator(fPositionComparator);
+ }
+ });
+
+ if (store) {
+ // RMF Need to store separate settings per language
+ RuntimePlugin.getInstance().getPreferenceStore().setValue("LexicalSortingAction.isChecked", on); //$NON-NLS-1$
+ }
+ }
+ }
+
+ private void registerToolbarActions(IActionBars actionBars) {
+ IToolBarManager toolBarManager= actionBars.getToolBarManager();
+ toolBarManager.add(new LexicalSortingAction());
+
+// fMemberFilterActionGroup= new MemberFilterActionGroup(fOutlineViewer, "org.eclipse.jdt.ui.JavaOutlinePage"); //$NON-NLS-1$
+// fMemberFilterActionGroup.contributeToToolBar(toolBarManager);
+//
+// fCustomFiltersActionGroup.fillActionBars(actionBars);
+//
+// IMenuManager viewMenuManager= actionBars.getMenuManager();
+// viewMenuManager.add(new Separator("EndFilterGroup")); //$NON-NLS-1$
+//
+// fToggleLinkingAction= new ToggleLinkingAction(this);
+// viewMenuManager.add(new ClassOnlyAction());
+// viewMenuManager.add(fToggleLinkingAction);
+//
+// fCategoryFilterActionGroup= new CategoryFilterActionGroup(fOutlineViewer, "org.eclipse.jdt.ui.JavaOutlinePage", new IJavaElement[] {fInput}); //$NON-NLS-1$
+// fCategoryFilterActionGroup.contributeToViewMenu(viewMenuManager);
+ }
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/IProblemChangedListener.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/IProblemChangedListener.java
new file mode 100644
index 000000000..094287b6a
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/IProblemChangedListener.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+import org.eclipse.core.resources.IResource;
+
+/**
+ * Can be added to a ProblemMarkerManager to get notified about problem marker changes. Used to update error ticks.
+ *
+ * @author Dr. Robert M. Fuhrer
+ */
+public interface IProblemChangedListener {
+ /**
+ * Called when problems changed. This call is posted in an aynch exec, therefore passed resources must not exist.
+ *
+ * @param changedResources
+ * A set with elements of type <code>IResource</code> that describe the resources that had an problem
+ * change.
+ * @param isMarkerChange
+ * If set to <code>true</code>, the change was a marker change, if <code>false</code>, the change
+ * came from an annotation model modification.
+ */
+ void problemsChanged(IResource[] changedResources, boolean isMarkerChange);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/IRegionSelectionService.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/IRegionSelectionService.java
new file mode 100644
index 000000000..e0409c04a
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/IRegionSelectionService.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+* Copyright (c) 2008 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+public interface IRegionSelectionService {
+ void selectAndReveal(int startOffset, int length);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ImageImageDescriptor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ImageImageDescriptor.java
new file mode 100644
index 000000000..6f37a8bb9
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ImageImageDescriptor.java
@@ -0,0 +1,43 @@
+package org.eclipse.imp.editor;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+
+/**
+ * An ImageDescriptor that takes its data from an already-manifested Image.
+ * Copied from the JDT class of the same name.
+ * @author rfuhrer@watson.ibm.com
+ */
+public class ImageImageDescriptor extends ImageDescriptor {
+ private Image fImage;
+
+ /**
+ * Constructor for ImagImageDescriptor.
+ */
+ public ImageImageDescriptor(Image image) {
+ super();
+ fImage= image;
+ }
+
+ /* (non-Javadoc)
+ * @see ImageDescriptor#getImageData()
+ */
+ public ImageData getImageData() {
+ return fImage.getImageData();
+ }
+
+ /* (non-Javadoc)
+ * @see Object#equals(Object)
+ */
+ public boolean equals(Object obj) {
+ return (obj != null) && getClass().equals(obj.getClass()) && fImage.equals(((ImageImageDescriptor)obj).fImage);
+ }
+
+ /* (non-Javadoc)
+ * @see Object#hashCode()
+ */
+ public int hashCode() {
+ return fImage.hashCode();
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/LanguageServiceManager.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/LanguageServiceManager.java
new file mode 100644
index 000000000..dc4dc1dfd
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/LanguageServiceManager.java
@@ -0,0 +1,249 @@
+/*******************************************************************************
+* Copyright (c) 2008 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.imp.core.ErrorHandler;
+import org.eclipse.imp.editor.OutlineLabelProvider.IElementImageProvider;
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.language.ServiceFactory;
+import org.eclipse.imp.parser.IModelListener;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.preferences.PreferenceCache;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.imp.services.IAutoEditStrategy;
+import org.eclipse.imp.services.IContentProposer;
+import org.eclipse.imp.services.IDocumentationProvider;
+import org.eclipse.imp.services.IEntityNameLocator;
+import org.eclipse.imp.services.IFoldingUpdater;
+import org.eclipse.imp.services.IHelpService;
+import org.eclipse.imp.services.IHoverHelper;
+import org.eclipse.imp.services.ILanguageActionsContributor;
+import org.eclipse.imp.services.IOccurrenceMarker;
+import org.eclipse.imp.services.IRefactoringContributor;
+import org.eclipse.imp.services.IReferenceResolver;
+import org.eclipse.imp.services.ISourceFormatter;
+import org.eclipse.imp.services.ISourceHyperlinkDetector;
+import org.eclipse.imp.services.IToggleBreakpointsHandler;
+import org.eclipse.imp.services.ITokenColorer;
+import org.eclipse.imp.services.base.TreeModelBuilderBase;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IWorkbenchPart;
+
+public class LanguageServiceManager {
+ private Language fLanguage;
+
+ private ServiceFactory fServiceFactory = ServiceFactory.getInstance();
+
+ private IParseController fParseController;
+
+ private ITokenColorer fTokenColorer;
+
+ private IReferenceResolver fResolver;
+
+ private IAnnotationHover fAnnotationHover;
+
+ private IHoverHelper fHoverHelper;
+
+ private ILabelProvider fLabelProvider;
+
+ private IElementImageProvider fImageProvider;
+
+ private TreeModelBuilderBase fModelBuilder;
+
+ private IOccurrenceMarker fOccurrenceMarker;
+
+ private ISourceHyperlinkDetector fHyperLinkDetector;
+
+ private IFoldingUpdater fFoldingUpdater;
+
+ private ISourceFormatter fFormattingStrategy;
+
+ private Set<IAutoEditStrategy> fAutoEditStrategies;
+
+ private IContentProposer fContentProposer;
+
+ private Set<IRefactoringContributor> fRefactoringContributors;
+
+ private Set<ILanguageActionsContributor> fActionContributors;
+
+ private IDocumentationProvider fDocProvider;
+
+ private Set<IModelListener> fEditorServices;
+
+ private IHelpService fContextHelper;
+
+ private IToggleBreakpointsHandler fToggleBreakpointsHandler;
+
+ private IEntityNameLocator fEntityNameLocator;
+
+ public LanguageServiceManager(Language lang) {
+ fLanguage= lang;
+ }
+
+ public void initialize(IEditorPart part) {
+ saveMyServiceManager(part, this);
+ if (PreferenceCache.emitMessages)
+ RuntimePlugin.getInstance().writeInfoMsg("Instantiating language service extensions for " + fLanguage.getName());
+
+ fActionContributors= fServiceFactory.getLanguageActionsContributors(fLanguage);
+ fAnnotationHover= fServiceFactory.getAnnotationHover(fLanguage);
+ fAutoEditStrategies= fServiceFactory.getAutoEditStrategies(fLanguage);
+ fContentProposer= fServiceFactory.getContentProposer(fLanguage);
+ fContextHelper= fServiceFactory.getContextHelper(fLanguage);
+ fDocProvider= fServiceFactory.getDocumentationProvider(fLanguage);
+ fEditorServices= fServiceFactory.getEditorServices(fLanguage);
+ fFoldingUpdater= fServiceFactory.getFoldingUpdater(fLanguage);
+ fFormattingStrategy= fServiceFactory.getSourceFormatter(fLanguage);
+ fHyperLinkDetector= fServiceFactory.getSourceHyperlinkDetector(fLanguage);
+ fImageProvider= fServiceFactory.getElementImageProvider(fLanguage);
+ fModelBuilder= fServiceFactory.getTreeModelBuilder(fLanguage);
+ fLabelProvider= fServiceFactory.getLabelProvider(fLanguage);
+ fOccurrenceMarker = fServiceFactory.getOccurrenceMarker(fLanguage);
+ fParseController= fServiceFactory.getParseController(fLanguage);
+ fRefactoringContributors= fServiceFactory.getRefactoringContributors(fLanguage);
+ fResolver= fServiceFactory.getReferenceResolver(fLanguage);
+ fToggleBreakpointsHandler= fServiceFactory.getToggleBreakpointsHandler(fLanguage);
+ fTokenColorer= fServiceFactory.getTokenColorer(fLanguage);
+ fEntityNameLocator= fServiceFactory.getEntityNameLocator(fLanguage);
+
+ if (fHyperLinkDetector == null)
+ fHyperLinkDetector= new HyperlinkDetector(fLanguage);
+
+ if (fParseController == null) {
+ ErrorHandler.reportError("Unable to instantiate parser for language '" + fLanguage.getName()
+ + "'; parser-related services will be disabled.", true, true);
+ }
+ }
+
+ public Language getLanguage() {
+ return fLanguage;
+ }
+ public Set<ILanguageActionsContributor> getActionContributors() {
+ return fActionContributors;
+ }
+
+ public IAnnotationHover getAnnotationHover() {
+ return fAnnotationHover;
+ }
+
+ public Set<IAutoEditStrategy> getAutoEditStrategies() {
+ return fAutoEditStrategies;
+ }
+
+ public IContentProposer getContentProposer() {
+ return fContentProposer;
+ }
+
+ public IHelpService getContextHelp() {
+ return fContextHelper;
+ }
+
+ public IDocumentationProvider getDocProvider() {
+ return fDocProvider;
+ }
+
+ public Set<IModelListener> getEditorServices() {
+ return fEditorServices;
+ }
+
+ public IFoldingUpdater getFoldingUpdater() {
+ return fFoldingUpdater;
+ }
+
+ public ISourceFormatter getFormattingStrategy() {
+ return fFormattingStrategy;
+ }
+
+ public IHoverHelper getHoverHelper() {
+ return fHoverHelper;
+ }
+
+ public ISourceHyperlinkDetector getHyperLinkDetector() {
+ return fHyperLinkDetector;
+ }
+
+ public IElementImageProvider getImageProvider() {
+ return fImageProvider;
+ }
+
+ public ILabelProvider getLabelProvider() {
+ return fLabelProvider;
+ }
+
+ public TreeModelBuilderBase getModelBuilder() {
+ return fModelBuilder;
+ }
+
+ public IOccurrenceMarker getOccurrenceMarker() {
+ return fOccurrenceMarker;
+ }
+
+ public IParseController getParseController() {
+ return fParseController;
+ }
+
+ public Set<IRefactoringContributor> getRefactoringContributors() {
+ return fRefactoringContributors;
+ }
+
+ public IReferenceResolver getResolver() {
+ return fResolver;
+ }
+
+ public IToggleBreakpointsHandler getToggleBreakpointsHandler() {
+ return fToggleBreakpointsHandler;
+ }
+
+ public ITokenColorer getTokenColorer() {
+ return fTokenColorer;
+ }
+
+ public IEntityNameLocator getEntityNameLocator() {
+ return fEntityNameLocator;
+ }
+
+ private static HashMap<IEditorPart, LanguageServiceManager> editorServiceMap = new HashMap<IEditorPart, LanguageServiceManager>();
+
+ public static void saveMyServiceManager(IEditorPart part, LanguageServiceManager manager) {
+ clearDeadEntries();
+ editorServiceMap.put(part, manager);
+ }
+
+ public static LanguageServiceManager getMyServiceManager(IEditorPart part) {
+ clearDeadEntries();
+ return editorServiceMap.get(part);
+ }
+
+ private static void clearDeadEntries() {
+ List<IEditorPart> deadEditors = new ArrayList<IEditorPart>();
+ for (IEditorPart edPart: editorServiceMap.keySet()) {
+ IEditorSite edSite = edPart.getEditorSite();
+ IWorkbenchPart wbPart = edSite.getPart();
+ if (wbPart == null) {
+ deadEditors.add(edPart);
+ } else {
+ }
+ }
+ for (IEditorPart edPart: deadEditors) {
+ editorServiceMap.remove(edPart);
+ }
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/MarkOccurrencesAction.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/MarkOccurrencesAction.java
new file mode 100644
index 000000000..f09392de3
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/MarkOccurrencesAction.java
@@ -0,0 +1,441 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+* - refinement and hardening
+* Stan Sutton (suttons@us.ibm.com) - refinement and hardening
+*
+*******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.imp.core.ErrorHandler;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.parser.ISourcePositionLocator;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.imp.services.IOccurrenceMarker;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.text.ISynchronizable;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.IAnnotationModelExtension;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+public class MarkOccurrencesAction implements IWorkbenchWindowActionDelegate {
+
+ public static final String OCCURRENCE_ANNOTATION= RuntimePlugin.IMP_RUNTIME + ".occurrenceAnnotation";
+
+ private boolean fMarkingEnabled = false;
+
+ private ITextEditor fActiveEditor;
+
+ private IParseController fParseController;
+
+ private IDocumentProvider fDocumentProvider;
+
+ private Object fCompilationUnit; // AST for compilation unit in active editor
+
+ private IOccurrenceMarker fOccurrenceMarker;
+
+ private Annotation[] fOccurrenceAnnotations;
+
+ private ISelectionChangedListener fSelectionListener;
+
+ private IDocumentListener fDocumentListener;
+
+ /**
+ * Listens to document changes and invalidates the AST cache to force a re-parsing.
+ */
+ private final class DocumentListener implements IDocumentListener {
+ public void documentAboutToBeChanged(DocumentEvent event) {
+ }
+
+ public void documentChanged(DocumentEvent event) {
+ fCompilationUnit= null;
+ }
+ }
+
+
+ /*
+ * Notes on the interaction of text folding and occurrence marking:
+ *
+ * When you click on a text-folding widget, you can generate two events: one signaling a
+ * change to the project model, the other signaling a change to the text selection (even
+ * though you have not directly clicked in text). The selection-changed event is propagated
+ * to the listener posted by MarkOccurrencesAction, just as selection-changed events that
+ * actually correspond to changes of selections within the text. Only selection-changed
+ * events originating within the text are of interest here. More to the point, selection-
+ * changed events from the folding widgets should be ignored because they may cause the
+ * selection (and dependent markings) to be changed in unanticipated and undesirable ways.
+ * In general, we do not expect the text selection and dependent markings to change just
+ * because the text has been folded (or unfolded).
+ *
+ * Unfortunately, while we can listen for updates to the projection annotation model,
+ * there appears to be no definite way to correlate changes in that model to changes in
+ * the annotation model that contains the selection annotations. The projection annotation
+ * events seem to be generated after the corresponding selection-changed events, and they
+ * lack a text position or timestamp that would allow them to be correlated with the
+ * selection-changed events.
+ *
+ * The one potentially useful characteristic of the selection-changed events that come
+ * from changes to the projection annotation model is that they seem to have a length of 0.
+ * On that basis, the selection listener implemented below filters out events of 0 length.
+ * This approach assumes that such events can be ignored. In practice this does prevent
+ * changes to the projection annotation model from causing inappropriate updates to the
+ * text selection. Some genuine selections of length 0 may be missed by this approach,
+ * but perhaps most text selections of interest will have length greater than 0. If not,
+ * then we can revisit this issue.
+ */
+
+
+
+ /**
+ * Listens to selection changes and forces a recomputation of the annotations.
+ * The analysis is performed once each time the compilation unit in the active
+ * editor changes, and the results are reused each time the selection changes
+ * in order to produce the annotations corresponding to the selection.
+ */
+ private final class SelectionListener implements ISelectionChangedListener {
+ private final IDocument document;
+ private ISelection previousSelection = null;
+
+ private SelectionListener(IDocument document) {
+ this.document = document;
+ }
+
+
+ public void selectionChanged(SelectionChangedEvent event) {
+ ISelection selection= event.getSelection();
+ if (selection instanceof ITextSelection) {
+ if (previousSelection != null && previousSelection.equals(selection)) {
+ return;
+ }
+
+ previousSelection = selection;
+ ITextSelection textSel= (ITextSelection) selection;
+ int offset= textSel.getOffset();
+ int length= textSel.getLength();
+
+ if (length == 0)
+ return;
+
+ recomputeAnnotationsForSelection(offset, length, document);
+ }
+ }
+ }
+
+
+ public MarkOccurrencesAction() { }
+
+
+ public void run(IAction action) {
+ fMarkingEnabled = action.isChecked();
+ if (fMarkingEnabled) {
+ setUpActiveEditor(
+ (ITextEditor) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor()
+ );
+ } else {
+ unregisterListeners();
+ removeExistingOccurrenceAnnotations();
+ }
+ }
+
+ private void registerListeners() {
+ // getDocumentFromEditor() can return null, but register listeners
+ // should only be called when there is an active editor that can
+ // be presumed to have a document provider that has document
+ IDocument document = getDocumentFromEditor();
+ if (document == null)
+ return;
+
+ createListeners(document);
+ fActiveEditor.getSelectionProvider().addSelectionChangedListener(fSelectionListener);
+ document.addDocumentListener(fDocumentListener);
+ }
+
+ private void createListeners(IDocument document) {
+ fSelectionListener= new SelectionListener(document);
+ fDocumentListener= new DocumentListener();
+ }
+
+ private void unregisterListeners() {
+ if (fActiveEditor == null)
+ return;
+ if (fSelectionListener != null) {
+ ISelectionProvider provider = fActiveEditor.getSelectionProvider();
+ if (provider != null)
+ fActiveEditor.getSelectionProvider().removeSelectionChangedListener(fSelectionListener);
+ }
+ if (fDocumentListener != null) {
+ IDocument document = getDocumentFromEditor();
+ if (document != null)
+ getDocumentFromEditor().removeDocumentListener(fDocumentListener);
+ }
+ }
+
+ private IDocument getDocumentFromEditor() {
+ IDocumentProvider provider = getDocumentProvider();
+ if (provider != null)
+ return provider.getDocument(getEditorInput());
+ else
+ return null;
+ }
+
+ private void recomputeAnnotationsForSelection(int offset, int length, IDocument document) {
+ IAnnotationModel annotationModel= fDocumentProvider.getAnnotationModel(getEditorInput());
+ Object root= getCompilationUnit();
+ if (root == null) {
+ // Get this when "selecting" an error message that is shown in the editor view
+ // but is not part of the source file; just returning should leave previous
+ // markings, if any, as they were (which is probably fine)
+ // Also get this when the current AST is null, e.g., as in the event of
+ // a parse error
+// System.err.println("MarkOccurrencesAction.recomputeAnnotationsForSelection(..): root of current AST is null; returning");
+ return;
+ }
+ Object selectedNode= fParseController.getSourcePositionLocator().findNode(root, offset, offset+length-1);
+ if (fOccurrenceMarker == null) {
+ // It might be possible to set the active editor at this point under
+ // some circumstances, but attempting to do so under other circumstances
+ // can lead to stack overflow, so just return.
+ return;
+ }
+ try {
+ List<Object> occurrences= fOccurrenceMarker.getOccurrencesOf(fParseController, selectedNode);
+ if (occurrences != null) {
+ Position[] positions= convertRefNodesToPositions(occurrences);
+
+ placeAnnotations(convertPositionsToAnnotationMap(positions, document), annotationModel);
+ } else {
+ ErrorHandler.reportError("Occurrence marker returned a null list of occurrences.");
+ }
+ } catch (Exception e) {
+ ErrorHandler.reportError("Error obtaining occurrences of selected node", e);
+ }
+ }
+
+ private Map<Annotation, Position> convertPositionsToAnnotationMap(Position[] positions, IDocument document) {
+ Map<Annotation, Position> annotationMap= new HashMap<Annotation, Position>(positions.length);
+
+ for(int i= 0; i < positions.length; i++) {
+ Position position= positions[i];
+ try { // Create & add annotation
+ String message= document.get(position.offset, position.length);
+
+ annotationMap.put(new Annotation(OCCURRENCE_ANNOTATION, false, message), position);
+ } catch (BadLocationException ex) {
+ continue; // skip apparently bogus position
+ }
+ }
+ return annotationMap;
+ }
+
+ private void placeAnnotations(Map<Annotation,Position> annotationMap, IAnnotationModel annotationModel) {
+ Object lockObject= getLockObject(annotationModel);
+
+ synchronized (lockObject) {
+ if (annotationModel instanceof IAnnotationModelExtension) {
+ ((IAnnotationModelExtension) annotationModel).replaceAnnotations(fOccurrenceAnnotations, annotationMap);
+ } else {
+ removeExistingOccurrenceAnnotations();
+ Iterator<Map.Entry<Annotation,Position>> iter= annotationMap.entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry<Annotation,Position> mapEntry= iter.next();
+ annotationModel.addAnnotation((Annotation) mapEntry.getKey(), (Position) mapEntry.getValue());
+ }
+ }
+ fOccurrenceAnnotations= (Annotation[]) annotationMap.keySet().toArray(new Annotation[annotationMap.keySet().size()]);
+ }
+ }
+
+ void removeExistingOccurrenceAnnotations() {
+ // RMF 6/27/2008 - If we've come up in an empty workspace, there won't be an active editor
+ if (fActiveEditor == null)
+ return;
+ // RMF 6/27/2008 - Apparently partActivated() gets called before the editor is initialized
+ // (on MacOS?), and then we can't properly initialize this MarkOccurrencesAction instance.
+ // When that happens, fDocumentProvider will be null. Initialization needs a fix for that,
+ // rather than this simple-minded null guard.
+ if (fDocumentProvider == null)
+ return;
+ IAnnotationModel annotationModel= fDocumentProvider.getAnnotationModel(getEditorInput());
+ if (annotationModel == null || fOccurrenceAnnotations == null)
+ return;
+
+ synchronized (getLockObject(annotationModel)) {
+ if (annotationModel instanceof IAnnotationModelExtension) {
+ ((IAnnotationModelExtension) annotationModel).replaceAnnotations(fOccurrenceAnnotations, null);
+ } else {
+ for(int i= 0, length= fOccurrenceAnnotations.length; i < length; i++)
+ annotationModel.removeAnnotation(fOccurrenceAnnotations[i]);
+ }
+ fOccurrenceAnnotations= null;
+ }
+ }
+
+
+ private Position[] convertRefNodesToPositions(List<Object> refs) {
+ Position[] positions= new Position[refs.size()];
+ int i= 0;
+ ISourcePositionLocator locator= fParseController.getSourcePositionLocator();
+
+ for(Iterator iter= refs.iterator(); iter.hasNext(); i++) {
+ Object node= iter.next();
+ positions[i]= new Position(locator.getStartOffset(node), locator.getLength(node)+1);
+ }
+ return positions;
+ }
+
+
+ private Object getCompilationUnit() {
+ // Do NOT compute fCompilationUnit conditionally based
+ // on the AST being null; that causes problems when switching
+ // between editor windows because the old value of the AST
+ // will be retained even after the new window comes up, until
+ // the text in the new window is parsed. For now just
+ // get the current AST (but in the future do something more
+ // sophisticated to avoid needless recomputation but only
+ // when it is truly needless).
+ fCompilationUnit= fParseController.getCurrentAst();
+ return fCompilationUnit;
+ }
+
+
+ private IEditorInput getEditorInput() {
+ return fActiveEditor.getEditorInput();
+ }
+
+
+ private IDocumentProvider getDocumentProvider() {
+ fDocumentProvider= fActiveEditor.getDocumentProvider();
+
+ return fDocumentProvider;
+ }
+
+
+ private void setUpActiveEditor(ITextEditor textEditor) {
+ unregisterListeners();
+ if (textEditor == null)
+ return;
+ fActiveEditor = textEditor;
+ LanguageServiceManager fLanguageServiceManager = LanguageServiceManager.getMyServiceManager(fActiveEditor);
+ if (fLanguageServiceManager == null)
+ return;
+ fParseController = fLanguageServiceManager.getParseController();
+
+ if (fParseController == null) {
+ return;
+ }
+
+ fOccurrenceMarker = fLanguageServiceManager.getOccurrenceMarker();
+ registerListeners();
+
+ ISelection selection = fActiveEditor.getSelectionProvider().getSelection();
+ if (selection instanceof ITextSelection) {
+ ITextSelection textSelection = (ITextSelection) selection;
+ recomputeAnnotationsForSelection(textSelection.getOffset(), textSelection.getLength(), getDocumentFromEditor());
+ }
+ }
+
+
+ private Object getLockObject(IAnnotationModel annotationModel) {
+ if (annotationModel instanceof ISynchronizable)
+ return ((ISynchronizable) annotationModel).getLockObject();
+ else
+ return annotationModel;
+ }
+
+
+ public void selectionChanged(IAction action, ISelection selection) {
+ }
+
+ public void dispose() {
+// System.out.println("Dispose");
+ }
+
+ public void init(IWorkbenchWindow window) {
+ window.getActivePage().addPartListener(
+ new IPartListener() {
+
+ public void partActivated(IWorkbenchPart part) {
+// System.out.println("partActivated");
+ if (part instanceof ITextEditor) {
+ setUpActiveEditor((ITextEditor)part);
+ if (fDocumentProvider == null)
+ return;
+ IAnnotationModel annotationModel= fDocumentProvider.getAnnotationModel(getEditorInput());
+ // Need to initialize the set of pre-existing annotations in order
+ // for them to be removed properly when new occurrences are marked
+ if (annotationModel != null) {
+ Iterator<Annotation> annotationIterator = annotationModel.getAnnotationIterator();
+ List<Annotation> annotationList = new ArrayList<Annotation>();
+
+ while (annotationIterator.hasNext()) {
+ // SMS 23 Jul 2008: added test for annotation type
+ Annotation ann = (Annotation)annotationIterator.next();
+ if (ann.getType().indexOf(OCCURRENCE_ANNOTATION) > -1)
+ annotationList.add(ann);
+ }
+ fOccurrenceAnnotations = annotationList.toArray(new Annotation[annotationList.size()]);
+ }
+ }
+ if (!fMarkingEnabled) {
+ unregisterListeners();
+ removeExistingOccurrenceAnnotations();
+ }
+ }
+
+ public void partBroughtToTop(IWorkbenchPart part) {
+// System.out.println("partBroughtToTop");
+ }
+
+ public void partClosed(IWorkbenchPart part) {
+ if (part == fActiveEditor) {
+ unregisterListeners();
+ fActiveEditor= null;
+ fCompilationUnit= null;
+ fDocumentProvider= null;
+ fParseController= null;
+ fOccurrenceMarker= null;
+ fOccurrenceAnnotations= null;
+ }
+ }
+
+ public void partDeactivated(IWorkbenchPart part) {
+// System.out.println("partDeactivated");
+ }
+
+ public void partOpened(IWorkbenchPart part) {
+// System.out.println("partOpened");
+ }
+ });
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ModelTreeContentProvider.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ModelTreeContentProvider.java
new file mode 100644
index 000000000..64147ee9f
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ModelTreeContentProvider.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+/**
+ *
+ */
+package org.eclipse.imp.editor;
+
+public final class ModelTreeContentProvider extends OutlineContentProviderBase {
+ public ModelTreeContentProvider(OutlineInformationControl oic) {
+ super(oic);
+ }
+
+ public Object[] getChildren(Object element) {
+ ModelTreeNode node= (ModelTreeNode) element;
+ return node.getChildren();
+ }
+
+ public Object getParent(Object element) {
+ ModelTreeNode node= (ModelTreeNode) element;
+ return node.getParent();
+ }
+} \ No newline at end of file
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ModelTreeNode.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ModelTreeNode.java
new file mode 100644
index 000000000..3181bfd53
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ModelTreeNode.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+/**
+ *
+ */
+package org.eclipse.imp.editor;
+
+public class ModelTreeNode {
+ public static final int DEFAULT_CATEGORY= 0;
+
+ private static final ModelTreeNode[] NO_CHILDREN= new ModelTreeNode[0];
+
+ private ModelTreeNode[] fChildren= NO_CHILDREN;
+
+ private ModelTreeNode fParent;
+
+ private final Object fASTNode;
+
+ private final int fCategory;
+
+ public ModelTreeNode(Object astNode) {
+ this(astNode, DEFAULT_CATEGORY);
+ }
+
+ public ModelTreeNode(Object astNode, int category) {
+ fASTNode= astNode;
+ fCategory= category;
+ }
+
+ public ModelTreeNode(Object astNode, ModelTreeNode parent) {
+ this(astNode, parent, DEFAULT_CATEGORY);
+ }
+
+ public ModelTreeNode(Object astNode, ModelTreeNode parent, int category) {
+ fASTNode= astNode;
+ fParent= parent;
+ fCategory= category;
+ }
+
+ public void setChildren(ModelTreeNode[] children) {
+ fChildren= children;
+ for(int i= 0; i < children.length; i++) {
+ children[i].fParent= this;
+ }
+ }
+
+ public void addChild(ModelTreeNode child) {
+ ModelTreeNode[] newChildren= new ModelTreeNode[fChildren.length + 1];
+ System.arraycopy(fChildren, 0, newChildren, 0, fChildren.length);
+ newChildren[fChildren.length]= child;
+ fChildren= newChildren;
+ }
+
+ public ModelTreeNode[] getChildren() {
+ return fChildren;
+ }
+
+ public ModelTreeNode getParent() {
+ return fParent;
+ }
+
+ public Object getASTNode() {
+ return fASTNode;
+ }
+
+ public int getCategory() {
+ return fCategory;
+ }
+
+ public String toString() {
+ StringBuilder sb= new StringBuilder();
+
+ sb.append(fASTNode.toString());
+ if (fChildren.length > 0) {
+ sb.append(" [");
+ for(int i= 0; i < fChildren.length; i++) {
+ sb.append(fChildren[i].toString());
+ }
+ sb.append(" ]");
+ }
+ return sb.toString();
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/OutlineContentProviderBase.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/OutlineContentProviderBase.java
new file mode 100644
index 000000000..d207dce9e
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/OutlineContentProviderBase.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+/**
+ *
+ */
+package org.eclipse.imp.editor;
+
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.widgets.Tree;
+
+public abstract class OutlineContentProviderBase implements ITreeContentProvider, ILanguageService {
+ private OutlineInformationControl fInfoControl;
+ boolean fShowInheritedMembers;
+
+ protected OutlineContentProviderBase(OutlineInformationControl oic) {
+ this(oic, false);
+ }
+
+ /**
+ * Creates a new Outline content provider.
+ *
+ * @param showInheritedMembers <code>true</code> iff inherited members are shown
+ */
+ protected OutlineContentProviderBase(OutlineInformationControl oic, boolean showInheritedMembers) {
+ fShowInheritedMembers= showInheritedMembers;
+ fInfoControl= oic;
+ }
+
+ public void setInfoControl(OutlineInformationControl infoControl) {
+ fInfoControl= infoControl;
+ }
+
+ public boolean isShowingInheritedMembers() {
+ return fShowInheritedMembers;
+ }
+
+ public void toggleShowInheritedMembers() {
+ if (fInfoControl == null) return;
+ Tree tree= fInfoControl.getTreeViewer().getTree();
+ tree.setRedraw(false);
+ fShowInheritedMembers= !fShowInheritedMembers;
+ fInfoControl.getTreeViewer().refresh();
+ fInfoControl.getTreeViewer().expandToLevel(2);
+ // reveal selection
+ Object selectedElement= fInfoControl.getSelectedElement();
+ if (selectedElement != null)
+ fInfoControl.getTreeViewer().reveal(selectedElement);
+ tree.setRedraw(true);
+ }
+
+ public Object[] getChildren(Object element) { // left here as a placeholder for the commented-out code below
+// if (fShowOnlyMainType) {
+// if (element instanceof ICompilationUnit) {
+// element= getMainType((ICompilationUnit) element);
+// } else if (element instanceof IClassFile) {
+// element= getMainType((IClassFile) element);
+// }
+// if (element == null)
+// return NO_CHILDREN;
+// }
+// if (fShowInheritedMembers && element instanceof IType) {
+// IType type= (IType) element;
+// if (type.getDeclaringType() == null) {
+// ITypeHierarchy th= getSuperTypeHierarchy(type);
+// if (th != null) {
+// List children= new ArrayList();
+// IType[] superClasses= th.getAllSupertypes(type);
+// children.addAll(Arrays.asList(super.getChildren(type)));
+// for(int i= 0, scLength= superClasses.length; i < scLength; i++)
+// children.addAll(Arrays.asList(super.getChildren(superClasses[i])));
+// return children.toArray();
+// }
+// }
+// }
+// return super.getChildren(element);
+ return OutlineInformationControl.NO_CHILDREN;
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ if (fInfoControl != null)
+ fInfoControl.fTypeHierarchies.clear();
+ }
+
+ public void dispose() {
+ if (fInfoControl != null)
+ fInfoControl.fTypeHierarchies.clear();
+ }
+
+ public boolean hasChildren(Object element) {
+ Object[] children= getChildren(element);
+
+ return (children != null) && children.length > 0;
+ }
+
+ public Object[] getElements(Object inputElement) {
+ return getChildren(inputElement);
+ }
+ } \ No newline at end of file
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/OutlineInformationControl.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/OutlineInformationControl.java
new file mode 100644
index 000000000..41d4855c1
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/OutlineInformationControl.java
@@ -0,0 +1,382 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.imp.editor.OutlineLabelProvider.IElementImageProvider;
+import org.eclipse.imp.editor.internal.AbstractInformationControl;
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.language.ServiceFactory;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.bindings.keys.KeySequence;
+import org.eclipse.jface.bindings.keys.KeyStroke;
+import org.eclipse.jface.bindings.keys.SWTKeySupport;
+import org.eclipse.jface.viewers.AbstractTreeViewer;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Item;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+
+public class OutlineInformationControl extends AbstractInformationControl {
+ private KeyAdapter fKeyAdapter;
+ private OutlineContentProviderBase fOutlineContentProvider;
+ private Object fInput= null;
+ private OutlineSorter fOutlineSorter;
+ private OutlineLabelProvider fInnerLabelProvider;
+ protected Color fForegroundColor;
+ // private boolean fShowOnlyMainType; // RMF what would this mean in general?
+ private LexicalSortingAction fLexicalSortingAction;
+ Map fTypeHierarchies= new HashMap();
+
+ private Language fLanguage;
+
+ // All of the following should be provided by language-specific extensions.
+ // private ViewerFilter fElementFilter;
+ private ILabelProvider fLangLabelProvider;
+ private IElementImageProvider fElemImageProvider;
+ private final boolean fShowStorage= false;
+
+ protected static final Object[] NO_CHILDREN= new Object[0];
+
+ private class OutlineTreeViewer extends TreeViewer {
+ private boolean fIsFiltering= false;
+
+ private OutlineTreeViewer(Tree tree) {
+ super(tree);
+ }
+
+ protected Object[] getFilteredChildren(Object parent) {
+ Object[] result= getRawChildren(parent);
+ int unfilteredChildren= result.length;
+ ViewerFilter[] filters= getFilters();
+ if (filters != null) {
+ for(int i= 0; i < filters.length; i++)
+ result= filters[i].filter(this, parent, result);
+ }
+ fIsFiltering= unfilteredChildren != result.length;
+ return result;
+ }
+
+ protected void internalExpandToLevel(Widget node, int level) {
+ if (!fIsFiltering && node instanceof Item) {
+ // Item i= (Item) node;
+ // if (i.getData() instanceof IJavaElement) {
+ // IJavaElement je= (IJavaElement) i.getData();
+ // if (je.getElementType() == IJavaElement.IMPORT_CONTAINER || isInnerType(je)) {
+ // setExpanded(i, false);
+ // return;
+ // }
+ // }
+ }
+ super.internalExpandToLevel(node, level);
+ }
+
+ // private boolean isInnerType(IJavaElement element) {
+ // if (element != null && element.getElementType() == IJavaElement.TYPE) {
+ // IType type= (IType) element;
+ // return type.isMember();
+ // }
+ // return false;
+ // }
+ }
+
+ private class OutlineSorter extends ViewerSorter {
+ // TODO Should be extensible by lang-specific implementation.
+ // Maybe an interface with a pair of methods: categoryOf(e) and compare(e1, e2)?
+ private static final int OTHER= 1;
+
+ // private static final int TYPE= 2;
+ // private static final int ANONYM= 3;
+ // private JavaElementSorter fJavaElementSorter= new JavaElementSorter();
+
+ /*
+ * @see org.eclipse.jface.viewers.ViewerSorter#sort(org.eclipse.jface.viewers.Viewer, java.lang.Object[])
+ */
+ public void sort(Viewer viewer, Object[] elements) {
+ if (!fLexicalSortingAction.isChecked())
+ return;
+ super.sort(viewer, elements);
+ }
+
+ /*
+ * @see org.eclipse.jface.viewers.ViewerSorter#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ int cat1= category(e1);
+ int cat2= category(e2);
+ if (cat1 != cat2)
+ return cat1 - cat2;
+ // if (cat1 == OTHER) { // method or field
+ // if (fSortByDefiningTypeAction.isChecked()) {
+ // IType def1= (e1 instanceof IMethod) ? getDefiningType((IMethod) e1) : null;
+ // IType def2= (e2 instanceof IMethod) ? getDefiningType((IMethod) e2) : null;
+ // if (def1 != null) {
+ // if (def2 != null) {
+ // if (!def2.equals(def1)) {
+ // return compareInHierarchy(getSuperTypeHierarchy(def1), def1, def2);
+ // }
+ // } else {
+ // return -1;
+ // }
+ // } else {
+ // if (def2 != null) {
+ // return 1;
+ // }
+ // }
+ // }
+ // } else if (cat1 == ANONYM) {
+ // return 0;
+ // }
+ String label1= fLangLabelProvider.getText(e1);
+ String label2= fLangLabelProvider.getText(e2);
+
+ return label1.compareTo(label2);
+ }
+
+ /*
+ * @see org.eclipse.jface.viewers.ViewerSorter#category(java.lang.Object)
+ */
+ public int category(Object element) {
+ // if (element instanceof IType) {
+ // IType type= (IType) element;
+ // if (type.getElementName().length() == 0) {
+ // return ANONYM;
+ // }
+ // return TYPE;
+ // }
+ return OTHER;
+ }
+ }
+
+ private class LexicalSortingAction extends Action {
+ private static final String STORE_LEXICAL_SORTING_CHECKED= "LexicalSortingAction.isChecked"; //$NON-NLS-1$
+ private TreeViewer fOutlineViewer;
+
+ private LexicalSortingAction(TreeViewer outlineViewer) {
+ super("Sort", IAction.AS_CHECK_BOX);
+ setToolTipText("Sort by name");
+ setDescription("Sort entries lexically by name");
+ RuntimePlugin.getImageDescriptor("alphab_sort_co.gif"); //$NON-NLS-1$
+ fOutlineViewer= outlineViewer;
+ boolean checked= getDialogSettings().getBoolean(STORE_LEXICAL_SORTING_CHECKED);
+ setChecked(checked);
+ // PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.LEXICAL_SORTING_BROWSING_ACTION);
+ }
+
+ public void run() {
+ valueChanged(isChecked(), true);
+ }
+
+ private void valueChanged(final boolean on, boolean store) {
+ setChecked(on);
+ BusyIndicator.showWhile(fOutlineViewer.getControl().getDisplay(), new Runnable() {
+ public void run() {
+ fOutlineViewer.refresh(false);
+ }
+ });
+ if (store)
+ getDialogSettings().put(STORE_LEXICAL_SORTING_CHECKED, on);
+ }
+ }
+
+ public OutlineInformationControl(Shell parent, int shellStyle, int treeStyle, String commandId, Language language) {
+ super(parent, shellStyle, treeStyle, commandId, true);
+ fLanguage= language;
+ }
+
+ protected Text createFilterText(Composite parent) {
+ Text text= super.createFilterText(parent);
+ text.addKeyListener(getKeyAdapter());
+ return text;
+ }
+
+ protected TreeViewer createTreeViewer(Composite parent, int style) {
+ Tree tree= new Tree(parent, SWT.SINGLE | (style & ~SWT.MULTI));
+ GridData gd= new GridData(GridData.FILL_BOTH);
+ gd.heightHint= tree.getItemHeight() * 12;
+ tree.setLayoutData(gd);
+ final TreeViewer treeViewer= new OutlineTreeViewer(tree);
+ // Hard-coded filters
+ fLexicalSortingAction= new LexicalSortingAction(treeViewer);
+ // JJV: this code is broken:
+ // if (fElementFilter != null)
+ // treeViewer.addFilter(fElementFilter);
+ fForegroundColor= parent.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY);
+
+ // RMF 7/7/2006 - oops, fLanguage is still null at this point, b/c createTreeViewer() gets called from super ctor and field inits haven't happened yet...
+ fLanguage= ((UniversalEditor) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor()).fLanguage;
+ fOutlineContentProvider= new ModelTreeContentProvider(null);
+
+ fOutlineContentProvider.setInfoControl(this);
+ fLangLabelProvider= ServiceFactory.getInstance().getLabelProvider(fLanguage);
+ fElemImageProvider= ServiceFactory.getInstance().getElementImageProvider(fLanguage);
+ // JJV; commented out because untested
+ // fElementFilter= (ViewerFilter) ExtensionPointFactory.createExtensionPoint(fLanguage, ILanguageService.VIEWER_FILTER_SERVICE);
+
+ fInnerLabelProvider= new OutlineLabelProvider(fLangLabelProvider, fElemImageProvider, fOutlineContentProvider.fShowInheritedMembers, fShowStorage,
+ fForegroundColor);
+ fInnerLabelProvider.addLabelDecorator(new ProblemsLabelDecorator(fLanguage));
+ // IDecoratorManager decoratorMgr= PlatformUI.getWorkbench().getDecoratorManager();
+ // if (decoratorMgr.getEnabled("org.eclipse.jdt.ui.override.decorator")) //$NON-NLS-1$
+ // fInnerLabelProvider.addLabelDecorator(new OverrideIndicatorLabelDecorator(null));
+ treeViewer.setLabelProvider(fInnerLabelProvider);
+ treeViewer.addFilter(new NamePatternFilter());
+ // fSortByDefiningTypeAction= new SortByDefiningTypeAction(treeViewer);
+ // fShowOnlyMainTypeAction= new ShowOnlyMainTypeAction(treeViewer);
+ treeViewer.setContentProvider(fOutlineContentProvider);
+ fOutlineSorter= new OutlineSorter();
+ treeViewer.setSorter(fOutlineSorter);
+ treeViewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
+ treeViewer.getTree().addKeyListener(getKeyAdapter());
+ return treeViewer;
+ }
+
+ @Override
+ public TreeViewer getTreeViewer() { // make visible to OutlineContentProviderBase
+ return super.getTreeViewer();
+ }
+
+ @Override
+ public Object getSelectedElement() { // make visible to OutlineContentProviderBase
+ return super.getSelectedElement();
+ }
+
+ protected String getStatusFieldText() {
+ // KeySequence[] sequences= new KeySequence[0]; // getInvokingCommandKeySequences(); // Disabled for now, since impl in jdt relied on deprecated API
+ // if (sequences == null || sequences.length == 0)
+ // return ""; //$NON-NLS-1$
+ // String keySequence= sequences[0].format();
+ if (fOutlineContentProvider.isShowingInheritedMembers())
+ return "Press Ctrl+O to hide inherited members";
+ else
+ return "Press Ctrl+O to show inherited members";
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.AbstractInformationControl#getId()
+ * @since 3.0
+ */
+ protected String getId() {
+ return "org.eclipse.imp.QuickOutline"; //$NON-NLS-1$
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setInput(Object information) {
+ if (information == null || information instanceof String) {
+ inputChanged(null, null);
+ return;
+ }
+ // IJavaElement je= (IJavaElement) information;
+ // ICompilationUnit cu= (ICompilationUnit) je.getAncestor(IJavaElement.COMPILATION_UNIT);
+ // if (cu != null)
+ // fInput= cu;
+ // else
+ // fInput= je.getAncestor(IJavaElement.CLASS_FILE);
+ fInput= information;
+ inputChanged(fInput, information);
+ }
+
+ private KeyAdapter getKeyAdapter() {
+ if (fKeyAdapter == null) {
+ fKeyAdapter= new KeyAdapter() {
+ public void keyPressed(KeyEvent e) {
+ int accelerator= SWTKeySupport.convertEventToUnmodifiedAccelerator(e);
+ KeySequence keySequence= KeySequence.getInstance(SWTKeySupport.convertAcceleratorToKeyStroke(accelerator));
+ KeyStroke[] strokes= keySequence.getKeyStrokes();
+ for(int i= 0; i < strokes.length; i++) {
+ // HACK Hard-wired code for detecting Ctrl-O...
+ if ((strokes[i].getModifierKeys() & SWT.CTRL) != 0 && strokes[i].getNaturalKey() == 'O') {
+ e.doit= false;
+ toggleShowInheritedMembers();
+ return;
+ }
+ }
+ // KeySequence[] sequences= new KeySequence[0]; // getInvokingCommandKeySequences(); // RMF 6/1/2006 - disabled since impl used deprecated API
+ // if (sequences == null)
+ // return;
+ // for(int i= 0; i < sequences.length; i++) {
+ // if (sequences[i].equals(keySequence)) {
+ // e.doit= false;
+ // toggleShowInheritedMembers();
+ // return;
+ // }
+ // }
+ }
+ };
+ }
+ return fKeyAdapter;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void handleStatusFieldClicked() {
+ toggleShowInheritedMembers();
+ }
+
+ protected void toggleShowInheritedMembers() {
+ // long flags= AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS | JavaElementLabels.F_APP_TYPE_SIGNATURE;
+ // if (!fOutlineContentProvider.isShowingInheritedMembers())
+ // flags|= JavaElementLabels.ALL_POST_QUALIFIED;
+ // fInnerLabelProvider.setTextFlags(flags);
+ fOutlineContentProvider.toggleShowInheritedMembers();
+ updateStatusFieldText();
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.AbstractInformationControl#fillViewMenu(org.eclipse.jface.action.IMenuManager)
+ */
+ protected void fillViewMenu(IMenuManager viewMenu) {
+ super.fillViewMenu(viewMenu);
+ // viewMenu.add(fShowOnlyMainTypeAction); //$NON-NLS-1$
+ viewMenu.add(new Separator("Sorters")); //$NON-NLS-1$
+ if (fLexicalSortingAction != null)
+ viewMenu.add(fLexicalSortingAction);
+ // viewMenu.add(fSortByDefiningTypeAction);
+ }
+
+ private IProgressMonitor getProgressMonitor() {
+ IWorkbenchPage wbPage= RuntimePlugin.getInstance().getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ if (wbPage == null)
+ return null;
+ IEditorPart editor= wbPage.getActiveEditor();
+ if (editor == null)
+ return null;
+ return editor.getEditorSite().getActionBars().getStatusLineManager().getProgressMonitor();
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/OutlineLabelProvider.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/OutlineLabelProvider.java
new file mode 100644
index 000000000..8b6c31e03
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/OutlineLabelProvider.java
@@ -0,0 +1,219 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+/**
+ *
+ */
+package org.eclipse.imp.editor;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.jface.viewers.IColorProvider;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+
+public class OutlineLabelProvider implements ILabelProvider, IColorProvider, ILanguageService /*, IPropertyChangeListener (to react to preference changes) */{
+ boolean fShowDefiningType;
+
+ private boolean fIsShowingInheritedMembers;
+
+ protected ListenerList fListeners= new ListenerList();
+
+ private final ILabelProvider fLanguageLabelProvider;
+
+ private ArrayList<ILabelDecorator> fLabelDecorators;
+
+ protected final StorageLabelProvider fStorageLabelProvider;
+
+ protected final IElementImageProvider fImageLabelProvider;
+
+ private Color fForegroundColor;
+
+ public interface IElementImageProvider extends ILanguageService {
+ Image getImageLabel(Object element, long imageFlags);
+ }
+
+ public OutlineLabelProvider(ILabelProvider langLabelProvider, IElementImageProvider elemImageProvider, boolean showInheritedMembers, boolean showStorage, Color foregroundColor) {
+ fLanguageLabelProvider= langLabelProvider;
+ fImageLabelProvider= elemImageProvider; // new JikesPGElementImageProvider();
+ fIsShowingInheritedMembers= showInheritedMembers;
+ fForegroundColor= foregroundColor;
+ fStorageLabelProvider= showStorage ? new StorageLabelProvider() : null;
+ }
+
+ /**
+ * Adds a decorator to the label provider
+ */
+ public void addLabelDecorator(ILabelDecorator decorator) {
+ if (fLabelDecorators == null) {
+ fLabelDecorators= new ArrayList<ILabelDecorator>(2);
+ }
+ fLabelDecorators.add(decorator);
+ }
+
+ /*
+ * @see ILabelProvider#getText
+ */
+ public String getText(Object element) {
+ String result= fLanguageLabelProvider.getText(element); // JikesPGElementLabels.getTextLabel(element, getTextFlags(element));
+ if (result.length() == 0 && (element instanceof IStorage)) {
+ result= fStorageLabelProvider.getText(element);
+ }
+ result= decorateText(result, element);
+ if (fShowDefiningType) {
+ // IType type= getDefiningType(element);
+ // if (type != null) {
+ // StringBuffer buf= new StringBuffer(super.getText(type));
+ // buf.append(JavaElementLabels.CONCAT_STRING);
+ // buf.append(result);
+ // return buf.toString();
+ // }
+ }
+ return result;
+ }
+
+ private long getTextFlags(Object element) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ private long getImageFlags(Object element) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ protected String decorateText(String text, Object element) {
+ if (fLabelDecorators != null && text.length() > 0) {
+ for(int i= 0; i < fLabelDecorators.size(); i++) {
+ ILabelDecorator decorator= (ILabelDecorator) fLabelDecorators.get(i);
+ text= decorator.decorateText(text, element);
+ }
+ }
+ return text;
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.viewsupport.JavaUILabelProvider#getForeground(java.lang.Object)
+ */
+ public Color getForeground(Object element) {
+ if (fIsShowingInheritedMembers) {
+ // if (element instanceof ASTNode) {
+ // ASTNode node= (ASTNode) element;
+ //
+ // if (fInput.getElementType() == IJavaElement.CLASS_FILE)
+ // je= je.getAncestor(IJavaElement.CLASS_FILE);
+ // else
+ // je= je.getAncestor(IJavaElement.COMPILATION_UNIT);
+ // if (fInput.equals(je)) {
+ // return null;
+ // }
+ // }
+ return fForegroundColor;
+ }
+ return null;
+ }
+
+ public Color getBackground(Object element) {
+ return null;
+ }
+
+ public void setShowDefiningType(boolean showDefiningType) {
+ fShowDefiningType= showDefiningType;
+ }
+
+ public boolean isShowDefiningType() {
+ return fShowDefiningType;
+ }
+
+ // private IType getDefiningType(Object element) {
+ // int kind= ((IJavaElement) element).getElementType();
+ // if (kind != IJavaElement.METHOD && kind != IJavaElement.FIELD && kind != IJavaElement.INITIALIZER) {
+ // return null;
+ // }
+ // IType declaringType= ((IMember) element).getDeclaringType();
+ // if (kind != IJavaElement.METHOD) {
+ // return declaringType;
+ // }
+ // ITypeHierarchy hierarchy= getSuperTypeHierarchy(declaringType);
+ // if (hierarchy == null) {
+ // return declaringType;
+ // }
+ // IMethod method= (IMethod) element;
+ // int flags= method.getFlags();
+ // if (Flags.isPrivate(flags) || Flags.isStatic(flags) || method.isConstructor()) {
+ // return declaringType;
+ // }
+ // IMethod res= JavaModelUtil.findMethodDeclarationInHierarchy(hierarchy, declaringType, method.getElementName(), method.getParameterTypes(), false);
+ // if (res == null || method.equals(res)) {
+ // return declaringType;
+ // }
+ // return res.getDeclaringType();
+ // }
+
+ public Image getImage(Object element) {
+ Image result= null;
+ if (fImageLabelProvider != null)
+ result= fImageLabelProvider.getImageLabel(element, getImageFlags(element));
+ else if (fLanguageLabelProvider != null)
+ result= fLanguageLabelProvider.getImage(element);
+ if (result == null && (element instanceof IStorage)) {
+ result= fStorageLabelProvider.getImage(element);
+ }
+ return decorateImage(result, element);
+ }
+
+ protected Image decorateImage(Image image, Object element) {
+ if (fLabelDecorators != null && image != null) {
+ for(int i= 0; i < fLabelDecorators.size(); i++) {
+ ILabelDecorator decorator= (ILabelDecorator) fLabelDecorators.get(i);
+ image= decorator.decorateImage(image, element);
+ }
+ }
+ return image;
+ }
+
+ public void addListener(ILabelProviderListener listener) {
+ fListeners.add(listener);
+ }
+
+ public void dispose() {
+ if (fLabelDecorators != null) {
+ for(int i= 0; i < fLabelDecorators.size(); i++) {
+ ILabelDecorator decorator= (ILabelDecorator) fLabelDecorators.get(i);
+ decorator.dispose();
+ }
+ fLabelDecorators= null;
+ }
+ if (fStorageLabelProvider != null)
+ fStorageLabelProvider.dispose();
+ }
+
+ public boolean isLabelProperty(Object element, String property) {
+ return true;
+ }
+
+ public void removeListener(ILabelProviderListener listener) {
+ if (fLabelDecorators != null) {
+ for(int i= 0; i < fLabelDecorators.size(); i++) {
+ ILabelDecorator decorator= (ILabelDecorator) fLabelDecorators.get(i);
+ decorator.removeListener(listener);
+ }
+ }
+ fListeners.remove(listener);
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ParserScheduler.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ParserScheduler.java
new file mode 100644
index 000000000..449e157b2
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ParserScheduler.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+* Copyright (c) 2008 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.imp.core.ErrorHandler;
+import org.eclipse.imp.language.LanguageRegistry;
+import org.eclipse.imp.parser.IMessageHandler;
+import org.eclipse.imp.parser.IModelListener;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.preferences.PreferenceCache;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+
+/**
+ * Parsing may take a long time, and is not done inside the UI thread. Therefore, we create a job that is executed in a
+ * background thread by the platform's job service.
+ */
+// TODO Perhaps this should be driven off of the "IReconcilingStrategy" mechanism?
+public class ParserScheduler extends Job {
+ private final IParseController fParseController;
+
+ private final IEditorPart fEditorPart;
+
+ private final IDocumentProvider fDocumentProvider;
+
+ private final IMessageHandler fMsgHandler;
+
+ private final List<IModelListener> fAstListeners= new ArrayList<IModelListener>();
+
+// private final IPreferencesService fPrefService;
+
+ public ParserScheduler(IParseController parseController, IEditorPart editorPart,
+ IDocumentProvider docProvider, IMessageHandler msgHandler) {
+ super(LanguageRegistry.findLanguage(EditorInputUtils.getPath(editorPart.getEditorInput()), null).getName() + " ParserScheduler for " + editorPart.getEditorInput().getName());
+ setSystem(true); // do not show this job in the Progress view
+ fParseController= parseController;
+ fEditorPart= editorPart;
+ fDocumentProvider= docProvider;
+ fMsgHandler= msgHandler;
+// fPrefService= new PreferencesService(fParseController.getProject().getRawProject(), fParseController.getLanguage().getName());
+
+ // rmf 7/1/2008 - N.B. The parse controller is now initialized before it gets handed to us here,
+ // since some other services may actually depend on that.
+ }
+
+ public IStatus run(IProgressMonitor monitor) {
+ if (fParseController == null || fDocumentProvider == null) {
+ /* Editor was closed, or no parse controller */
+ return Status.OK_STATUS;
+ }
+
+ IEditorInput editorInput= fEditorPart.getEditorInput();
+ try {
+ IDocument document= fDocumentProvider.getDocument(editorInput);
+ if (document == null) { // EDW 29 Sep 2008
+ /* Editor was deleted */
+ return Status.OK_STATUS;
+ }
+
+ if (PreferenceCache.emitMessages /* fPrefService.getBooleanPreference(PreferenceConstants.P_EMIT_MESSAGES) */) {
+ RuntimePlugin.getInstance().writeInfoMsg(
+ "Parsing language " + fParseController.getLanguage().getName() + " for input " + editorInput.getName());
+ }
+
+ // Don't need to retrieve the AST; we don't need it.
+ // Just make sure the document contents gets parsed once (and only once).
+ fMsgHandler.clearMessages();
+ fParseController.parse(document.get(), monitor);
+ if (!monitor.isCanceled())
+ notifyModelListeners(monitor);
+ } catch (Exception e) {
+ ErrorHandler.reportError("Error running parser for language " + fParseController.getLanguage().getName() + " and input " + editorInput.getName() + ":", e);
+ // RMF 8/2/2006 - Notify the AST listeners even on an exception - the compiler front end
+ // may have failed at some phase, but there may be enough info to drive IDE services.
+ notifyModelListeners(monitor);
+ } catch (LinkageError e) {
+ // Catch things like NoClassDefFoundError that might result from, e.g., errors in plugin metadata, classpath, etc.
+ ErrorHandler.reportError("Error loading IParseController implementation class for language " + fParseController.getLanguage().getName(), e);
+ }
+ return Status.OK_STATUS;
+ }
+
+ public void addModelListener(IModelListener listener) {
+ fAstListeners.add(listener);
+ }
+
+ public void removeModelListener(IModelListener listener) {
+ fAstListeners.remove(listener);
+ }
+
+ public void notifyModelListeners(IProgressMonitor monitor) {
+ // Suppress the notification if there's no AST (e.g. due to a parse error)
+ if (fParseController != null) {
+ if (
+ PreferenceCache.emitMessages
+ // TODO RMF Switch to pref svc for this, once the "global" IMP preferences (using the "IMP" pseudo-language name) gets initialized properly
+// fPrefService.isDefined(PreferenceConstants.P_EMIT_MESSAGES) &&
+// fPrefService.getBooleanPreference(PreferenceConstants.P_EMIT_MESSAGES) ||
+// RuntimePlugin.getInstance().getPreferencesService().getBooleanPreference(PreferenceConstants.P_EMIT_MESSAGES)
+ ) {
+ RuntimePlugin.getInstance().writeInfoMsg(
+ "Notifying AST listeners of change in " + fParseController.getPath().toPortableString());
+ }
+ for(int n= fAstListeners.size() - 1; n >= 0 && !monitor.isCanceled(); n--) {
+ IModelListener listener= fAstListeners.get(n);
+ // Pretend to get through the highest level of analysis so all services execute (for now)
+ int analysisLevel= IModelListener.AnalysisRequired.POINTER_ANALYSIS.level();
+
+ if (fParseController.getCurrentAst() == null)
+ analysisLevel= IModelListener.AnalysisRequired.LEXICAL_ANALYSIS.level();
+ // TODO How to tell how far we got with the source analysis? The IAnalysisController should tell us!
+ // TODO Rename IParseController to IAnalysisController
+ // TODO Compute the minimum amount of analysis sufficient for all current listeners, and pass that to
+ // the IAnalysisController.
+ if (listener.getAnalysisRequired().level() <= analysisLevel) {
+ listener.update(fParseController, monitor);
+ }
+ }
+// long curTime= System.currentTimeMillis();
+// System.out.println("All model listeners notified; time = " + curTime);
+// long diffToRuntimeStart= curTime - RuntimePlugin.PRE_STARTUP_TIME;
+// long diffToEditorStart= curTime - RuntimePlugin.EDITOR_START_TIME;
+// System.out.println("Time from runtime start: " + diffToRuntimeStart);
+// System.out.println("Time from editor start: " + diffToEditorStart);
+ } else if (PreferenceCache.emitMessages
+// fPrefService.isDefined(PreferenceConstants.P_EMIT_MESSAGES) &&
+// fPrefService.getBooleanPreference(PreferenceConstants.P_EMIT_MESSAGES) ||
+// RuntimePlugin.getInstance().getPreferencesService().getBooleanPreference(PreferenceConstants.P_EMIT_MESSAGES)
+ ) {
+ RuntimePlugin.getInstance().writeInfoMsg("No AST; bypassing listener notification.");
+ }
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ProblemsLabelDecorator.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ProblemsLabelDecorator.java
new file mode 100644
index 000000000..f9a3189fe
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ProblemsLabelDecorator.java
@@ -0,0 +1,336 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+import java.util.Iterator;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceStatus;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.imp.editor.internal.ImageDecoratorController;
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.language.ServiceFactory;
+import org.eclipse.imp.model.ICompilationUnit;
+import org.eclipse.imp.model.ISourceEntity;
+import org.eclipse.imp.runtime.ImageDescriptorRegistry;
+import org.eclipse.imp.runtime.PluginImages;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.IDecoration;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.LabelProviderChangedEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+
+/**
+ * Decorates an image of a program element to indicate any related errors/warnings.
+ * See org.eclipse.jdt.ui.ProblemsLabelDecorator for inspiration.
+ * @author rfuhrer@watson.ibm.com
+ */
+public class ProblemsLabelDecorator implements ILabelDecorator {
+ /**
+ * This is a special <code>LabelProviderChangedEvent</code> carrying additional
+ * information whether the event originates from a marker change.
+ * <p>
+ * <code>ProblemsLabelChangedEvent</code>s are only generated by <code>
+ * ProblemsLabelDecorator</code>s.
+ * </p>
+ */
+ public static class ProblemsLabelChangedEvent extends LabelProviderChangedEvent {
+ private static final long serialVersionUID= 1L;
+
+ private boolean fMarkerChange;
+
+ /**
+ * Note: This constructor is for internal use only. Clients should not call this constructor.
+ *
+ * @param eventSource the base label provider
+ * @param changedResource the changed resources
+ * @param isMarkerChange <code>true<code> if the change is a marker change; otherwise
+ * <code>false</code>
+ */
+ public ProblemsLabelChangedEvent(IBaseLabelProvider eventSource, IResource[] changedResource, boolean isMarkerChange) {
+ super(eventSource, changedResource);
+ fMarkerChange= isMarkerChange;
+ }
+
+ /**
+ * Returns whether this event origins from marker changes. If <code>false</code> an annotation
+ * model change is the origin. In this case viewers not displaying working copies can ignore these
+ * events.
+ *
+ * @return if this event origins from a marker change.
+ */
+ public boolean isMarkerChange() {
+ return fMarkerChange;
+ }
+ }
+
+ private static final int ERRORTICK_WARNING= 0;
+
+ private static final int ERRORTICK_ERROR= 1;
+
+ private ImageDescriptorRegistry fRegistry;
+
+ private ImageDecoratorController fDecoratorController;
+
+ private boolean fUseNewRegistry= false;
+
+ private IProblemChangedListener fProblemChangedListener;
+
+ private ListenerList fListeners;
+
+ public ProblemsLabelDecorator(Language lang) {
+ fRegistry= null;
+ fProblemChangedListener= null;
+ fUseNewRegistry= true;
+ fDecoratorController= new ImageDecoratorController(lang);
+ }
+
+ private ImageDescriptorRegistry getRegistry() {
+ if (fRegistry == null) {
+ fRegistry= fUseNewRegistry ? new ImageDescriptorRegistry() : RuntimePlugin.getImageDescriptorRegistry();
+ }
+ return fRegistry;
+ }
+
+ /* (non-Javadoc)
+ * @see ILabelDecorator#decorateText(String, Object)
+ */
+ public String decorateText(String text, Object element) {
+ return text;
+ }
+
+ /* (non-Javadoc)
+ * @see ILabelDecorator#decorateImage(Image, Object)
+ */
+ public Image decorateImage(Image image, Object obj) {
+ int adornmentFlags= computeAdornmentFlags(obj);
+ if (adornmentFlags != 0) {
+ ImageDescriptor baseImage= new ImageImageDescriptor(image);
+ Rectangle bounds= image.getBounds();
+ Point ptBounds= new Point(bounds.width, bounds.height);
+ return getRegistry().get(fDecoratorController.getImageDescriptor(baseImage, obj, ptBounds));
+ }
+ return image;
+ }
+
+ /**
+ * Note: This method is for internal use only. Clients should not call this method.
+ *
+ * @param obj the element to compute the flags for
+ *
+ * @return the adornment flags
+ */
+ protected int computeAdornmentFlags(Object obj) {
+ try {
+ if (obj instanceof ISourceEntity) {
+ ISourceEntity element= (ISourceEntity) obj;
+ IResource res= element.getResource();
+ int depth= IResource.DEPTH_INFINITE;
+ if (element instanceof ICompilationUnit) {
+ depth= IResource.DEPTH_ONE;
+ }
+ return getErrorTicksFromMarkers(res, depth);
+ } else if (obj instanceof IResource) {
+ return getErrorTicksFromMarkers((IResource) obj, IResource.DEPTH_INFINITE);
+ }
+ } catch (CoreException e) {
+ if (e.getStatus().getCode() == IResourceStatus.MARKER_NOT_FOUND) {
+ return 0;
+ }
+ RuntimePlugin.getInstance().logException("", e);
+ }
+ return 0;
+ }
+
+ // TODO The following code used to use the given ISourceReference to determine which markers
+ // lay within the source range of the given entity. We don't yet have ISourceEntity's for
+ // anything smaller than a compilation unit, so that functionality will have to wait for an
+ // API enhancement.
+ private int getErrorTicksFromMarkers(IResource res, int depth /*, ISourceReference sourceElement*/) throws CoreException {
+ if (res == null || !res.isAccessible()) {
+ return 0;
+ }
+ int info= 0;
+ IMarker[] markers= res.findMarkers(IMarker.PROBLEM, true, depth);
+ if (markers != null) {
+ for(int i= 0; i < markers.length && (info != ERRORTICK_ERROR); i++) {
+ IMarker curr= markers[i];
+// if (sourceElement == null || isMarkerInRange(curr, sourceElement)) {
+ int priority= curr.getAttribute(IMarker.SEVERITY, -1);
+ if (priority == IMarker.SEVERITY_WARNING) {
+ info= ERRORTICK_WARNING;
+ } else if (priority == IMarker.SEVERITY_ERROR) {
+ info= ERRORTICK_ERROR;
+ }
+// }
+ }
+ }
+ return info;
+ }
+
+// private boolean isMarkerInRange(IMarker marker, ISourceReference sourceElement) throws CoreException {
+// if (marker.isSubtypeOf(IMarker.TEXT)) {
+// int pos= marker.getAttribute(IMarker.CHAR_START, -1);
+// return isInside(pos, sourceElement);
+// }
+// return false;
+// }
+
+// private IAnnotationModel isInJavaAnnotationModel(ICompilationUnit original) {
+// if (original.isWorkingCopy()) {
+// FileEditorInput editorInput= new FileEditorInput((IFile) original.getResource());
+// return JavaPlugin.getDefault().getCompilationUnitDocumentProvider().getAnnotationModel(editorInput);
+// }
+// return null;
+// }
+
+ private int getErrorTicksFromAnnotationModel(IAnnotationModel model /*, ISourceReference sourceElement*/) throws CoreException {
+ int info= 0;
+ Iterator iter= model.getAnnotationIterator();
+ while ((info != ERRORTICK_ERROR) && iter.hasNext()) {
+ Annotation annot= (Annotation) iter.next();
+ IMarker marker= isAnnotationInRange(model, annot /*, sourceElement */);
+ if (marker != null) {
+ int priority= marker.getAttribute(IMarker.SEVERITY, -1);
+ if (priority == IMarker.SEVERITY_WARNING) {
+ info= ERRORTICK_WARNING;
+ } else if (priority == IMarker.SEVERITY_ERROR) {
+ info= ERRORTICK_ERROR;
+ }
+ }
+ }
+ return info;
+ }
+
+ private IMarker isAnnotationInRange(IAnnotationModel model, Annotation annot /*, ISourceReference sourceElement */) throws CoreException {
+ if (annot instanceof MarkerAnnotation) {
+// if (sourceElement == null || isInside(model.getPosition(annot), sourceElement)) {
+ IMarker marker= ((MarkerAnnotation) annot).getMarker();
+ if (marker.exists() && marker.isSubtypeOf(IMarker.PROBLEM)) {
+ return marker;
+ }
+// }
+ }
+ return null;
+ }
+
+// private boolean isInside(Position pos, ISourceReference sourceElement) throws CoreException {
+// return pos != null && isInside(pos.getOffset(), sourceElement);
+// }
+
+// /**
+// * Tests if a position is inside the source range of an element.
+// * @param pos Position to be tested.
+// * @param sourceElement Source element (must be a IJavaElement)
+// * @return boolean Return <code>true</code> if position is located inside the source element.
+// * @throws CoreException Exception thrown if element range could not be accessed.
+// *
+// * @since 2.1
+// */
+// protected boolean isInside(int pos, ISourceReference sourceElement) throws CoreException {
+// if (fCachedRange == null) {
+// fCachedRange= sourceElement.getSourceRange();
+// }
+// ISourceRange range= fCachedRange;
+// if (range != null) {
+// int rangeOffset= range.getOffset();
+// return (rangeOffset <= pos && rangeOffset + range.getLength() > pos);
+// }
+// return false;
+// }
+
+ /* (non-Javadoc)
+ * @see IBaseLabelProvider#dispose()
+ */
+ public void dispose() {
+ if (fProblemChangedListener != null) {
+ // TODO RMF reenable
+ // JavaPlugin.getDefault().getProblemMarkerManager().removeListener(fProblemChangedListener);
+ fProblemChangedListener= null;
+ }
+ if (fRegistry != null && fUseNewRegistry) {
+ fRegistry.dispose();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see IBaseLabelProvider#isLabelProperty(Object, String)
+ */
+ public boolean isLabelProperty(Object element, String property) {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see IBaseLabelProvider#addListener(ILabelProviderListener)
+ */
+ public void addListener(ILabelProviderListener listener) {
+ if (fListeners == null) {
+ fListeners= new ListenerList();
+ }
+ fListeners.add(listener);
+ if (fProblemChangedListener == null) {
+ fProblemChangedListener= new IProblemChangedListener() {
+ public void problemsChanged(IResource[] changedResources, boolean isMarkerChange) {
+ fireProblemsChanged(changedResources, isMarkerChange);
+ }
+ };
+ // TODO RMF reenable
+ // JavaPlugin.getDefault().getProblemMarkerManager().addListener(fProblemChangedListener);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see IBaseLabelProvider#removeListener(ILabelProviderListener)
+ */
+ public void removeListener(ILabelProviderListener listener) {
+ if (fListeners != null) {
+ fListeners.remove(listener);
+ if (fListeners.isEmpty() && fProblemChangedListener != null) {
+ // TODO RMF reenable
+ // JavaPlugin.getDefault().getProblemMarkerManager().removeListener(fProblemChangedListener);
+ fProblemChangedListener= null;
+ }
+ }
+ }
+
+ private void fireProblemsChanged(IResource[] changedResources, boolean isMarkerChange) {
+ if (fListeners != null && !fListeners.isEmpty()) {
+ LabelProviderChangedEvent event= new ProblemsLabelChangedEvent(this, changedResources, isMarkerChange);
+ Object[] listeners= fListeners.getListeners();
+ for(int i= 0; i < listeners.length; i++) {
+ ((ILabelProviderListener) listeners[i]).labelProviderChanged(event);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ILightweightLabelDecorator#decorate(java.lang.Object, org.eclipse.jface.viewers.IDecoration)
+ */
+ public void decorate(Object element, IDecoration decoration) {
+ int adornmentFlags= computeAdornmentFlags(element);
+ if (adornmentFlags == ERRORTICK_ERROR) {
+ decoration.addOverlay(PluginImages.DESC_OVR_ERROR);
+ } else if (adornmentFlags == ERRORTICK_WARNING) {
+ decoration.addOverlay(PluginImages.DESC_OVR_WARNING);
+ }
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ReferenceResolver.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ReferenceResolver.java
new file mode 100644
index 000000000..a8ac98dad
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ReferenceResolver.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.services.IReferenceResolver;
+
+/**
+ * Provides a default implementation for (most of) the the IReferenceResolver interface,
+ * the purpose of which is to support the creation of hyperlinks between nodes in an AST.
+ *
+ * The principal methods remaining for the user to implement are
+ * public Object getLinkTarget(Object node, IParseController parseController)
+ * and
+ * public String getLinkText(Object node)
+ * which will currently return not-very-useful values.
+ *
+ * @author sutton
+ */
+public abstract class ReferenceResolver implements IReferenceResolver {
+
+ protected Set<Class<?>> fSourceTypes = new HashSet<Class<?>>();
+
+ public ReferenceResolver() { }
+
+ public ReferenceResolver(Collection<Class<?>> sourceTypes)
+ {
+ fSourceTypes.addAll(sourceTypes);
+ }
+
+ public void setSourceTypes(Collection<Class<?>> sourceTypes) {
+ fSourceTypes.clear();
+ fSourceTypes.addAll(sourceTypes);
+ }
+
+ public void addSourceType (Class<?> type)
+ {
+ fSourceTypes.add(type);
+ }
+
+ public void removeSourceType(Class<?> type)
+ {
+ fSourceTypes.remove(type);
+ }
+
+ // If you don't wish to enumerate the source types for hyperlinks
+ // then fSourceTypes can be ignored and this method can be
+ // overridden in the language-specific concrete subclass so as
+ // to return an appropriate value in some other way
+ public boolean hasSuitableLinkSourceType(Object node) {
+ return fSourceTypes.contains(node.getClass());
+ }
+
+ public abstract Object getLinkTarget(Object node, IParseController parseController);
+
+ public abstract String getLinkText(Object node);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ServiceControllerManager.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ServiceControllerManager.java
new file mode 100644
index 000000000..316b87a8f
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/ServiceControllerManager.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+* Copyright (c) 2008 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+import org.eclipse.imp.editor.internal.CompletionProcessor;
+import org.eclipse.imp.editor.internal.FormattingController;
+import org.eclipse.imp.editor.internal.HoverHelpController;
+import org.eclipse.imp.editor.internal.OutlineController;
+import org.eclipse.imp.editor.internal.PresentationController;
+import org.eclipse.imp.editor.internal.SourceHyperlinkController;
+import org.eclipse.imp.parser.IModelListener;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+public class ServiceControllerManager {
+ private LanguageServiceManager fLanguageServiceManager;
+
+ private SourceHyperlinkController fHyperLinkController;
+
+ private HoverHelpController fHoverHelpController;
+
+ private FormattingController fFormattingController;
+
+ private IModelListener fOutlineController;
+
+ private PresentationController fPresentationController;
+
+ private CompletionProcessor fCompletionProcessor;
+
+ private final ITextEditor fTextEditor;
+
+ private ISourceViewer fSourceViewer;
+
+ public ServiceControllerManager(ITextEditor textEditor, LanguageServiceManager serviceMgr) {
+ fTextEditor= textEditor;
+ fLanguageServiceManager= serviceMgr;
+
+ if (fLanguageServiceManager.getHyperLinkDetector() != null)
+ fHyperLinkController= new SourceHyperlinkController(fLanguageServiceManager.getHyperLinkDetector(), fTextEditor);
+ }
+
+ public void initialize() {
+ IRegionSelectionService regionSelector= (IRegionSelectionService) fTextEditor.getAdapter(IRegionSelectionService.class);
+
+ fHoverHelpController= new HoverHelpController(fLanguageServiceManager.getLanguage());
+ fFormattingController= new FormattingController(fLanguageServiceManager.getFormattingStrategy());
+ fFormattingController.setParseController(fLanguageServiceManager.getParseController());
+
+ if (fLanguageServiceManager.getModelBuilder() != null) {
+ fOutlineController= new IMPOutlinePage(fLanguageServiceManager.getParseController(), fLanguageServiceManager.getModelBuilder(), fLanguageServiceManager.getLabelProvider(),
+ fLanguageServiceManager.getImageProvider(), regionSelector);
+ } else {
+ fOutlineController= new OutlineController(fTextEditor, fLanguageServiceManager.getLanguage());
+ }
+ fCompletionProcessor= new CompletionProcessor(fLanguageServiceManager.getLanguage());
+ }
+
+ public void setSourceViewer(ISourceViewer sourceViewer) {
+ fSourceViewer= sourceViewer;
+ fPresentationController= new PresentationController(fSourceViewer, fLanguageServiceManager);
+ }
+
+ public void setupModelListeners(ParserScheduler parserScheduler) {
+ if (fOutlineController != null)
+ parserScheduler.addModelListener(fOutlineController);
+ if (fPresentationController != null)
+ parserScheduler.addModelListener(fPresentationController);
+ if (fHoverHelpController != null)
+ parserScheduler.addModelListener(fHoverHelpController);
+ if (fHyperLinkController != null)
+ parserScheduler.addModelListener(fHyperLinkController);
+ if (fCompletionProcessor != null)
+ parserScheduler.addModelListener(fCompletionProcessor);
+ }
+
+ public SourceHyperlinkController getHyperLinkController() {
+ return fHyperLinkController;
+ }
+
+ public HoverHelpController getHoverHelpController() {
+ return fHoverHelpController;
+ }
+
+ public FormattingController getFormattingController() {
+ return fFormattingController;
+ }
+
+ public IModelListener getOutlineController() {
+ return fOutlineController;
+ }
+
+ public PresentationController getPresentationController() {
+ return fPresentationController;
+ }
+
+ public ITextEditor getTextEditor() {
+ return fTextEditor;
+ }
+
+ public ISourceViewer getSourceViewer() {
+ return fSourceViewer;
+ }
+
+ public CompletionProcessor getCompletionProcessor() {
+ return fCompletionProcessor;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/SourceEntityImageDescriptor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/SourceEntityImageDescriptor.java
new file mode 100644
index 000000000..1c38a3096
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/SourceEntityImageDescriptor.java
@@ -0,0 +1,229 @@
+/*******************************************************************************
+* Copyright (c) 2009 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+package org.eclipse.imp.editor;
+
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.imp.editor.internal.ImageDecoratorController;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.imp.services.DecorationDescriptor;
+import org.eclipse.jface.resource.CompositeImageDescriptor;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * A {@link SourceEntityImageDescriptor} consists of a base image and several adornments. The adornments
+ * are computed according to the flags either passed during creation or set via the method
+ * {@link #setAdornments(int)}.
+ * <p>
+ * N.B. The JDT version of this code specially handles certain combinations of flags using a "merged"
+ * decoration (e.g. synchronized + overrides) by checking for those first. We could duplicate that
+ * functionality for each of the quadrants, if someone wanted us to. The DecorationDescriptor and
+ * much of the logic is already prepared for that, but we'd just need to change the behavior of the
+ * various drawXXX() methods.
+ *
+ * <p>
+ * For now, we assume the decorations in each quadrant are mutually exclusive.
+ *
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ *
+ * @since 0.1
+ */
+public class SourceEntityImageDescriptor extends CompositeImageDescriptor {
+ private final ImageDecoratorController fController;
+ private ImageDescriptor fBaseImage;
+ private int fFlags;
+ private Point fSize;
+
+ /**
+ * Creates a new SourceEntityImageDescriptor.
+ *
+ * @param baseImage an image descriptor used as the base image
+ * @param flags flags indicating which adornments are to be rendered. See {@link #setAdornments(int)}
+ * for valid values.
+ * @param size the size of the resulting image
+ */
+ public SourceEntityImageDescriptor(ImageDescriptor baseImage, int flags, Point size, ImageDecoratorController ctlr) {
+ fController= ctlr;
+ fBaseImage= baseImage;
+ Assert.isNotNull(fBaseImage);
+ fFlags= flags;
+ Assert.isTrue(fFlags >= 0);
+ fSize= size;
+ Assert.isNotNull(fSize);
+ }
+
+ /**
+ * Sets the descriptors adornments. Valid values are: {@link #ABSTRACT}, {@link #FINAL},
+ * {@link #SYNCHRONIZED}, {@link #STATIC}, {@link #RUNNABLE}, {@link #WARNING},
+ * {@link #ERROR}, {@link #OVERRIDES}, {@link #IMPLEMENTS}, {@link #CONSTRUCTOR},
+ * {@link #DEPRECATED}, {@link #VOLATILE}, {@link #TRANSIENT} or any combination of those.
+ *
+ * @param adornments the image descriptors adornments
+ */
+ public void setAdornments(int adornments) {
+ Assert.isTrue(adornments >= 0);
+ fFlags= adornments;
+ }
+
+ /**
+ * Returns the current adornments.
+ *
+ * @return the current adornments
+ */
+ public int getAdornments() {
+ return fFlags;
+ }
+
+ /**
+ * Sets the size of the image created by calling {@link #createImage()}.
+ *
+ * @param size the size of the image returned from calling {@link #createImage()}
+ */
+ public void setImageSize(Point size) {
+ Assert.isNotNull(size);
+ Assert.isTrue(size.x >= 0 && size.y >= 0);
+ fSize= size;
+ }
+
+ /**
+ * Returns the size of the image created by calling {@link #createImage()}.
+ *
+ * @return the size of the image created by calling {@link #createImage()}
+ */
+ public Point getImageSize() {
+ return new Point(fSize.x, fSize.y);
+ }
+
+ /* (non-Javadoc)
+ * Method declared in CompositeImageDescriptor
+ */
+ protected Point getSize() {
+ return fSize;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on Object.
+ */
+ public boolean equals(Object object) {
+ if (object == null || !SourceEntityImageDescriptor.class.equals(object.getClass()))
+ return false;
+
+ SourceEntityImageDescriptor other= (SourceEntityImageDescriptor) object;
+ return (fBaseImage.equals(other.fBaseImage) && fFlags == other.fFlags && fSize.equals(other.fSize));
+ }
+
+ /* (non-Javadoc)
+ * Method declared on Object.
+ */
+ public int hashCode() {
+ return fBaseImage.hashCode() | fFlags | fSize.hashCode();
+ }
+
+ /* (non-Javadoc)
+ * Method declared in CompositeImageDescriptor
+ */
+ protected void drawCompositeImage(int width, int height) {
+ ImageData bg= getImageData(fBaseImage);
+
+// if ((fFlags & DEPRECATED) != 0) { // draw *behind* the full image
+// Point size= getSize();
+// ImageData data= getImageData(PluginImages.DESC_OVR_DEPRECATED);
+// drawImage(data, 0, size.y - data.height);
+// }
+ drawImage(bg, 0, 0);
+
+// drawTopLeft(); // conventionally not used
+ drawTopRight();
+ drawBottomRight();
+ drawBottomLeft();
+ }
+
+ private ImageData getImageData(ImageDescriptor descriptor) {
+ ImageData data= descriptor.getImageData(); // see bug 51965: getImageData can return null
+ if (data == null) {
+ data= DEFAULT_IMAGE_DATA;
+ RuntimePlugin.getInstance().writeErrorMsg("Image data not available: " + descriptor.toString()); //$NON-NLS-1$
+ }
+ return data;
+ }
+
+ private void addTopRightImage(ImageDescriptor desc, Point pos) {
+ ImageData data= getImageData(desc);
+ int x= pos.x - data.width;
+ if (x >= 0) {
+ drawImage(data, x, pos.y);
+ pos.x= x;
+ }
+ }
+
+ private void addBottomRightImage(ImageDescriptor desc, Point pos) {
+ ImageData data= getImageData(desc);
+ int x= pos.x - data.width;
+ int y= pos.y - data.height;
+ if (x >= 0 && y >= 0) {
+ drawImage(data, x, y);
+ pos.x= x;
+ }
+ }
+
+ private void addBottomLeftImage(ImageDescriptor desc, Point pos) {
+ ImageData data= getImageData(desc);
+ int x= pos.x;
+ int y= pos.y - data.height;
+ if (x + data.width < getSize().x && y >= 0) {
+ drawImage(data, x, y);
+ pos.x= x + data.width;
+ }
+ }
+
+ private void drawTopRight() {
+ Point pos= new Point(getSize().x, 0);
+ for(DecorationDescriptor d: fController.getTopRightDecorations()) {
+ if ((fFlags & d.mask) != 0) {
+ addTopRightImage(d.getImageDescriptor(), pos);
+ }
+ }
+ }
+
+ private void drawBottomRight() {
+ Point size= getSize();
+ Point pos= new Point(size.x, size.y);
+
+ // Were we to support "merged" decorators, we'd need to do something like the following instead:
+ //
+// int flags= fFlags;
+// for(DecorationDescriptor d: fController.getBottomRightDecorations()) {
+// if ((flags & d.mask) != 0) {
+// addBottomRightImage(d.getImageDescriptor(), pos);
+// }
+// flags &= ~d.mask;
+// }
+
+ for(DecorationDescriptor d: fController.getBottomRightDecorations()) {
+ if ((fFlags & d.mask) != 0) {
+ addBottomRightImage(d.getImageDescriptor(), pos);
+ }
+ }
+ }
+
+ private void drawBottomLeft() {
+ Point pos= new Point(0, getSize().y);
+ for(DecorationDescriptor d: fController.getBottomLeftDecorations()) {
+ if ((fFlags & d.mask) != 0) {
+ addBottomLeftImage(d.getImageDescriptor(), pos);
+ }
+ }
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/SourceProposal.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/SourceProposal.java
new file mode 100644
index 000000000..9834acb1d
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/SourceProposal.java
@@ -0,0 +1,162 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+/**
+ *
+ */
+package org.eclipse.imp.editor;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+
+public class SourceProposal implements ICompletionProposal {
+ /**
+ * The text shown to the user in the popup view
+ */
+ private final String fProposal;
+
+ /**
+ * The new text being added/substituted if the user accepts this proposal
+ */
+ private final String fNewText;
+
+ /**
+ * The prefix being completed.
+ */
+ private final String fPrefix;
+
+ /**
+ * The range of text being replaced.
+ */
+ private final Region fRange;
+
+ /**
+ * The offset at which the insertion point should be placed after completing
+ * using this proposal
+ */
+ private final int fCursorLoc;
+
+ /**
+ * Additional information displayed in the pop-up view to the right of the
+ * main proposal list view when this proposal is selected.
+ */
+ private final String fAdditionalInfo;
+
+ /**
+ * Create a new completion proposal.
+ * @param newText the actual replacement text for this proposal
+ * @param prefix the prefix being completed
+ * @param offset the starting character offset of the text to be replaced
+ */
+ public SourceProposal(String newText, String prefix, int offset) {
+ this(newText, newText, prefix, offset);
+ }
+
+ /**
+ * Create a new completion proposal.
+ * @param proposal the text to be shown in the popup view listing the proposals
+ * @param newText the actual replacement text for this proposal
+ * @param prefix the prefix being completed
+ * @param offset the starting character offset of the text to be replaced
+ */
+ public SourceProposal(String proposal, String newText, String prefix, int offset) {
+ this(proposal, newText, prefix, offset, offset + newText.length() - prefix.length());
+ }
+
+ /**
+ * Create a new completion proposal.
+ * @param proposal the text to be shown in the popup view listing the proposals
+ * @param newText the actual replacement text for this proposal
+ * @param prefix the prefix being completed
+ * @param offset the starting character offset of the text to be replaced
+ * @param cursorLoc the point at which to place the cursor after the replacement
+ */
+ public SourceProposal(String proposal, String newText, String prefix, int offset, int cursorLoc) {
+ this(proposal, newText, prefix, new Region(offset, 0), cursorLoc);
+ }
+
+ /**
+ * Create a new completion proposal.
+ * @param proposal the text to be shown in the popup view listing the proposals
+ * @param newText the actual replacement text for this proposal
+ * @param prefix the prefix being completed
+ * @param region the region of text to be replaced
+ * @param cursorLoc the point at which to place the cursor after the replacement
+ */
+ public SourceProposal(String proposal, String newText, String prefix, Region region, String addlInfo) {
+ this(proposal, newText, prefix, region, region.getOffset() + newText.length() - prefix.length(), addlInfo);
+ }
+
+ /**
+ * Create a new completion proposal.
+ * @param proposal the text to be shown in the popup view listing the proposals
+ * @param newText the actual replacement text for this proposal
+ * @param prefix the prefix being completed
+ * @param region the region of text to be replaced
+ * @param cursorLoc the point at which to place the cursor after the replacement
+ */
+ public SourceProposal(String proposal, String newText, String prefix, Region region, int cursorLoc) {
+ this(proposal, newText, prefix, region, cursorLoc, null);
+ }
+
+ /**
+ * Create a new completion proposal.
+ * @param proposal the text to be shown in the popup view listing the proposals
+ * @param newText the actual replacement text for this proposal
+ * @param prefix the prefix being completed
+ * @param region the region of text to be replaced
+ * @param cursorLoc the point at which to place the cursor after the replacement
+ * @param addlInfo the text to display in the pop-up view on the right when this
+ * proposal is selected
+ */
+ public SourceProposal(String proposal, String newText, String prefix, Region region, int cursorLoc, String addlInfo) {
+ fProposal= proposal;
+ fNewText= newText;
+ fPrefix= prefix;
+ fRange= region;
+ fCursorLoc= cursorLoc;
+ fAdditionalInfo= addlInfo;
+ }
+
+ public void apply(IDocument document) {
+ try {
+ document.replace(fRange.getOffset(), fRange.getLength(), fNewText.substring(fPrefix.length()));
+ } catch (BadLocationException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public Point getSelection(IDocument document) {
+ return new Point(fCursorLoc, 0);
+ }
+
+ public String getDisplayString() {
+ return fProposal;
+ }
+
+ public String getAdditionalProposalInfo() {
+ return fAdditionalInfo;
+ }
+
+ public Image getImage() {
+ return null;
+ }
+
+ public IContextInformation getContextInformation() {
+ return null;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/StorageLabelProvider.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/StorageLabelProvider.java
new file mode 100644
index 000000000..c0feeeb9c
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/StorageLabelProvider.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.IEditorRegistry;
+import org.eclipse.ui.IFileEditorMapping;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Standard label provider for IStorage objects.
+ * Use this class when you want to present IStorage objects in a viewer.
+ * Copied from JDT/UI internal package.
+ */
+public class StorageLabelProvider extends LabelProvider {
+
+ private IEditorRegistry fEditorRegistry= null;
+ private Map fJarImageMap= new HashMap(10);
+ private Image fDefaultImage;
+
+ private IEditorRegistry getEditorRegistry() {
+ if (fEditorRegistry == null)
+ fEditorRegistry= PlatformUI.getWorkbench().getEditorRegistry();
+ return fEditorRegistry;
+ }
+
+ /* (non-Javadoc)
+ * @see ILabelProvider#getImage
+ */
+ public Image getImage(Object element) {
+ if (element instanceof IStorage)
+ return getImageForJarEntry((IStorage)element);
+
+ return super.getImage(element);
+ }
+
+ /* (non-Javadoc)
+ * @see ILabelProvider#getText
+ */
+ public String getText(Object element) {
+ if (element instanceof IStorage)
+ return ((IStorage)element).getName();
+
+ return super.getText(element);
+ }
+
+ /* (non-Javadoc)
+ *
+ * @see IBaseLabelProvider#dispose
+ */
+ public void dispose() {
+ if (fJarImageMap != null) {
+ Iterator each= fJarImageMap.values().iterator();
+ while (each.hasNext()) {
+ Image image= (Image)each.next();
+ image.dispose();
+ }
+ fJarImageMap= null;
+ }
+ fDefaultImage= null;
+ }
+
+ /*
+ * Gets and caches an image for a JarEntryFile.
+ * The image for a JarEntryFile is retrieved from the EditorRegistry.
+ */
+ private Image getImageForJarEntry(IStorage element) {
+ if (fJarImageMap == null)
+ return getDefaultImage();
+
+ if (element == null || element.getName() == null)
+ return getDefaultImage();
+
+ // Try to find icon for full name
+ String name= element.getName();
+ Image image= (Image)fJarImageMap.get(name);
+ if (image != null)
+ return image;
+ IFileEditorMapping[] mappings= getEditorRegistry().getFileEditorMappings();
+ int i= 0;
+ while (i < mappings.length) {
+ if (mappings[i].getLabel().equals(name))
+ break;
+ i++;
+ }
+ String key= name;
+ if (i == mappings.length) {
+ // Try to find icon for extension
+ IPath path= element.getFullPath();
+ if (path == null)
+ return getDefaultImage();
+ key= path.getFileExtension();
+ if (key == null)
+ return getDefaultImage();
+ image= (Image)fJarImageMap.get(key);
+ if (image != null)
+ return image;
+ }
+
+ // Get the image from the editor registry
+ ImageDescriptor desc= getEditorRegistry().getImageDescriptor(name);
+ image= desc.createImage();
+
+ fJarImageMap.put(key, image);
+
+ return image;
+ }
+
+ private Image getDefaultImage() {
+ if (fDefaultImage == null)
+ fDefaultImage= PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE);
+ return fDefaultImage;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/StringMatcher.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/StringMatcher.java
new file mode 100644
index 000000000..c7dc12bc3
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/StringMatcher.java
@@ -0,0 +1,386 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+import java.util.Vector;
+
+/**
+ * A string pattern matcher. Supports '*' and '?' wildcards. Copied from org.eclipse.jdt.ui.util.
+ */
+public class StringMatcher {
+ protected String fPattern;
+ protected int fLength; // pattern length
+ protected boolean fIgnoreWildCards;
+ protected boolean fIgnoreCase;
+ protected boolean fHasLeadingStar;
+ protected boolean fHasTrailingStar;
+ protected String fSegments[]; //the given pattern is split into * separated segments
+
+ /* boundary value beyond which we don't need to search in the text */
+ protected int fBound= 0;
+
+
+ protected static final char fSingleWildCard= '\u0000';
+
+ public static class Position {
+ int start; //inclusive
+ int end; //exclusive
+ public Position(int start, int end) {
+ this.start= start;
+ this.end= end;
+ }
+ public int getStart() {
+ return start;
+ }
+ public int getEnd() {
+ return end;
+ }
+ }
+ /**
+ * StringMatcher constructor takes in a String object that is a simple
+ * pattern. The pattern may contain '*' for 0 and many characters and
+ * '?' for exactly one character.
+ *
+ * Literal '*' and '?' characters must be escaped in the pattern
+ * e.g., "\*" means literal "*", etc.
+ *
+ * Escaping any other character (including the escape character itself),
+ * just results in that character in the pattern.
+ * e.g., "\a" means "a" and "\\" means "\"
+ *
+ * If invoking the StringMatcher with string literals in Java, don't forget
+ * escape characters are represented by "\\".
+ *
+ * @param pattern the pattern to match text against
+ * @param ignoreCase if true, case is ignored
+ * @param ignoreWildCards if true, wild cards and their escape sequences are ignored
+ * (everything is taken literally).
+ */
+ public StringMatcher(String pattern, boolean ignoreCase, boolean ignoreWildCards) {
+ if (pattern == null)
+ throw new IllegalArgumentException();
+ fIgnoreCase= ignoreCase;
+ fIgnoreWildCards= ignoreWildCards;
+ fPattern= pattern;
+ fLength= pattern.length();
+
+ if (fIgnoreWildCards) {
+ parseNoWildCards();
+ } else {
+ parseWildCards();
+ }
+ }
+ /**
+ * Find the first occurrence of the pattern between <code>start</code)(inclusive)
+ * and <code>end</code>(exclusive).
+ * @param text the String object to search in
+ * @param start the starting index of the search range, inclusive
+ * @param end the ending index of the search range, exclusive
+ * @return an <code>StringMatcher.Position</code> object that keeps the starting
+ * (inclusive) and ending positions (exclusive) of the first occurrence of the
+ * pattern in the specified range of the text; return null if not found or subtext
+ * is empty (start==end). A pair of zeros is returned if pattern is empty string
+ * Note that for pattern like "*abc*" with leading and trailing stars, position of "abc"
+ * is returned. For a pattern like"*??*" in text "abcdf", (1,3) is returned
+ */
+ public StringMatcher.Position find(String text, int start, int end) {
+ if (text == null)
+ throw new IllegalArgumentException();
+
+ int tlen= text.length();
+ if (start < 0)
+ start= 0;
+ if (end > tlen)
+ end= tlen;
+ if (end < 0 ||start >= end )
+ return null;
+ if (fLength == 0)
+ return new Position(start, start);
+ if (fIgnoreWildCards) {
+ int x= posIn(text, start, end);
+ if (x < 0)
+ return null;
+ return new Position(x, x+fLength);
+ }
+
+ int segCount= fSegments.length;
+ if (segCount == 0)//pattern contains only '*'(s)
+ return new Position (start, end);
+
+ int curPos= start;
+ int matchStart= -1;
+ int i;
+ for (i= 0; i < segCount && curPos < end; ++i) {
+ String current= fSegments[i];
+ int nextMatch= regExpPosIn(text, curPos, end, current);
+ if (nextMatch < 0 )
+ return null;
+ if(i == 0)
+ matchStart= nextMatch;
+ curPos= nextMatch + current.length();
+ }
+ if (i < segCount)
+ return null;
+ return new Position(matchStart, curPos);
+ }
+ /**
+ * match the given <code>text</code> with the pattern
+ * @return true if matched eitherwise false
+ * @param text a String object
+ */
+ public boolean match(String text) {
+ return match(text, 0, text.length());
+ }
+ /**
+ * Given the starting (inclusive) and the ending (exclusive) positions in the
+ * <code>text</code>, determine if the given substring matches with aPattern
+ * @return true if the specified portion of the text matches the pattern
+ * @param text a String object that contains the substring to match
+ * @param start marks the starting position (inclusive) of the substring
+ * @param end marks the ending index (exclusive) of the substring
+ */
+ public boolean match(String text, int start, int end) {
+ if (null == text)
+ throw new IllegalArgumentException();
+
+ if (start > end)
+ return false;
+
+ if (fIgnoreWildCards)
+ return (end - start == fLength) && fPattern.regionMatches(fIgnoreCase, 0, text, start, fLength);
+ int segCount= fSegments.length;
+ if (segCount == 0 && (fHasLeadingStar || fHasTrailingStar)) // pattern contains only '*'(s)
+ return true;
+ if (start == end)
+ return fLength == 0;
+ if (fLength == 0)
+ return start == end;
+
+ int tlen= text.length();
+ if (start < 0)
+ start= 0;
+ if (end > tlen)
+ end= tlen;
+
+ int tCurPos= start;
+ int bound= end - fBound;
+ if ( bound < 0)
+ return false;
+ int i=0;
+ String current= fSegments[i];
+ int segLength= current.length();
+
+ /* process first segment */
+ if (!fHasLeadingStar){
+ if(!regExpRegionMatches(text, start, current, 0, segLength)) {
+ return false;
+ } else {
+ ++i;
+ tCurPos= tCurPos + segLength;
+ }
+ }
+ if ((fSegments.length == 1) && (!fHasLeadingStar) && (!fHasTrailingStar)) {
+ // only one segment to match, no wildcards specified
+ return tCurPos == end;
+ }
+ /* process middle segments */
+ while (i < segCount) {
+ current= fSegments[i];
+ int currentMatch;
+ int k= current.indexOf(fSingleWildCard);
+ if (k < 0) {
+ currentMatch= textPosIn(text, tCurPos, end, current);
+ if (currentMatch < 0)
+ return false;
+ } else {
+ currentMatch= regExpPosIn(text, tCurPos, end, current);
+ if (currentMatch < 0)
+ return false;
+ }
+ tCurPos= currentMatch + current.length();
+ i++;
+ }
+
+ /* process final segment */
+ if (!fHasTrailingStar && tCurPos != end) {
+ int clen= current.length();
+ return regExpRegionMatches(text, end - clen, current, 0, clen);
+ }
+ return i == segCount ;
+ }
+
+ /**
+ * This method parses the given pattern into segments seperated by wildcard '*' characters.
+ * Since wildcards are not being used in this case, the pattern consists of a single segment.
+ */
+ private void parseNoWildCards() {
+ fSegments= new String[1];
+ fSegments[0]= fPattern;
+ fBound= fLength;
+ }
+ /**
+ * Parses the given pattern into segments seperated by wildcard '*' characters.
+ */
+ private void parseWildCards() {
+ if(fPattern.startsWith("*"))//$NON-NLS-1$
+ fHasLeadingStar= true;
+ if(fPattern.endsWith("*")) {//$NON-NLS-1$
+ /* make sure it's not an escaped wildcard */
+ if (fLength > 1 && fPattern.charAt(fLength - 2) != '\\') {
+ fHasTrailingStar= true;
+ }
+ }
+
+ Vector temp= new Vector();
+
+ int pos= 0;
+ StringBuffer buf= new StringBuffer();
+ while (pos < fLength) {
+ char c= fPattern.charAt(pos++);
+ switch (c) {
+ case '\\':
+ if (pos >= fLength) {
+ buf.append(c);
+ } else {
+ char next= fPattern.charAt(pos++);
+ /* if it's an escape sequence */
+ if (next == '*' || next == '?' || next == '\\') {
+ buf.append(next);
+ } else {
+ /* not an escape sequence, just insert literally */
+ buf.append(c);
+ buf.append(next);
+ }
+ }
+ break;
+ case '*':
+ if (buf.length() > 0) {
+ /* new segment */
+ temp.addElement(buf.toString());
+ fBound += buf.length();
+ buf.setLength(0);
+ }
+ break;
+ case '?':
+ /* append special character representing single match wildcard */
+ buf.append(fSingleWildCard);
+ break;
+ default:
+ buf.append(c);
+ }
+ }
+
+ /* add last buffer to segment list */
+ if (buf.length() > 0) {
+ temp.addElement(buf.toString());
+ fBound += buf.length();
+ }
+
+ fSegments= new String[temp.size()];
+ temp.copyInto(fSegments);
+ }
+ /**
+ * @param text a string which contains no wildcard
+ * @param start the starting index in the text for search, inclusive
+ * @param end the stopping point of search, exclusive
+ * @return the starting index in the text of the pattern , or -1 if not found
+ */
+ protected int posIn(String text, int start, int end) {//no wild card in pattern
+ int max= end - fLength;
+
+ if (!fIgnoreCase) {
+ int i= text.indexOf(fPattern, start);
+ if (i == -1 || i > max)
+ return -1;
+ return i;
+ }
+
+ for (int i= start; i <= max; ++i) {
+ if (text.regionMatches(true, i, fPattern, 0, fLength))
+ return i;
+ }
+
+ return -1;
+ }
+ /**
+ * @param text a simple regular expression that may only contain '?'(s)
+ * @param start the starting index in the text for search, inclusive
+ * @param end the stopping point of search, exclusive
+ * @param p a simple regular expression that may contains '?'
+ * @return the starting index in the text of the pattern , or -1 if not found
+ */
+ protected int regExpPosIn(String text, int start, int end, String p) {
+ int plen= p.length();
+
+ int max= end - plen;
+ for (int i= start; i <= max; ++i) {
+ if (regExpRegionMatches(text, i, p, 0, plen))
+ return i;
+ }
+ return -1;
+ }
+
+
+ protected boolean regExpRegionMatches(String text, int tStart, String p, int pStart, int plen) {
+ while (plen-- > 0) {
+ char tchar= text.charAt(tStart++);
+ char pchar= p.charAt(pStart++);
+
+ /* process wild cards */
+ if (!fIgnoreWildCards) {
+ /* skip single wild cards */
+ if (pchar == fSingleWildCard) {
+ continue;
+ }
+ }
+ if (pchar == tchar)
+ continue;
+ if (fIgnoreCase) {
+ if (Character.toUpperCase(tchar) == Character.toUpperCase(pchar))
+ continue;
+ // comparing after converting to upper case doesn't handle all cases;
+ // also compare after converting to lower case
+ if (Character.toLowerCase(tchar) == Character.toLowerCase(pchar))
+ continue;
+ }
+ return false;
+ }
+ return true;
+ }
+ /**
+ * @param text the string to match
+ * @param start the starting index in the text for search, inclusive
+ * @param end the stopping point of search, exclusive
+ * @param p a string that has no wildcard
+ * @return the starting index in the text of the pattern , or -1 if not found
+ */
+ protected int textPosIn(String text, int start, int end, String p) {
+
+ int plen= p.length();
+ int max= end - plen;
+
+ if (!fIgnoreCase) {
+ int i= text.indexOf(p, start);
+ if (i == -1 || i > max)
+ return -1;
+ return i;
+ }
+
+ for (int i= start; i <= max; ++i) {
+ if (text.regionMatches(true, i, p, 0, plen))
+ return i;
+ }
+
+ return -1;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/StructuredSourceViewer.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/StructuredSourceViewer.java
new file mode 100644
index 000000000..7a8f5d770
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/StructuredSourceViewer.java
@@ -0,0 +1,337 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+import java.util.List;
+
+import org.eclipse.imp.editor.UniversalEditor.StructuredSourceViewerConfiguration;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.services.IAutoEditStrategy;
+import org.eclipse.imp.services.ILanguageSyntaxProperties;
+import org.eclipse.imp.services.base.DefaultAutoIndentStrategy;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.DocumentRewriteSession;
+import org.eclipse.jface.text.DocumentRewriteSessionType;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension4;
+import org.eclipse.jface.text.formatter.IContentFormatter;
+import org.eclipse.jface.text.information.IInformationPresenter;
+import org.eclipse.jface.text.source.IOverviewRuler;
+import org.eclipse.jface.text.source.IVerticalRuler;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Composite;
+
+public class StructuredSourceViewer extends ProjectionViewer {
+ /**
+ * Text operation code for requesting the outline for the current input.
+ */
+ public static final int SHOW_OUTLINE= 51;
+
+ /**
+ * Text operation code for requesting the outline for the element at the current position.
+ */
+ public static final int OPEN_STRUCTURE= 52;
+
+ /**
+ * Text operation code for requesting the hierarchy for the current input.
+ */
+ public static final int SHOW_HIERARCHY= 53;
+
+ /**
+ * Text operation code for toggling the commenting of a selected range of text, or the current line.
+ */
+ public static final int TOGGLE_COMMENT= 54;
+
+ /**
+ * Text operation code for toggling the display of "occurrences" of the
+ * current selection, whatever that means to the current language.
+ */
+ public static final int MARK_OCCURRENCES= 55;
+
+ // mmk 4/8/08
+ /**
+ * Text operation code for indenting the currently selected text.
+ */
+ public static final int INDENT_SELECTION= 60;
+
+ private IInformationPresenter fOutlinePresenter;
+
+ private IInformationPresenter fStructurePresenter;
+
+ private IInformationPresenter fHierarchyPresenter;
+
+ private IAutoEditStrategy fAutoEditStrategy;
+
+ // SMS 29 May 2007
+ private IParseController fParseController;
+
+ /**
+ * Is this source viewer configured?
+ *
+ * @since 3.0
+ */
+ private boolean fIsConfigured;
+
+ public StructuredSourceViewer(Composite parent, IVerticalRuler verticalRuler, IOverviewRuler overviewRuler, boolean showAnnotationsOverview, int styles) {
+ super(parent, verticalRuler, overviewRuler, showAnnotationsOverview, styles);
+ }
+
+ /*
+ * @see ITextOperationTarget#canDoOperation(int)
+ */
+ public boolean canDoOperation(int operation) {
+ switch(operation) {
+ case SHOW_OUTLINE:
+ return fOutlinePresenter != null;
+ case OPEN_STRUCTURE:
+ return fStructurePresenter != null;
+ case SHOW_HIERARCHY:
+ return fHierarchyPresenter != null;
+ case TOGGLE_COMMENT:
+ return true;
+ case INDENT_SELECTION:
+ return fAutoEditStrategy != null;
+ }
+ return super.canDoOperation(operation);
+ }
+
+ /*
+ * @see ITextOperationTarget#doOperation(int)
+ */
+ public void doOperation(int operation) {
+ if (getTextWidget() == null)
+ return;
+ switch (operation) {
+ case SHOW_OUTLINE:
+ if (fOutlinePresenter != null)
+ fOutlinePresenter.showInformation();
+ return;
+ case OPEN_STRUCTURE:
+ if (fStructurePresenter != null)
+ fStructurePresenter.showInformation();
+ return;
+ case SHOW_HIERARCHY:
+ if (fHierarchyPresenter != null)
+ fHierarchyPresenter.showInformation();
+ return;
+ case TOGGLE_COMMENT:
+ doToggleComment();
+ return;
+ // mmk 4/8/08
+ case INDENT_SELECTION:
+ doIndentLines();
+ return;
+ }
+ super.doOperation(operation);
+ }
+
+ // SMS 29 May 2007 (see doToggleComment())
+ public void setParseController(IParseController parseController) {
+ fParseController = parseController;
+ }
+
+ public void setFormatter(IContentFormatter formatter) {
+ fContentFormatter= formatter;
+ }
+
+ private void doToggleComment() {
+ ILanguageSyntaxProperties syntaxProps= fParseController.getSyntaxProperties();
+
+ if (syntaxProps == null)
+ return;
+
+ IDocument doc= this.getDocument();
+ DocumentRewriteSession rewriteSession= null;
+ Point p= this.getSelectedRange();
+ final String lineCommentStart= syntaxProps.getSingleLineCommentPrefix();
+
+ if (doc instanceof IDocumentExtension4) {
+ IDocumentExtension4 extension= (IDocumentExtension4) doc;
+ rewriteSession= extension.startRewriteSession(DocumentRewriteSessionType.SEQUENTIAL);
+ }
+
+ try {
+ final int selStart= p.x;
+ final int selLen= p.y;
+ final int selEnd= selStart + selLen;
+ final int startLine= doc.getLineOfOffset(selStart);
+ int endLine= doc.getLineOfOffset(selEnd);
+
+ if (selLen > 0 && doc.getChar(selEnd - 1) == '\n')
+ endLine--;
+ for(int line= startLine; line <= endLine; line++) {
+ int lineStartOffset= doc.getLineOffset(line);
+ int offset= lineStartOffset;
+
+ while (Character.isWhitespace(doc.getChar(offset)) && offset < doc.getLength())
+ offset++;
+ if (doc.get(offset, lineCommentStart.length()).equals(lineCommentStart)) {
+ int len= lineCommentStart.length();
+
+ while (Character.isWhitespace(doc.getChar(offset + len)))
+ len++;
+ doc.replace(offset, len, "");
+ } else
+ doc.replace(offset, 0, lineCommentStart + " ");
+ }
+ } catch (BadLocationException e) {
+ e.printStackTrace();
+ } finally {
+ if (doc instanceof IDocumentExtension4) {
+ IDocumentExtension4 extension= (IDocumentExtension4) doc;
+ extension.stopRewriteSession(rewriteSession);
+ }
+ restoreSelection();
+ }
+ }
+
+ // mmk 4/8/08
+ private void doIndentLines() {
+ IDocument doc= this.getDocument();
+ DocumentRewriteSession rewriteSession= null;
+ Point p= this.getSelectedRange();
+
+ if (doc instanceof IDocumentExtension4) {
+ IDocumentExtension4 extension= (IDocumentExtension4) doc;
+ rewriteSession= extension.startRewriteSession(DocumentRewriteSessionType.SEQUENTIAL);
+ }
+
+ try {
+ final int selStart= p.x;
+ final int selLen= p.y;
+ final int selEnd= selStart + selLen;
+ final int startLine= doc.getLineOfOffset(selStart);
+ int endLine= doc.getLineOfOffset(selEnd);
+
+ if (selLen > 0 && doc.getChar(selEnd - 1) == '\n')
+ endLine--;
+ for(int line= startLine; line <= endLine; line++) {
+ int lineStartOffset= doc.getLineOffset(line);
+ int offset= lineStartOffset;
+
+ // Replace the indent with desired indent
+ // make use of the language-specific AutoEditStrategy
+ // This strategy assumes keystroke input, so infrastructure requires a key event/DocumentCommand to work.
+ DocumentCommand cmd= new DocumentCommand() { };
+ cmd.offset= lineStartOffset;
+ cmd.length= 1;
+ cmd.text= Character.toString('\t');
+ cmd.doit= true;
+ cmd.shiftsCaret= false;
+ fAutoEditStrategy.customizeDocumentCommand(doc, cmd);
+ doc.replace(cmd.offset, cmd.length, cmd.text);
+ }
+ } catch (BadLocationException e) {
+ e.printStackTrace();
+ } finally {
+ if (doc instanceof IDocumentExtension4) {
+ IDocumentExtension4 extension= (IDocumentExtension4) doc;
+ extension.stopRewriteSession(rewriteSession);
+ }
+ restoreSelection();
+ }
+ }
+
+ /*
+ * @see ISourceViewer#configure(SourceViewerConfiguration)
+ */
+ public void configure(SourceViewerConfiguration configuration) {
+ /*
+ * Prevent access to colors disposed in unconfigure(), see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=53641
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=86177
+ */
+ StyledText textWidget= getTextWidget();
+ if (textWidget != null && !textWidget.isDisposed()) {
+ Color foregroundColor= textWidget.getForeground();
+ if (foregroundColor != null && foregroundColor.isDisposed())
+ textWidget.setForeground(null);
+ Color backgroundColor= textWidget.getBackground();
+ if (backgroundColor != null && backgroundColor.isDisposed())
+ textWidget.setBackground(null);
+ }
+ super.configure(configuration);
+ if (configuration instanceof StructuredSourceViewerConfiguration) {
+ StructuredSourceViewerConfiguration sSVConfiguration= (StructuredSourceViewerConfiguration) configuration;
+
+ fOutlinePresenter= sSVConfiguration.getOutlinePresenter(this);
+ if (fOutlinePresenter != null)
+ fOutlinePresenter.install(this);
+
+ fStructurePresenter= sSVConfiguration.getOutlinePresenter(this);
+ if (fStructurePresenter != null)
+ fStructurePresenter.install(this);
+
+ fHierarchyPresenter= sSVConfiguration.getHierarchyPresenter(this, true);
+ if (fHierarchyPresenter != null)
+ fHierarchyPresenter.install(this);
+
+ if (fAutoIndentStrategies != null) {
+ List<org.eclipse.jface.text.IAutoEditStrategy> strategies= (List<org.eclipse.jface.text.IAutoEditStrategy>) fAutoIndentStrategies.get(IDocument.DEFAULT_CONTENT_TYPE);
+ // TODO If there are multiple IAudoEditStrategy's, we may pick up one that doesn't do indent. How to identify the right one?
+ // SMS 5 Aug 2008: There's another problem here, in that the available strategy here
+ // may not be of type IAutoEditStrategy. See bug #243212. To provide at least a
+ // short term fix, I'm going to substitute an appropriate value when that turns out
+ // to be the case. This may be revised if we decide to somehow avoid the possibility
+ // that a strategy of an inappropriate type might appear here.
+ if (strategies != null && strategies.size() > 0) {
+// fAutoEditStrategy= (IAutoEditStrategy) strategies.get(0);
+ if (strategies.get(0) instanceof IAutoEditStrategy)
+ fAutoEditStrategy= (IAutoEditStrategy) strategies.get(0);
+ else
+ fAutoEditStrategy = new DefaultAutoIndentStrategy();
+ }
+ }
+ }
+ // if (fPreferenceStore != null) {
+ // fPreferenceStore.addPropertyChangeListener(this);
+ // initializeViewerColors();
+ // }
+ fIsConfigured= true;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.ISourceViewerExtension2#unconfigure()
+ * @since 3.0
+ */
+ public void unconfigure() {
+ if (fOutlinePresenter != null) {
+ fOutlinePresenter.uninstall();
+ fOutlinePresenter= null;
+ }
+ if (fStructurePresenter != null) {
+ fStructurePresenter.uninstall();
+ fStructurePresenter= null;
+ }
+ if (fHierarchyPresenter != null) {
+ fHierarchyPresenter.uninstall();
+ fHierarchyPresenter= null;
+ }
+ // if (fForegroundColor != null) {
+ // fForegroundColor.dispose();
+ // fForegroundColor= null;
+ // }
+ // if (fBackgroundColor != null) {
+ // fBackgroundColor.dispose();
+ // fBackgroundColor= null;
+ // }
+ // if (fPreferenceStore != null)
+ // fPreferenceStore.removePropertyChangeListener(this);
+ super.unconfigure();
+ fIsConfigured= false;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/TargetLink.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/TargetLink.java
new file mode 100644
index 000000000..d1425322f
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/TargetLink.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+ *******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.part.FileEditorInput;
+
+/**
+ * Common class to represent a hyperlink to a given target location.
+ *
+ * @author rfuhrer
+ */
+public final class TargetLink implements IHyperlink {
+ private final String fText;
+
+ private final Object fTarget;
+
+ private final int fStart;
+
+ private final int fLength;
+
+ private final int fTargetStart;
+
+ private final int fTargetLength;
+
+ private IRegionSelectionService fSelectionService;
+
+ /**
+ * @param text
+ * @param srcStart
+ * @param srcLength
+ * @param target a workspace-relative or filesystem-absolute IPath to the file,
+ * if 'editor' is null; otherwise, an object that indicates the particular target within the source file
+ * @param targetStart
+ * @param targetLength
+ * @param editor may be null, if the target is in another compilation unit
+ */
+ public TargetLink(String text, int srcStart, int srcLength, Object target, int targetStart, int targetLength, IRegionSelectionService selService) {
+ fText= text;
+ fStart= srcStart;
+ fTarget= target;
+ fLength= srcLength;
+ fTargetStart= targetStart;
+ fTargetLength= targetLength;
+ fSelectionService= selService;
+ }
+
+ public IRegion getHyperlinkRegion() {
+ return new Region(fStart, fLength);
+ }
+
+ public String getTypeLabel() {
+ return fTarget.getClass().getName();
+ }
+
+ public String getHyperlinkText() {
+ return new String(fText);
+ }
+
+ public void open() {
+ if (fSelectionService == null) {
+ // Either we're opening up a new editor, or there's an existing one open on the target file.
+ // Either way, get a handle to an IEditorPart for the target file, and try to get an
+ // IRegionSelectionService interface on it.
+ final IPath targetPath= (IPath) fTarget;
+ IEditorDescriptor ed= PlatformUI.getWorkbench().getEditorRegistry().getDefaultEditor(targetPath.lastSegment());
+ IWorkbenchWindow activeWindow= PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ IWorkbenchPage activePage= activeWindow.getActivePage();
+
+ if (ed == null) {
+ MessageDialog.openError(activeWindow.getShell(), "Error", "No editor defined for target file "
+ + targetPath.toPortableString());
+ return;
+ }
+
+ IWorkspaceRoot wsRoot= ResourcesPlugin.getWorkspace().getRoot();
+ IPath wsLoc= wsRoot.getLocation();
+ IEditorPart editor;
+
+ // Abortive attempt to support links to class files embedded in jars (e.g., Java rt.jar).
+ // if (targetPath.toPortableString().endsWith(".class")) {
+ // IFile jarFile= null; // Can't get an IFile for something not in the workspace... and rt.jar usually isn't...
+ // // Anyway, we'll have to use something other than a plain IFileEditorInput.
+ // // JDT has IClassFileEditorInput, but it's internal... Hmmm...
+ // JavaCore.createClassFileFrom(jarFile);
+ // } else
+
+ try {
+ boolean targetPathHasWSPrefix= wsLoc.isPrefixOf(targetPath);
+
+ if (targetPathHasWSPrefix || wsRoot.getFile(targetPath).exists()) {
+ IFile file= wsRoot.getFile(targetPathHasWSPrefix ? targetPath.removeFirstSegments(wsLoc.segmentCount()) : targetPath);
+ IEditorInput editorInput= new FileEditorInput(file);
+
+ editor= activePage.openEditor(editorInput, ed.getId());
+ } else {
+// if (targetPath.isAbsolute() && !wsLoc.isPrefixOf(targetPath)) {
+ // http://wiki.eclipse.org/index.php/FAQ_How_do_I_open_an_editor_on_a_file_outside_the_workspace%3F
+ IFileStore fileStore = EFS.getLocalFileSystem().getStore(targetPath);
+
+ editor= IDE.openEditorOnFileStore(activePage, fileStore);
+ }
+ } catch (PartInitException e) {
+ RuntimePlugin.getInstance().logException(e.getLocalizedMessage(), e);
+ return;
+ }
+ // Don't assume the target editor is a text editor; the target might be
+ // in a class file or another kind of binary file.
+ if (editor instanceof IRegionSelectionService)
+ fSelectionService= (IRegionSelectionService) editor;
+ else
+ fSelectionService= (IRegionSelectionService) editor.getAdapter(IRegionSelectionService.class);
+ }
+ if (fSelectionService != null)
+ fSelectionService.selectAndReveal(fTargetStart, fTargetLength);
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/UniversalEditor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/UniversalEditor.java
new file mode 100644
index 000000000..695b4e5f2
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/UniversalEditor.java
@@ -0,0 +1,1850 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.editor;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget;
+import org.eclipse.debug.ui.actions.ToggleBreakpointAction;
+import org.eclipse.help.IContextProvider;
+import org.eclipse.imp.actions.OpenAction;
+import org.eclipse.imp.actions.RulerEnableDisableBreakpointAction;
+import org.eclipse.imp.core.ErrorHandler;
+import org.eclipse.imp.editor.internal.AnnotationCreator;
+import org.eclipse.imp.editor.internal.EditorErrorTickUpdater;
+import org.eclipse.imp.editor.internal.FoldingController;
+import org.eclipse.imp.editor.internal.ProblemMarkerManager;
+import org.eclipse.imp.editor.internal.ToggleBreakpointsAdapter;
+import org.eclipse.imp.help.IMPHelp;
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.language.LanguageRegistry;
+import org.eclipse.imp.language.ServiceFactory;
+import org.eclipse.imp.model.ISourceProject;
+import org.eclipse.imp.model.ModelFactory;
+import org.eclipse.imp.model.ModelFactory.ModelException;
+import org.eclipse.imp.parser.IMessageHandler;
+import org.eclipse.imp.parser.IModelListener;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.parser.ISourcePositionLocator;
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferenceCache;
+import org.eclipse.imp.preferences.PreferenceConstants;
+import org.eclipse.imp.preferences.PreferencesService;
+import org.eclipse.imp.preferences.IPreferencesService.IntegerPreferenceListener;
+import org.eclipse.imp.preferences.IPreferencesService.PreferenceServiceListener;
+import org.eclipse.imp.preferences.IPreferencesService.StringPreferenceListener;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.imp.services.IASTFindReplaceTarget;
+import org.eclipse.imp.services.IAnnotationTypeInfo;
+import org.eclipse.imp.services.IDocumentationProvider;
+import org.eclipse.imp.services.IEditorService;
+import org.eclipse.imp.services.ILanguageActionsContributor;
+import org.eclipse.imp.services.ILanguageSyntaxProperties;
+import org.eclipse.imp.services.IOccurrenceMarker;
+import org.eclipse.imp.services.IRefactoringContributor;
+import org.eclipse.imp.services.IToggleBreakpointsHandler;
+import org.eclipse.imp.services.ITokenColorer;
+import org.eclipse.imp.services.base.DefaultAnnotationHover;
+import org.eclipse.imp.services.base.TreeModelBuilderBase;
+import org.eclipse.imp.ui.DefaultPartListener;
+import org.eclipse.imp.ui.textPresentation.HTMLTextPresenter;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.resource.FontRegistry;
+import org.eclipse.jface.text.AbstractInformationControlManager;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IAutoEditStrategy;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerExtension;
+import org.eclipse.jface.text.ITextViewerExtension5;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.IUndoManager;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.contentassist.ContentAssistant;
+import org.eclipse.jface.text.contentassist.IContentAssistant;
+import org.eclipse.jface.text.formatter.ContentFormatter;
+import org.eclipse.jface.text.formatter.IContentFormatter;
+import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
+import org.eclipse.jface.text.hyperlink.IHyperlinkPresenter;
+import org.eclipse.jface.text.information.IInformationPresenter;
+import org.eclipse.jface.text.information.IInformationProvider;
+import org.eclipse.jface.text.information.IInformationProviderExtension;
+import org.eclipse.jface.text.information.InformationPresenter;
+import org.eclipse.jface.text.presentation.IPresentationDamager;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.IPresentationRepairer;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.DefaultCharacterPairMatcher;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.IAnnotationModelListener;
+import org.eclipse.jface.text.source.ICharacterPairMatcher;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.IVerticalRuler;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
+import org.eclipse.jface.text.source.projection.ProjectionSupport;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.custom.VerifyKeyListener;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.SubActionBars;
+import org.eclipse.ui.editors.text.TextEditor;
+import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
+import org.eclipse.ui.texteditor.AbstractTextEditor;
+import org.eclipse.ui.texteditor.ContentAssistAction;
+import org.eclipse.ui.texteditor.IEditorStatusLine;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
+import org.eclipse.ui.texteditor.TextOperationAction;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+
+/**
+ * An Eclipse editor, which is not enhanced using API; rather, we publish extension
+ * points for outline, content assist, hover help, etc.
+ *
+ * @author Chris Laffra
+ * @author Robert M. Fuhrer
+ */
+public class UniversalEditor extends TextEditor implements IASTFindReplaceTarget {
+ public static final String FORMAT_SOURCE_COMMAND= RuntimePlugin.IMP_RUNTIME + ".editor.formatSource";
+
+ public static final String TOGGLE_COMMENT_COMMAND= RuntimePlugin.IMP_RUNTIME + ".editor.toggleComment";
+
+ public static final String SHOW_OUTLINE_COMMAND= RuntimePlugin.IMP_RUNTIME + ".editor.showOutline";
+
+ public static final String INDENT_SELECTION_COMMAND= RuntimePlugin.IMP_RUNTIME + ".editor.indentSelection";
+
+ /**
+ * Action definition ID of the edit -> go to matching fence action
+ * (value <code>"org.eclipse.imp.runtime.gotoMatchingFence"</code>).
+ */
+ public static final String GOTO_MATCHING_FENCE_COMMAND= RuntimePlugin.IMP_RUNTIME + ".editor.gotoMatchingFence"; //$NON-NLS-1$
+
+ public static final String MESSAGE_BUNDLE= "org.eclipse.imp.editor.messages";
+
+ public static final String EDITOR_ID= RuntimePlugin.IMP_RUNTIME + ".impEditor";
+
+ public static final String PARSE_ANNOTATION_TYPE= "org.eclipse.imp.editor.parseAnnotation";
+
+ /** Preference key for matching brackets */
+ protected final static String MATCHING_BRACKETS= PreferenceConstants.EDITOR_MATCHING_BRACKETS;
+
+ /** Preference key for matching brackets color */
+ protected final static String MATCHING_BRACKETS_COLOR= PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR;
+
+ public Language fLanguage;
+
+ public ParserScheduler fParserScheduler;
+
+ protected LanguageServiceManager fLanguageServiceManager;
+
+ protected ServiceControllerManager fServiceControllerManager;
+
+ private ProjectionAnnotationModel fAnnotationModel;
+
+ private ProblemMarkerManager fProblemMarkerManager;
+
+ private ICharacterPairMatcher fBracketMatcher;
+
+ private SubActionBars fActionBars;
+
+ private DefaultPartListener fRefreshContributions;
+
+ private IPreferencesService fLangSpecificPrefs;
+
+ private PreferenceServiceListener fFontListener;
+
+ private PreferenceServiceListener fTabListener;
+
+ private IAction fToggleBreakpointAction;
+
+ private IAction fEnableDisableBreakpointAction;
+
+ private ToggleBreakpointsAdapter fBreakpointHandler;
+
+ private static final String BUNDLE_FOR_CONSTRUCTED_KEYS= MESSAGE_BUNDLE;//$NON-NLS-1$
+
+ private static final String IMP_EDITOR_CONTEXT= RuntimePlugin.IMP_RUNTIME + ".imp_editor_context";
+
+ static ResourceBundle fgBundleForConstructedKeys= ResourceBundle.getBundle(BUNDLE_FOR_CONSTRUCTED_KEYS);
+
+ public UniversalEditor() {
+// RuntimePlugin.EDITOR_START_TIME= System.currentTimeMillis();
+ if (PreferenceCache.emitMessages)
+ RuntimePlugin.getInstance().writeInfoMsg("Creating UniversalEditor instance");
+ // SMS 4 Apr 2007
+ // Do not set preference store with store obtained from plugin; one is
+ // already defined for the parent text editor and populated with relevant
+ // preferences
+ // setPreferenceStore(RuntimePlugin.getInstance().getPreferenceStore());
+ setSourceViewerConfiguration(new StructuredSourceViewerConfiguration());
+ configureInsertMode(SMART_INSERT, true);
+ setInsertMode(SMART_INSERT);
+ fProblemMarkerManager= new ProblemMarkerManager();
+ }
+
+ public Object getAdapter(Class required) {
+ if (IContentOutlinePage.class.equals(required)) {
+ return fServiceControllerManager == null ? null : fServiceControllerManager.getOutlineController();
+ }
+ if (IToggleBreakpointsTarget.class.equals(required)) {
+ IToggleBreakpointsHandler bkptHandler = fLanguageServiceManager == null ? null : fLanguageServiceManager.getToggleBreakpointsHandler();
+ if (bkptHandler != null) {
+ if (fBreakpointHandler == null) {
+ fBreakpointHandler= new ToggleBreakpointsAdapter(this, bkptHandler);
+ }
+ return fBreakpointHandler;
+ }
+ }
+ if (IRegionSelectionService.class.equals(required)) {
+ return fRegionSelector;
+ }
+ if (IContextProvider.class.equals(required)) {
+ return IMPHelp.getHelpContextProvider(this, fLanguageServiceManager, IMP_EDITOR_CONTEXT);
+ }
+ return super.getAdapter(required);
+ }
+
+ protected void createActions() {
+ super.createActions();
+
+ final ResourceBundle bundle= ResourceBundle.getBundle(MESSAGE_BUNDLE);
+ Action action= new ContentAssistAction(bundle, "ContentAssistProposal.", this);
+ action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+ setAction("ContentAssistProposal", action);
+ markAsStateDependentAction("ContentAssistProposal", true);
+
+ // Not sure how to hook this up - the following class has all the right enablement logic,
+ // but it doesn't implement IAction... How to register it as an action here???
+// fToggleBreakpointAction= new AbstractRulerActionDelegate() {
+// protected IAction createAction(ITextEditor editor, IVerticalRulerInfo rulerInfo) {
+// return new ToggleBreakpointAction(UniversalEditor.this, getDocumentProvider().getDocument(getEditorInput()), getVerticalRuler());
+// }
+// }
+ fToggleBreakpointAction= new ToggleBreakpointAction(this, getDocumentProvider().getDocument(getEditorInput()), getVerticalRuler());
+ setAction("ToggleBreakpoint", action);
+ fEnableDisableBreakpointAction= new RulerEnableDisableBreakpointAction(this, getVerticalRuler());
+ setAction("ToggleBreakpoint", action);
+
+ action= new TextOperationAction(bundle, "Format.", this, ISourceViewer.FORMAT); //$NON-NLS-1$
+ action.setActionDefinitionId(FORMAT_SOURCE_COMMAND);
+ setAction("Format", action); //$NON-NLS-1$
+ markAsStateDependentAction("Format", true); //$NON-NLS-1$
+ markAsSelectionDependentAction("Format", true); //$NON-NLS-1$
+// PlatformUI.getWorkbench().getHelpSystem().setHelp(action, IJavaHelpContextIds.FORMAT_ACTION);
+
+ action= new TextOperationAction(bundle, "ShowOutline.", this, StructuredSourceViewer.SHOW_OUTLINE); //$NON-NLS-1$
+ action.setActionDefinitionId(SHOW_OUTLINE_COMMAND);
+ setAction(SHOW_OUTLINE_COMMAND, action); //$NON-NLS-1$
+// PlatformUI.getWorkbench().getHelpSystem().setHelp(action, IJavaHelpContextIds.SHOW_OUTLINE_ACTION);
+
+ action= new TextOperationAction(bundle, "ToggleComment.", this, StructuredSourceViewer.TOGGLE_COMMENT); //$NON-NLS-1$
+ action.setActionDefinitionId(TOGGLE_COMMENT_COMMAND);
+ setAction(TOGGLE_COMMENT_COMMAND, action); //$NON-NLS-1$
+// PlatformUI.getWorkbench().getHelpSystem().setHelp(action, IJavaHelpContextIds.TOGGLE_COMMENT_ACTION);
+
+ action= new TextOperationAction(bundle, "IndentSelection.", this, StructuredSourceViewer.INDENT_SELECTION); //$NON-NLS-1$
+ action.setActionDefinitionId(INDENT_SELECTION_COMMAND);
+ setAction(INDENT_SELECTION_COMMAND, action); //$NON-NLS-1$
+
+ action= new GotoMatchingFenceAction(this);
+ action.setActionDefinitionId(GOTO_MATCHING_FENCE_COMMAND);
+ setAction(GOTO_MATCHING_FENCE_COMMAND, action);
+
+ FoldingActionGroup foldingGroup= new FoldingActionGroup(this, this.getSourceViewer());
+ }
+
+ protected void editorContextMenuAboutToShow(IMenuManager menu) {
+ menu.add(new OpenAction(this));
+ super.editorContextMenuAboutToShow(menu);
+
+ contributeRefactoringActions(menu);
+ contributeLanguageActions(menu);
+ }
+
+ private void contributeRefactoringActions(IMenuManager menu) {
+ Set<IRefactoringContributor> contributors= fLanguageServiceManager.getRefactoringContributors();
+
+ if (contributors != null && !contributors.isEmpty()) {
+ List<IAction> editorActions= new ArrayList<IAction>();
+
+ for (Iterator<IRefactoringContributor> iter= contributors.iterator(); iter.hasNext(); ) {
+ IRefactoringContributor con= iter.next();
+
+ try {
+ IAction[] conActions= con.getEditorRefactoringActions(this);
+
+ for (int i= 0; i < conActions.length; i++)
+ editorActions.add(conActions[i]);
+ } catch (Exception e) {
+ RuntimePlugin.getInstance().logException("Unable to create refactoring actions for contributor " + con, e);
+ }
+ }
+ Separator refGroup= new Separator("group.refactor");
+ IMenuManager refMenu= new MenuManager("Refac&tor", "org.eclipse.imp.refactor");
+
+ menu.add(refGroup);
+ menu.appendToGroup("group.refactor", refMenu);
+
+ for (Iterator<IAction> actionIter= editorActions.iterator(); actionIter.hasNext(); ) {
+ refMenu.add(actionIter.next());
+ }
+ }
+ }
+
+ private void contributeLanguageActions(IMenuManager menu) {
+ Set<ILanguageActionsContributor> actionContributors= fLanguageServiceManager.getActionContributors();
+
+ if (!actionContributors.isEmpty()) {
+ menu.add(new Separator());
+ }
+
+ for(ILanguageActionsContributor con : actionContributors) {
+ try {
+ con.contributeToEditorMenu(this, menu);
+ } catch(Exception e) {
+ RuntimePlugin.getInstance().logException("Unable to create editor actions for contributor " + con, e);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#isOverviewRulerVisible()
+ */
+ protected boolean isOverviewRulerVisible() {
+ return true;
+ }
+
+ protected void rulerContextMenuAboutToShow(IMenuManager menu) {
+ addDebugActions(menu);
+
+ super.rulerContextMenuAboutToShow(menu);
+
+ IMenuManager foldingMenu= new MenuManager("Folding", "projection"); //$NON-NLS-1$
+
+ menu.appendToGroup(ITextEditorActionConstants.GROUP_RULERS, foldingMenu);
+
+ IAction action;
+// action= getAction("FoldingToggle"); //$NON-NLS-1$
+// foldingMenu.add(action);
+ action= getAction("FoldingExpandAll"); //$NON-NLS-1$
+ foldingMenu.add(action);
+ action= getAction("FoldingCollapseAll"); //$NON-NLS-1$
+ foldingMenu.add(action);
+ action= getAction("FoldingRestore"); //$NON-NLS-1$
+ foldingMenu.add(action);
+ action= getAction("FoldingCollapseMembers"); //$NON-NLS-1$
+ foldingMenu.add(action);
+ action= getAction("FoldingCollapseComments"); //$NON-NLS-1$
+ foldingMenu.add(action);
+ }
+
+ private void addDebugActions(IMenuManager menu) {
+ menu.add(fToggleBreakpointAction);
+ menu.add(fEnableDisableBreakpointAction);
+ }
+
+ /**
+ * Sets the given message as error message to this editor's status line.
+ *
+ * @param msg message to be set
+ */
+ protected void setStatusLineErrorMessage(String msg) {
+ IEditorStatusLine statusLine= (IEditorStatusLine) getAdapter(IEditorStatusLine.class);
+ if (statusLine != null)
+ statusLine.setMessage(true, msg, null);
+ }
+
+ /**
+ * Sets the given message as message to this editor's status line.
+ *
+ * @param msg message to be set
+ * @since 3.0
+ */
+ protected void setStatusLineMessage(String msg) {
+ IEditorStatusLine statusLine= (IEditorStatusLine) getAdapter(IEditorStatusLine.class);
+ if (statusLine != null)
+ statusLine.setMessage(false, msg, null);
+ }
+
+ public ProblemMarkerManager getProblemMarkerManager() {
+ return fProblemMarkerManager;
+ }
+
+ public void updatedTitleImage(Image image) {
+ setTitleImage(image);
+ }
+
+ // SMS 24 Jan 2007: Restoring gotoAnnotation (which had been briefly
+ // commented out) because it is called by the recently added class
+ // GotoAnnotationAction. Also made return void (since nothing is
+ // returned and no return seems expected).
+ // This change may be specific to Eclipse 3.1 and the method may
+ // be removed again in versions of the Editor intended for Eclipse 3.2.
+ //
+ // SMS 28 Jun 2007: Yes, indeed, the void return type doesn't work
+ // in Eclipse 3.2. Converted return type back to Annotation and adapted
+ // procedure to return an annotation in any case.
+
+ /**
+ * Jumps to the next enabled annotation according to the given direction.
+ * An annotation type is enabled if it is configured to be in the
+ * Next/Previous tool bar drop down menu and if it is checked.
+ *
+ * @param forward <code>true</code> if search direction is forward, <code>false</code> if backward
+ */
+ public Annotation /*void*/gotoAnnotation(boolean forward) {
+ ITextSelection selection= (ITextSelection) getSelectionProvider().getSelection();
+ Position position= new Position(0, 0);
+
+ // SMS 28 Jun 2007: declared here for something to return from both
+ // branches
+ Annotation annotation= null;
+
+ if (false /* delayed - see bug 18316 */) {
+ annotation= getNextAnnotation(selection.getOffset(), selection.getLength(), forward, position);
+ selectAndReveal(position.getOffset(), position.getLength());
+ } else /* no delay - see bug 18316 */{
+ /* Annotation */annotation= getNextAnnotation(selection.getOffset(), selection.getLength(), forward, position);
+
+ setStatusLineErrorMessage(null);
+ setStatusLineMessage(null);
+ if (annotation != null) {
+ updateAnnotationViews(annotation);
+ selectAndReveal(position.getOffset(), position.getLength());
+ setStatusLineMessage(annotation.getText());
+ }
+ }
+ return annotation;
+ }
+
+
+ /**
+ * Returns the annotation closest to the given range respecting the given
+ * direction. If an annotation is found, the annotations current position
+ * is copied into the provided annotation position.
+ *
+ * @param offset the region offset
+ * @param length the region length
+ * @param forward <code>true</code> for forwards, <code>false</code> for backward
+ * @param annotationPosition the position of the found annotation
+ * @return the found annotation
+ */
+ private Annotation getNextAnnotation(final int offset, final int length, boolean forward, Position annotationPosition) {
+ Annotation nextAnnotation= null;
+ Position nextAnnotationPosition= null;
+ Annotation containingAnnotation= null;
+ Position containingAnnotationPosition= null;
+ boolean currentAnnotation= false;
+
+ IDocument document= getDocumentProvider().getDocument(getEditorInput());
+ int endOfDocument= document.getLength();
+ int distance= Integer.MAX_VALUE;
+
+ IAnnotationModel model= getDocumentProvider().getAnnotationModel(getEditorInput());
+
+ for(Iterator e= model.getAnnotationIterator(); e.hasNext();) {
+ Annotation a= (Annotation) e.next();
+ // if ((a instanceof IJavaAnnotation) && ((IJavaAnnotation) a).hasOverlay() || !isNavigationTarget(a))
+ // continue;
+ // TODO RMF 4/19/2006 - Need more accurate logic here for filtering annotations
+ if (!(a instanceof MarkerAnnotation) && !a.getType().equals(PARSE_ANNOTATION_TYPE))
+ continue;
+
+ Position p= model.getPosition(a);
+ if (p == null)
+ continue;
+
+ if (forward && p.offset == offset || !forward && p.offset + p.getLength() == offset + length) {// || p.includes(offset)) {
+ if (containingAnnotation == null
+ || (forward && p.length >= containingAnnotationPosition.length || !forward && p.length >= containingAnnotationPosition.length)) {
+ containingAnnotation= a;
+ containingAnnotationPosition= p;
+ currentAnnotation= p.length == length;
+ }
+ } else {
+ int currentDistance= 0;
+
+ if (forward) {
+ currentDistance= p.getOffset() - offset;
+ if (currentDistance < 0)
+ currentDistance= endOfDocument + currentDistance;
+
+ if (currentDistance < distance || currentDistance == distance && p.length < nextAnnotationPosition.length) {
+ distance= currentDistance;
+ nextAnnotation= a;
+ nextAnnotationPosition= p;
+ }
+ } else {
+ currentDistance= offset + length - (p.getOffset() + p.length);
+ if (currentDistance < 0)
+ currentDistance= endOfDocument + currentDistance;
+
+ if (currentDistance < distance || currentDistance == distance && p.length < nextAnnotationPosition.length) {
+ distance= currentDistance;
+ nextAnnotation= a;
+ nextAnnotationPosition= p;
+ }
+ }
+ }
+ }
+ if (containingAnnotationPosition != null && (!currentAnnotation || nextAnnotation == null)) {
+ annotationPosition.setOffset(containingAnnotationPosition.getOffset());
+ annotationPosition.setLength(containingAnnotationPosition.getLength());
+ return containingAnnotation;
+ }
+ if (nextAnnotationPosition != null) {
+ annotationPosition.setOffset(nextAnnotationPosition.getOffset());
+ annotationPosition.setLength(nextAnnotationPosition.getLength());
+ }
+
+ return nextAnnotation;
+ }
+
+ /**
+ * Updates the annotation views that show the given annotation.
+ *
+ * @param annotation the annotation
+ */
+ private void updateAnnotationViews(Annotation annotation) {
+ IMarker marker= null;
+ if (annotation instanceof MarkerAnnotation)
+ marker= ((MarkerAnnotation) annotation).getMarker();
+ else
+ // if (annotation instanceof IJavaAnnotation) {
+ // Iterator e= ((IJavaAnnotation) annotation).getOverlaidIterator();
+ // if (e != null) {
+ // while (e.hasNext()) {
+ // Object o= e.next();
+ // if (o instanceof MarkerAnnotation) {
+ // marker= ((MarkerAnnotation) o).getMarker();
+ // break;
+ // }
+ // }
+ // }
+ // }
+
+ if (marker != null /* && !marker.equals(fLastMarkerTarget) */) {
+ try {
+ boolean isProblem= marker.isSubtypeOf(IMarker.PROBLEM);
+ IWorkbenchPage page= getSite().getPage();
+ IViewPart view= page.findView(isProblem ? IPageLayout.ID_PROBLEM_VIEW : IPageLayout.ID_TASK_LIST); //$NON-NLS-1$ //$NON-NLS-2$
+ if (view != null) {
+ Method method= view.getClass().getMethod("setSelection", new Class[] { IStructuredSelection.class, boolean.class }); //$NON-NLS-1$
+ method.invoke(view, new Object[] { new StructuredSelection(marker), Boolean.TRUE });
+ }
+ } catch (CoreException x) {
+ } catch (NoSuchMethodException x) {
+ } catch (IllegalAccessException x) {
+ } catch (InvocationTargetException x) {
+ }
+ // ignore exceptions, don't update any of the lists, just set status line
+ }
+ }
+
+ public void createPartControl(Composite parent) {
+ fLanguage= LanguageRegistry.findLanguage(getEditorInput(), getDocumentProvider());
+
+ // SMS 10 Oct 2008: null check added per bug #242949
+ if (fLanguage == null) {
+// throw new IllegalArgumentException("No language support found for files of type '" +
+// EditorInputUtils.getPath(getEditorInput()).getFileExtension() + "'");
+ }
+
+ // Create language service extensions now, since some services could
+ // get accessed via super.createPartControl() (in particular, while
+ // setting up the ISourceViewer).
+ if (fLanguage != null) {
+ fLanguageServiceManager= new LanguageServiceManager(fLanguage);
+ fLanguageServiceManager.initialize(this);
+ fServiceControllerManager= new ServiceControllerManager(this, fLanguageServiceManager);
+ fServiceControllerManager.initialize();
+ if (fLanguageServiceManager.getParseController() != null) {
+ initializeParseController();
+ findLanguageSpecificPreferences();
+ }
+ }
+
+ super.createPartControl(parent);
+
+ if (fLanguageServiceManager != null && fLanguageServiceManager.getParseController() != null) {
+ fServiceControllerManager.setSourceViewer(getSourceViewer());
+ initiateServiceControllers();
+ }
+
+ // SMS 4 Apr 2007: Call no longer needed because preferences for the
+ // overview ruler are now obtained from appropriate preference store directly
+ //setupOverviewRulerAnnotations();
+
+ // SMS 4 Apr 2007: Also should not need this, since we're not using
+ // the plugin's store (for this purpose)
+ //AbstractDecoratedTextEditorPreferenceConstants.initializeDefaultValues(RuntimePlugin.getInstance().getPreferenceStore());
+
+ setTitleImageFromLanguageIcon();
+ setSourceFontFromPreference();
+ setupBracketCloser();
+ setupSourcePrefListeners();
+
+ initializeEditorContributors();
+
+ // SMS 3 Oct 2008: moved call to watchDocument(..) to initiateServiceControllers().
+ watchForSourceMove();
+ }
+
+ private void initializeParseController() {
+ // Initialize the parse controller now, since the initialization of other things (like the context help support) might depend on it being so.
+ IEditorInput editorInput= getEditorInput();
+ IFile file= EditorInputUtils.getFile(editorInput);
+ IPath filePath= EditorInputUtils.getPath(editorInput);
+ try {
+ ISourceProject srcProject= (file != null) ? ModelFactory.open(file.getProject()) : null;
+
+ fLanguageServiceManager.getParseController().initialize(filePath, srcProject, fAnnotationCreator);
+ } catch (ModelException e) {
+ ErrorHandler.reportError("Error initializing parser for input " + editorInput.getName() + ":", e);
+ }
+ }
+
+ private void findLanguageSpecificPreferences() {
+ IProject project= fLanguageServiceManager.getParseController().getProject().getRawProject();
+
+ fLangSpecificPrefs= new PreferencesService(project, fLanguage.getName());
+ }
+
+ private void setupSourcePrefListeners() {
+ if (fLangSpecificPrefs == null) return;
+ fFontListener= new StringPreferenceListener(fLangSpecificPrefs, PreferenceConstants.P_SOURCE_FONT) {
+ @Override
+ public void changed(String oldValue, String newValue) {
+ FontRegistry fontRegistry= RuntimePlugin.getInstance().getFontRegistry();
+
+ if (!fontRegistry.hasValueFor(newValue)) {
+ fontRegistry.put(newValue, PreferenceConverter.readFontData(newValue));
+ }
+ Font sourceFont= fontRegistry.get(newValue);
+
+ if (sourceFont != null) {
+ getSourceViewer().getTextWidget().setFont(sourceFont);
+ }
+ }
+ };
+ fTabListener= new IntegerPreferenceListener(fLangSpecificPrefs, PreferenceConstants.P_TAB_WIDTH) {
+ @Override
+ public void changed(int oldValue, int newValue) {
+ if (getSourceViewer() != null)
+ getSourceViewer().getTextWidget().setTabs(newValue);
+ }
+ };
+ }
+
+ private void watchDocument(final long reparse_schedule_delay) {
+ if (fLanguageServiceManager.getParseController() == null) {
+ return;
+ }
+
+ IDocument doc= getDocumentProvider().getDocument(getEditorInput());
+
+ doc.addDocumentListener(new IDocumentListener() {
+ public void documentAboutToBeChanged(DocumentEvent event) {}
+ public void documentChanged(DocumentEvent event) {
+ fParserScheduler.cancel();
+ fParserScheduler.schedule(reparse_schedule_delay);
+ }
+ });
+ // SMS 3 Oct 2008: removed call to fParserScheduler.schedule(..)
+ }
+
+ private class BracketInserter implements VerifyKeyListener {
+ private final Map<String,String> fFencePairs= new HashMap<String, String>();
+ private final String fOpenFences;
+ private final Map<Character,Boolean> fCloseFenceMap= new HashMap<Character, Boolean>();
+// private final String CATEGORY= toString();
+// private IPositionUpdater fUpdater= new ExclusivePositionUpdater(CATEGORY);
+
+ public BracketInserter() {
+ String[][] pairs= fLanguageServiceManager.getParseController().getSyntaxProperties().getFences();
+ StringBuilder sb= new StringBuilder();
+ for(int i= 0; i < pairs.length; i++) {
+ sb.append(pairs[i][0]);
+ fFencePairs.put(pairs[i][0], pairs[i][1]);
+ }
+ fOpenFences= sb.toString();
+ }
+
+ public void setCloseFenceEnabled(char openingFence, boolean enabled) {
+ fCloseFenceMap.put(openingFence, enabled);
+ }
+
+ public void setCloseFencesEnabled(boolean enabled) {
+ for(int i= 0; i < fOpenFences.length(); i++) {
+ fCloseFenceMap.put(fOpenFences.charAt(i), enabled);
+ }
+ }
+
+ /*
+ * @see org.eclipse.swt.custom.VerifyKeyListener#verifyKey(org.eclipse.swt.events.VerifyEvent)
+ */
+ public void verifyKey(VerifyEvent event) {
+ // early pruning to slow down normal typing as little as possible
+ if (!event.doit || getInsertMode() != SMART_INSERT)
+ return;
+
+ if (fOpenFences.indexOf(event.character) < 0) {
+ return;
+ }
+
+ final ISourceViewer sourceViewer= getSourceViewer();
+ IDocument document= sourceViewer.getDocument();
+
+ final Point selection= sourceViewer.getSelectedRange();
+ final int offset= selection.x;
+ final int length= selection.y;
+
+ try {
+// IRegion startLine= document.getLineInformationOfOffset(offset);
+// IRegion endLine= document.getLineInformationOfOffset(offset + length);
+
+ // TODO Ask the parser/scanner whether the close fence is valid here
+ // (i.e. whether it would recover by inserting the matching close fence character)
+ // Right now, naively insert the closing fence regardless.
+
+ ITypedRegion partition= TextUtilities.getPartition(document, getSourceViewerConfiguration().getConfiguredDocumentPartitioning(sourceViewer), offset, true);
+ if (!IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType()))
+ return;
+
+ if (!validateEditorInputState())
+ return;
+
+ final String inputStr= new String(new char[] { event.character });
+ final String closingFence= fFencePairs.get(inputStr);
+ final StringBuffer buffer= new StringBuffer();
+ buffer.append(inputStr);
+ buffer.append(closingFence);
+
+ document.replace(offset, length, buffer.toString());
+ sourceViewer.setSelectedRange(offset + inputStr.length(), 0);
+
+ event.doit= false;
+ } catch (BadLocationException e) {
+ RuntimePlugin.getInstance().logException(e.getMessage(), e);
+ }
+ }
+ }
+
+ private BracketInserter fBracketInserter;
+ private final String CLOSE_FENCES= PreferenceConstants.EDITOR_CLOSE_FENCES;
+
+ private void setupBracketCloser() {
+ if (true) return; // Bug #536: Disable for now, until we can be more intelligent about when to overwrite an existing (subsequent) close-fence char.
+ IParseController parseController= fLanguageServiceManager.getParseController();
+ if (parseController == null || parseController.getSyntaxProperties() == null || parseController.getSyntaxProperties().getFences() == null) {
+ return;
+ }
+
+ /** Preference key for automatically closing brackets and parenthesis */
+ boolean closeFences= fLangSpecificPrefs.getBooleanPreference(CLOSE_FENCES); // false if no lang-specific setting
+
+ fBracketInserter= new BracketInserter();
+ fBracketInserter.setCloseFencesEnabled(closeFences);
+
+ ISourceViewer sourceViewer= getSourceViewer();
+ if (sourceViewer instanceof ITextViewerExtension)
+ ((ITextViewerExtension) sourceViewer).prependVerifyKeyListener(fBracketInserter);
+ }
+
+ private void watchForSourceMove() {
+ if (fLanguageServiceManager == null ||
+ fLanguageServiceManager.getParseController() == null ||
+ fLanguageServiceManager.getParseController().getProject() == null) {
+ return;
+ }
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(new IResourceChangeListener() {
+ public void resourceChanged(IResourceChangeEvent event) {
+ if (event.getType() != IResourceChangeEvent.POST_CHANGE)
+ return;
+ IParseController pc= fLanguageServiceManager.getParseController();
+ if (pc == null) {
+ return;
+ }
+ IPath oldWSRelPath= pc.getProject().getRawProject().getFullPath().append(pc.getPath());
+ IResourceDelta rd= event.getDelta().findMember(oldWSRelPath);
+
+ if (rd != null) {
+ if ((rd.getFlags() & IResourceDelta.MOVED_TO) == IResourceDelta.MOVED_TO) {
+ IPath newPath= rd.getMovedToPath();
+ IPath newProjRelPath= newPath.removeFirstSegments(1);
+ String newProjName= newPath.segment(0);
+ boolean sameProj= pc.getProject().getRawProject().getName().equals(newProjName);
+
+ try {
+ ISourceProject proj= sameProj ? pc.getProject() : ModelFactory.open(ResourcesPlugin.getWorkspace().getRoot().getProject(newProjName));
+
+ // Tell the IParseController about the move - it caches the path
+// fParserScheduler.cancel(); // avoid a race condition if ParserScheduler was starting/in the middle of a run
+ pc.initialize(newProjRelPath, proj, fAnnotationCreator);
+ } catch (ModelException e) {
+ RuntimePlugin.getInstance().logException("Error tracking resource move", e);
+ }
+ }
+ }
+ }
+ });
+ }
+
+ private void setSourceFontFromPreference() {
+ String fontName= null;
+ if (fLangSpecificPrefs != null) {
+ fLangSpecificPrefs.getStringPreference(PreferenceConstants.P_SOURCE_FONT);
+ }
+ if (fontName == null) {
+ IPreferenceStore prefStore= RuntimePlugin.getInstance().getPreferenceStore();
+
+ fontName= prefStore.getString(PreferenceConstants.P_SOURCE_FONT);
+ }
+ FontRegistry fontRegistry= RuntimePlugin.getInstance().getFontRegistry();
+
+ if (!fontRegistry.hasValueFor(fontName)) {
+ fontRegistry.put(fontName, PreferenceConverter.readFontData(fontName));
+ }
+ Font sourceFont= fontRegistry.get(fontName);
+
+ if (sourceFont != null) {
+ getSourceViewer().getTextWidget().setFont(sourceFont);
+ }
+ }
+
+ private void initiateServiceControllers() {
+ try {
+ StructuredSourceViewer sourceViewer= (StructuredSourceViewer) getSourceViewer();
+
+ if (PreferenceCache.emitMessages) {
+ RuntimePlugin.getInstance().writeInfoMsg(
+ "Creating language service controllers for " + fLanguage.getName());
+ }
+
+ fEditorErrorTickUpdater= new EditorErrorTickUpdater(this);
+ fProblemMarkerManager.addListener(fEditorErrorTickUpdater);
+
+ fParserScheduler= new ParserScheduler(fLanguageServiceManager.getParseController(), this, getDocumentProvider(),
+ fAnnotationCreator);
+
+ // The source viewer configuration has already been asked for its ITextHover,
+ // but before we actually instantiated the relevant controller class. So update
+ // the source viewer, now that we actually have the hover provider.
+ sourceViewer.setTextHover(fServiceControllerManager.getHoverHelpController(), IDocument.DEFAULT_CONTENT_TYPE);
+
+ // The source viewer configuration has already been asked for its IContentFormatter,
+ // but before we actually instantiated the relevant controller class. So update the
+ // source viewer, now that we actually have the IContentFormatter.
+ ContentFormatter formatter= new ContentFormatter();
+
+ formatter.setFormattingStrategy(fServiceControllerManager.getFormattingController(), IDocument.DEFAULT_CONTENT_TYPE);
+ sourceViewer.setFormatter(formatter);
+
+ try {
+ fServiceControllerManager.getPresentationController().damage(new Region(0, sourceViewer.getDocument().getLength()));
+ } catch (Exception e) {
+ ErrorHandler.reportError("Error during initial damage repair", e);
+ }
+ // SMS 29 May 2007 (to give viewer access to single-line comment prefix)
+ sourceViewer.setParseController(fLanguageServiceManager.getParseController());
+
+ if (fLanguageServiceManager.getFoldingUpdater() != null) {
+ ProjectionViewer projViewer= (ProjectionViewer) sourceViewer;
+ ProjectionSupport projectionSupport= new ProjectionSupport(projViewer, getAnnotationAccess(),
+ getSharedColors());
+
+ projectionSupport.install();
+ projViewer.doOperation(ProjectionViewer.TOGGLE);
+ fAnnotationModel= projViewer.getProjectionAnnotationModel();
+ fParserScheduler.addModelListener(new FoldingController(fAnnotationModel, fLanguageServiceManager.getFoldingUpdater()));
+ }
+
+ fParserScheduler.addModelListener(new AnnotationCreatorListener());
+ fServiceControllerManager.setupModelListeners(fParserScheduler);
+
+ // TODO RMF 8/6/2007 - Disable "Mark Occurrences" if no occurrence marker exists for this language
+ // The following doesn't work b/c getAction() doesn't find the Mark Occurrences action (why?)
+ // if (this.fOccurrenceMarker == null)
+ // getAction("org.eclipse.imp.runtime.actions.markOccurrencesAction").setEnabled(false);
+
+ installExternalEditorServices();
+ watchDocument(REPARSE_SCHEDULE_DELAY);
+ fParserScheduler.run(new NullProgressMonitor());
+
+ } catch (Exception e) {
+ ErrorHandler.reportError("Error while creating service controllers", e);
+ }
+ }
+
+ private static final int REPARSE_SCHEDULE_DELAY= 100;
+
+ private void setTitleImageFromLanguageIcon() {
+ // Only set the editor's title bar icon if the language has a label provider
+ if (fLanguageServiceManager != null && fLanguageServiceManager.getLabelProvider() != null) {
+ IEditorInput editorInput= getEditorInput();
+ IFile file= EditorInputUtils.getFile(editorInput);
+
+ try {
+ setTitleImage(fLanguageServiceManager.getLabelProvider().getImage(file));
+ } catch (Exception e) {
+ ErrorHandler.reportError("Error while setting source editor title icon from label provider", e);
+ }
+ }
+ }
+
+ private void installExternalEditorServices() {
+ Set<IModelListener> editorServices= fLanguageServiceManager.getEditorServices();
+
+ for(ILanguageService editorService : editorServices) {
+ if (editorService instanceof IEditorService)
+ ((IEditorService) editorService).setEditor(this);
+ fParserScheduler.addModelListener((IModelListener) editorService);
+ }
+ }
+
+ /**
+ * Adds elements to toolbars, menubars and statusbars
+ *
+ */
+ private void initializeEditorContributors() {
+ if (fLanguage != null) {
+ addEditorActions();
+ registerEditorContributionsActivator();
+ }
+ }
+
+ /**
+ * Makes sure that menu items and status bar items disappear as the editor
+ * is out of focus, and reappear when it gets focus again. This does
+ * not work for toolbar items for unknown reasons, they stay visible.
+ *
+ */
+ private void registerEditorContributionsActivator() {
+ fRefreshContributions = new DefaultPartListener() {
+ private UniversalEditor editor = UniversalEditor.this;
+
+ public void partActivated(IWorkbenchPart part) {
+ if (part == editor) {
+ editor.fActionBars.activate();
+ editor.fActionBars.updateActionBars();
+ }
+ }
+
+ public void partDeactivated(IWorkbenchPart part) {
+ if (part == editor) {
+ editor.fActionBars.deactivate();
+ editor.fActionBars.updateActionBars();
+ }
+ }
+ };
+ getSite().getPage().addPartListener(fRefreshContributions);
+ }
+
+ private void unregisterEditorContributionsActivator() {
+ if (fRefreshContributions != null) {
+ getSite().getPage().removePartListener(fRefreshContributions);
+ }
+ fRefreshContributions= null;
+ }
+
+ /**
+ * Uses the LanguageActionsContributor extension point to add
+ * elements to (sub) action bars.
+ *
+ */
+ private void addEditorActions() {
+ final IActionBars allActionBars = getEditorSite().getActionBars();
+ if (fActionBars == null) {
+ Set<ILanguageActionsContributor> contributors = ServiceFactory
+ .getInstance().getLanguageActionsContributors(fLanguage);
+
+ fActionBars = new SubActionBars(allActionBars);
+
+ IStatusLineManager status = fActionBars.getStatusLineManager();
+ IToolBarManager toolbar = fActionBars.getToolBarManager();
+ IMenuManager menu = fActionBars.getMenuManager();
+
+ for (ILanguageActionsContributor c : contributors) {
+ c.contributeToStatusLine(this, status);
+ c.contributeToToolBar(this, toolbar);
+ c.contributeToMenuBar(this, menu);
+ }
+
+ fActionBars.updateActionBars();
+ allActionBars.updateActionBars();
+ }
+ allActionBars.updateActionBars();
+ }
+
+ public void dispose() {
+ if (fFontListener != null) {
+ fFontListener.dispose();
+ }
+ if (fTabListener != null) {
+ fTabListener.dispose();
+ }
+
+ unregisterEditorContributionsActivator();
+ if (fEditorErrorTickUpdater != null) {
+ fProblemMarkerManager.removeListener(fEditorErrorTickUpdater);
+ }
+
+ if (fActionBars != null) {
+ fActionBars.dispose();
+ fActionBars = null;
+ }
+
+ super.dispose();
+ }
+
+ /**
+ * Override creation of the normal source viewer with one that supports source folding.
+ */
+ protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
+ // if (fFoldingUpdater == null)
+ // return super.createSourceViewer(parent, ruler, styles);
+
+ fAnnotationAccess= createAnnotationAccess();
+ fOverviewRuler= createOverviewRuler(getSharedColors());
+
+ ISourceViewer viewer= new StructuredSourceViewer(parent, ruler, getOverviewRuler(), isOverviewRulerVisible(), styles);
+ // ensure decoration support has been created and configured.
+ getSourceViewerDecorationSupport(viewer);
+ if (fLanguageServiceManager != null && fLanguageServiceManager.getParseController() != null) {
+ IMPHelp.setHelp(fLanguageServiceManager, this, viewer.getTextWidget(), IMP_EDITOR_CONTEXT);
+ }
+
+ return viewer;
+ }
+
+ protected void configureSourceViewerDecorationSupport(SourceViewerDecorationSupport support) {
+ // X10DT Bug #546: If this input has no corresponding language descriptor, someone
+ // can still associate the IMP editor with this file extension, in which case we
+ // get here with no fLanguage and no fLanguageServiceManager.
+ if (fLanguage == null || fLanguageServiceManager == null) {
+ return;
+ }
+ IParseController parseController = fLanguageServiceManager.getParseController();
+
+ if (parseController == null) {
+ return;
+ }
+
+ ILanguageSyntaxProperties syntaxProps= parseController.getSyntaxProperties();
+ getPreferenceStore().setValue(MATCHING_BRACKETS, true);
+ if (syntaxProps != null) {
+// fBracketMatcher.setSourceVersion(getPreferenceStore().getString(JavaCore.COMPILER_SOURCE));
+ String[][] fences= syntaxProps.getFences();
+ if (fences != null) {
+ StringBuilder sb= new StringBuilder();
+ for(int i= 0; i < fences.length; i++) {
+ sb.append(fences[i][0]);
+ sb.append(fences[i][1]);
+ }
+ fBracketMatcher= new DefaultCharacterPairMatcher(sb.toString().toCharArray());
+ support.setCharacterPairMatcher(fBracketMatcher);
+ support.setMatchingCharacterPainterPreferenceKeys(MATCHING_BRACKETS, MATCHING_BRACKETS_COLOR);
+ }
+ }
+ super.configureSourceViewerDecorationSupport(support);
+ }
+
+ /**
+ * Jumps to the matching bracket.
+ */
+ public void gotoMatchingFence() {
+ ISourceViewer sourceViewer= getSourceViewer();
+ IDocument document= sourceViewer.getDocument();
+ if (document == null)
+ return;
+
+ IRegion selection= getSignedSelection(sourceViewer);
+ int selectionLength= Math.abs(selection.getLength());
+
+ if (selectionLength > 1) {
+ setStatusLineErrorMessage("Invalid selection");
+ sourceViewer.getTextWidget().getDisplay().beep();
+ return;
+ }
+
+ // #26314
+ int sourceCaretOffset= selection.getOffset() + selection.getLength();
+ if (isSurroundedByBrackets(document, sourceCaretOffset))
+ sourceCaretOffset -= selection.getLength();
+
+ IRegion region= fBracketMatcher.match(document, sourceCaretOffset);
+ if (region == null) {
+ setStatusLineErrorMessage("No matching fence!");
+ sourceViewer.getTextWidget().getDisplay().beep();
+ return;
+ }
+
+ int offset= region.getOffset();
+ int length= region.getLength();
+
+ if (length < 1)
+ return;
+
+ int anchor= fBracketMatcher.getAnchor();
+ // http://dev.eclipse.org/bugs/show_bug.cgi?id=34195
+ int targetOffset= (ICharacterPairMatcher.RIGHT == anchor) ? offset + 1: offset + length;
+
+ boolean visible= false;
+ if (sourceViewer instanceof ITextViewerExtension5) {
+ ITextViewerExtension5 extension= (ITextViewerExtension5) sourceViewer;
+ visible= (extension.modelOffset2WidgetOffset(targetOffset) > -1);
+ } else {
+ IRegion visibleRegion= sourceViewer.getVisibleRegion();
+ // http://dev.eclipse.org/bugs/show_bug.cgi?id=34195
+ visible= (targetOffset >= visibleRegion.getOffset() && targetOffset <= visibleRegion.getOffset() + visibleRegion.getLength());
+ }
+
+ if (!visible) {
+ setStatusLineErrorMessage("Matching fence is outside the currently selected element.");
+ sourceViewer.getTextWidget().getDisplay().beep();
+ return;
+ }
+
+ if (selection.getLength() < 0)
+ targetOffset -= selection.getLength();
+
+ sourceViewer.setSelectedRange(targetOffset, selection.getLength());
+ sourceViewer.revealRange(targetOffset, selection.getLength());
+ }
+
+ private boolean isBracket(char character) {
+ ILanguageSyntaxProperties syntaxProps= fLanguageServiceManager.getParseController().getSyntaxProperties();
+ String[][] fences= syntaxProps.getFences();
+
+ for(int i= 0; i != fences.length; ++i) {
+ if (fences[i][0].indexOf(character) >= 0)
+ return true;
+ if (fences[i][1].indexOf(character) >= 0)
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isSurroundedByBrackets(IDocument document, int offset) {
+ if (offset == 0 || offset == document.getLength())
+ return false;
+
+ try {
+ return isBracket(document.getChar(offset - 1)) &&
+ isBracket(document.getChar(offset));
+ } catch (BadLocationException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the signed current selection.
+ * The length will be negative if the resulting selection
+ * is right-to-left (RtoL).
+ * <p>
+ * The selection offset is model based.
+ * </p>
+ *
+ * @param sourceViewer the source viewer
+ * @return a region denoting the current signed selection, for a resulting RtoL selections length is < 0
+ */
+ protected IRegion getSignedSelection(ISourceViewer sourceViewer) {
+ StyledText text= sourceViewer.getTextWidget();
+ Point selection= text.getSelectionRange();
+
+ if (text.getCaretOffset() == selection.x) {
+ selection.x= selection.x + selection.y;
+ selection.y= -selection.y;
+ }
+
+ selection.x= widgetOffset2ModelOffset(sourceViewer, selection.x);
+
+ return new Region(selection.x, selection.y);
+ }
+
+ public final String PARSE_ANNOTATION = "Parse_Annotation";
+
+ private Map<IMarker, Annotation> markerParseAnnotations = new HashMap<IMarker, Annotation>();
+ private Map<IMarker, MarkerAnnotation> markerMarkerAnnotations = new HashMap<IMarker, MarkerAnnotation>();
+
+ /**
+ * Refresh the marker annotations on the input document by removing any
+ * that do not map to current parse annotations. Do this for problem
+ * markers, specifically; ignore other types of markers.
+ *
+ * SMS 25 Apr 2007
+ */
+ public void refreshMarkerAnnotations(String problemMarkerType)
+ {
+ // Get current marker annotations
+ IAnnotationModel model = getDocumentProvider().getAnnotationModel(getEditorInput());
+ Iterator annIter = model.getAnnotationIterator();
+ List<MarkerAnnotation> markerAnnotations = new ArrayList<MarkerAnnotation>();
+ while (annIter.hasNext()) {
+ Object ann = annIter.next();
+ if (ann instanceof MarkerAnnotation) {
+ markerAnnotations.add((MarkerAnnotation) ann);
+ }
+ }
+
+ // For the current marker annotations, if any lacks a corresponding
+ // parse annotation, delete the marker annotation from the document's
+ // annotation model (but leave the marker on the underlying resource,
+ // which presumably hasn't been changed, despite changes to the document)
+ for (int i = 0; i < markerAnnotations.size(); i++) {
+ IMarker marker = markerAnnotations.get(i).getMarker();
+ try {
+ String markerType = marker.getType();
+ if (!markerType.endsWith(problemMarkerType))
+ continue;
+ } catch (CoreException e) {
+ // If we get a core exception here, probably something is wrong with the
+ // marker, and we probably don't want to keep any annotation that may be
+ // associated with it (I don't think)
+ model.removeAnnotation(markerAnnotations.get(i));
+ continue;
+ }
+ if (markerParseAnnotations.get(marker) != null) {
+ continue;
+ } else {
+ model.removeAnnotation(markerAnnotations.get(i));
+ }
+ }
+ }
+
+
+ /**
+ * This is a type of listener whose purpose is to monitor changes to a document
+ * annotation model and to maintain at a mapping from markers on the underlying
+ * resource to parse annotations on the document.
+ *
+ * The association of markers to annotations is determined by a subroutine that
+ * may be more or less sophisticated in how it identifies associations. The
+ * accuracy of the map depends on the implementation of this routine. (The
+ * current implementation of the method simply compares text ranges of annotations
+ * and markers.)
+ *
+ * The motivating purpose of the mapping is to enable the identification of marker
+ * annotations that are (or are not) associated with a current parse annotation.
+ * Then, for instance, marker annotations that are not associated with current parse
+ * annotations might be removed from the document.
+ *
+ * No assumptions are made here about the type (or types) of marker annotation of
+ * interest; all types of marker annotation are considered.
+ *
+ * SMS 25 Apr 2007
+ */
+ protected class InputAnnotationModelListener implements IAnnotationModelListener
+ {
+ public void modelChanged(IAnnotationModel model)
+ {
+ List<Annotation> currentParseAnnotations = new ArrayList<Annotation>();
+ List<IMarker> currentMarkers = new ArrayList<IMarker>();
+ markerParseAnnotations = new HashMap<IMarker,Annotation>();
+ markerMarkerAnnotations = new HashMap<IMarker,MarkerAnnotation>();
+
+ // Collect the current set of markers and parse annotations;
+ // also maintain a map of markers to marker annotations (as
+ // there doesn't seem to be a way to get from a marker to the
+ // annotations that may represent it)
+ Iterator annotations = model.getAnnotationIterator();
+ while (annotations.hasNext()) {
+ Object ann = annotations.next();
+ if (ann instanceof MarkerAnnotation) {
+ IMarker marker = ((MarkerAnnotation)ann).getMarker();
+ if (marker.exists()) {
+ currentMarkers.add(marker);
+ }
+ markerMarkerAnnotations.put(marker, (MarkerAnnotation) ann);
+ } else if (ann instanceof Annotation) {
+ Annotation annotation = (Annotation) ann;
+ if (annotation.getType().equals(PARSE_ANNOTATION_TYPE)) {
+ currentParseAnnotations.add(annotation);
+ }
+ }
+ }
+
+ // Create a mapping between current markers and parse annotations
+ for (int i = 0; i < currentMarkers.size(); i++) {
+ IMarker marker = currentMarkers.get(i);
+ Annotation annotation = findParseAnnotationForMarker(model, marker, currentParseAnnotations);
+ if (annotation != null) {
+ markerParseAnnotations.put(marker, annotation);
+ }
+ }
+ }
+
+
+ public Annotation findParseAnnotationForMarker(IAnnotationModel model, IMarker marker, List parseAnnotations) {
+ Integer markerStartAttr = null;
+ Integer markerEndAttr = null;
+ try {
+ // SMS 22 May 2007: With markers created through the editor the CHAR_START
+ // and CHAR_END attributes are null, giving rise to NPEs here. Not sure
+ // why this happens, but it seems to help down the line to trap the NPE.
+ markerStartAttr = ((Integer) marker.getAttribute(IMarker.CHAR_START));
+ markerEndAttr = ((Integer) marker.getAttribute(IMarker.CHAR_END));
+ if (markerStartAttr == null || markerEndAttr == null) {
+ return null;
+ }
+ } catch (CoreException e) {
+ // RMF 7/25/2008 -- This exception should never occur, now that we check that each marker still exists in modelChanged()
+ // (see Bug 242098).
+ RuntimePlugin.getInstance().logException("UniversalEditor.findParseAnnotationForMarker: CoreException getting marker start and end attributes", e);
+ return null;
+ } catch (NullPointerException e) {
+ RuntimePlugin.getInstance().logException("UniversalEditor.findParseAnnotationForMarker: NullPointerException getting marker start and end attributes", e);
+ return null;
+ }
+
+ int markerStart = markerStartAttr.intValue();
+ int markerEnd = markerEndAttr.intValue();
+ int markerLength = markerEnd - markerStart;
+
+ for (int j = 0; j < parseAnnotations.size(); j++) {
+ Annotation parseAnnotation = (Annotation) parseAnnotations.get(j);
+ Position pos = model.getPosition(parseAnnotation);
+ if (pos == null)
+ // And this would be why?
+ continue;
+ int annotationStart = pos.offset;
+ int annotationLength = pos.length;
+ //System.out.println("\tfindPareseAnnotationForMarker: Checking annotation offset and length = " + annotationStart + ", " + annotationLength);
+
+ if (markerStart == annotationStart && markerLength == annotationLength) {
+ //System.out.println("\tfindPareseAnnotationForMarker: Returning annotation at offset = " + markerStart);
+ return parseAnnotation;
+ } else {
+ //System.out.println("\tfindPareseAnnotationForMarker: Not returning annotation at offset = " + markerStart);
+ }
+ }
+
+ //System.out.println(" findPareseAnnotationForMarker: No corresponding annotation found; returning null");
+ return null;
+ }
+ }
+
+ protected void doSetInput(IEditorInput input) throws CoreException {
+ // SMS 22 May 2007: added try/catch around doSetInput(..)
+ try {
+ super.doSetInput(input);
+ } catch (NullPointerException e) {
+ return;
+ }
+ setInsertMode(SMART_INSERT);
+
+ // SMS 25 Apr 2007
+ // Added for maintenance of associations between marker annotations
+ // and parse annotations
+ IAnnotationModel annotationModel = getDocumentProvider().getAnnotationModel(input);
+ // RMF 6 Jun 2007 - Not sure why annotationModel is null for files outside the
+ // workspace, but they are, so make sure we don't cause an NPE here.
+ if (annotationModel != null)
+ annotationModel.addAnnotationModelListener(new InputAnnotationModelListener());
+ }
+
+ /**
+ * Add a Model listener to this editor. Any time the underlying AST is recomputed, the listener is notified.
+ *
+ * @param listener the listener to notify of Model changes
+ */
+ public void addModelListener(IModelListener listener) {
+ fParserScheduler.addModelListener(listener);
+ }
+
+ /**
+ * Remove a Model listener from this editor.
+ *
+ * @param listener the listener to remove
+ */
+ public void removeModelListener(IModelListener listener) {
+ fParserScheduler.removeModelListener(listener);
+ }
+
+ class StructuredSourceViewerConfiguration extends TextSourceViewerConfiguration {
+ public int getTabWidth(ISourceViewer sourceViewer) {
+ boolean langSpecificSetting= fLangSpecificPrefs != null && fLangSpecificPrefs.isDefined(PreferenceConstants.P_TAB_WIDTH);
+
+ return langSpecificSetting ? fLangSpecificPrefs.getIntPreference(PreferenceConstants.P_TAB_WIDTH) : PreferenceCache.tabWidth;
+ }
+
+ public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
+ if (fServiceControllerManager == null) {
+ return super.getPresentationReconciler(sourceViewer);
+ }
+ // BUG Perhaps we shouldn't use a PresentationReconciler; its JavaDoc says it runs in the UI thread!
+ PresentationReconciler reconciler= new PresentationReconciler();
+ reconciler.setRepairer(new PresentationRepairer(), IDocument.DEFAULT_CONTENT_TYPE);
+ reconciler.setDamager(new PresentationDamager(), IDocument.DEFAULT_CONTENT_TYPE);
+ return reconciler;
+ }
+
+ public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
+ if (fServiceControllerManager == null) {
+ return super.getContentAssistant(sourceViewer);
+ }
+ ContentAssistant ca= new ContentAssistant();
+ ca.setContentAssistProcessor(fServiceControllerManager.getCompletionProcessor(), IDocument.DEFAULT_CONTENT_TYPE);
+ ca.setInformationControlCreator(getInformationControlCreator(sourceViewer));
+ return ca;
+ }
+
+ public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
+ if (fLanguageServiceManager == null) {
+ return super.getAnnotationHover(sourceViewer);
+ }
+ IAnnotationHover hover= fLanguageServiceManager.getAnnotationHover();
+ if (hover == null)
+ hover= new DefaultAnnotationHover();
+ return hover;
+ }
+
+ public IAutoEditStrategy[] getAutoEditStrategies(ISourceViewer sourceViewer, String contentType) {
+ if (fLanguageServiceManager == null) {
+ return super.getAutoEditStrategies(sourceViewer, contentType);
+ }
+ Set<org.eclipse.imp.services.IAutoEditStrategy> autoEdits= fLanguageServiceManager.getAutoEditStrategies();
+
+ if (autoEdits == null)
+ return super.getAutoEditStrategies(sourceViewer, contentType);
+
+ return autoEdits.toArray(new IAutoEditStrategy[autoEdits.size()]);
+ }
+
+ public IContentFormatter getContentFormatter(ISourceViewer sourceViewer) {
+ // Disable the content formatter if no language-specific implementation exists.
+ // N.B.: This will probably always be null, since this method gets called before
+ // the formatting controller has been instantiated (which happens in
+ // instantiateServiceControllers()).
+ if (fServiceControllerManager == null || fServiceControllerManager.getFormattingController() == null)
+ return null;
+
+ // For now, assumes only one content type (i.e. one kind of partition)
+ ContentFormatter formatter= new ContentFormatter();
+
+ formatter.setFormattingStrategy(fServiceControllerManager.getFormattingController(), IDocument.DEFAULT_CONTENT_TYPE);
+ return formatter;
+ }
+
+ public String[] getDefaultPrefixes(ISourceViewer sourceViewer, String contentType) {
+ return super.getDefaultPrefixes(sourceViewer, contentType);
+ }
+
+ public ITextDoubleClickStrategy getDoubleClickStrategy(ISourceViewer sourceViewer, String contentType) {
+ return super.getDoubleClickStrategy(sourceViewer, contentType);
+ }
+
+ public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {
+ if (fServiceControllerManager != null && fServiceControllerManager.getHyperLinkController() != null)
+ return new IHyperlinkDetector[] { fServiceControllerManager.getHyperLinkController() };
+ return super.getHyperlinkDetectors(sourceViewer);
+ }
+
+ public IHyperlinkPresenter getHyperlinkPresenter(ISourceViewer sourceViewer) {
+ return super.getHyperlinkPresenter(sourceViewer);
+ }
+
+ public String[] getIndentPrefixes(ISourceViewer sourceViewer, String contentType) {
+ return super.getIndentPrefixes(sourceViewer, contentType);
+ }
+
+ public IInformationControlCreator getInformationControlCreator(ISourceViewer sourceViewer) {
+ return new IInformationControlCreator() {
+ public IInformationControl createInformationControl(Shell parent) {
+// int shellStyle= SWT.RESIZE | SWT.TOOL;
+ int style= SWT.NONE; // SWT.V_SCROLL | SWT.H_SCROLL;
+
+// if (BrowserInformationControl.isAvailable(parent))
+// return new BrowserInformationControl(parent, SWT.TOOL | SWT.NO_TRIM, SWT.NONE, EditorsUI.getTooltipAffordanceString());
+// else
+ // return new OutlineInformationControl(parent, shellStyle, style, new HTMLTextPresenter(false));
+ return new DefaultInformationControl(parent, style, new HTMLTextPresenter(true), "Press 'F2' for focus");
+ }
+ };
+ }
+
+ private InformationPresenter fInfoPresenter;
+
+ public IInformationPresenter getInformationPresenter(ISourceViewer sourceViewer) {
+ if (fLanguageServiceManager == null) {
+ return super.getInformationPresenter(sourceViewer);
+ }
+ if (fInfoPresenter == null) {
+ fInfoPresenter= new InformationPresenter(getInformationControlCreator(sourceViewer));
+ fInfoPresenter.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+ fInfoPresenter.setAnchor(AbstractInformationControlManager.ANCHOR_GLOBAL);
+
+ IInformationProvider provider= new IInformationProvider() { // this should be language-specific
+ private IDocumentationProvider fDocProvider= fLanguageServiceManager.getDocProvider();
+ private IParseController fParseController= fLanguageServiceManager.getParseController();
+ private ISourcePositionLocator fNodeLocator= (fParseController != null) ? fParseController.getSourcePositionLocator() : null;
+
+ public IRegion getSubject(ITextViewer textViewer, int offset) {
+ if (fNodeLocator == null) {
+ return new Region(offset, 0);
+ }
+ Object selNode= fNodeLocator.findNode(fParseController.getCurrentAst(), offset);
+ return new Region(fNodeLocator.getStartOffset(selNode), fNodeLocator.getLength(selNode));
+ }
+ public String getInformation(ITextViewer textViewer, IRegion subject) {
+ if (fNodeLocator == null) {
+ return "";
+ }
+ Object selNode= fNodeLocator.findNode(fParseController.getCurrentAst(), subject.getOffset());
+ return (fDocProvider != null) ? fDocProvider.getDocumentation(selNode, fParseController) : "No documentation available on the selected entity.";
+ }
+ };
+ fInfoPresenter.setInformationProvider(provider, IDocument.DEFAULT_CONTENT_TYPE);
+ fInfoPresenter.setSizeConstraints(60, 10, true, false);
+ fInfoPresenter.setRestoreInformationControlBounds(getSettings("outline_presenter_bounds"), true, true); //$NON-NLS-1$
+ }
+ return fInfoPresenter;
+ }
+
+ public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
+ if (fServiceControllerManager == null) {
+ return super.getTextHover(sourceViewer, contentType);
+ }
+ return fServiceControllerManager.getHoverHelpController();
+ }
+
+ public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType, int stateMask) {
+ return super.getTextHover(sourceViewer, contentType, stateMask);
+ }
+
+ public IUndoManager getUndoManager(ISourceViewer sourceViewer) {
+ return super.getUndoManager(sourceViewer);
+ }
+
+ public IAnnotationHover getOverviewRulerAnnotationHover(ISourceViewer sourceViewer) {
+ return super.getOverviewRulerAnnotationHover(sourceViewer);
+ }
+
+ private class OutlineInformationProvider implements IInformationProvider, IInformationProviderExtension {
+ private TreeModelBuilderBase fBuilder;
+
+ public IRegion getSubject(ITextViewer textViewer, int offset) {
+ return new Region(offset, 0); // Could be anything, since it's ignored below in getInformation2()...
+ }
+
+ public String getInformation(ITextViewer textViewer, IRegion subject) {
+ return "never called?!?"; // shouldn't be called, given IInformationProviderExtension???
+ }
+
+ public Object getInformation2(ITextViewer textViewer, IRegion subject) {
+ if (fBuilder == null) {
+ fBuilder= fLanguageServiceManager.getModelBuilder();
+ }
+ return fBuilder.buildTree(fLanguageServiceManager.getParseController().getCurrentAst());
+ }
+ }
+
+ private IInformationProvider fOutlineElementProvider= new OutlineInformationProvider();
+
+ public IInformationPresenter getOutlinePresenter(ISourceViewer sourceViewer) {
+ if (fLanguageServiceManager == null) {
+ return null;
+ }
+ TreeModelBuilderBase modelBuilder= fLanguageServiceManager.getModelBuilder();
+ if (modelBuilder == null) {
+ return null;
+ }
+
+ InformationPresenter presenter;
+
+ presenter= new InformationPresenter(getOutlinePresenterControlCreator(sourceViewer, IEditorActionDefinitionIds.SHOW_OUTLINE));
+ presenter.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+ presenter.setAnchor(AbstractInformationControlManager.ANCHOR_GLOBAL);
+
+ IInformationProvider provider= fOutlineElementProvider;
+
+ presenter.setInformationProvider(provider, IDocument.DEFAULT_CONTENT_TYPE);
+ // TODO Should associate all other partition types with this provider, too
+ presenter.setSizeConstraints(50, 20, true, false);
+ presenter.setRestoreInformationControlBounds(getSettings("outline_presenter_bounds"), true, true); //$NON-NLS-1$
+ return presenter;
+ }
+
+ /**
+ * Returns the outline presenter control creator. The creator is a factory creating outline presenter controls for the given source viewer. This
+ * implementation always returns a creator for <code>OutlineInformationControl</code> instances.
+ *
+ * @param sourceViewer the source viewer to be configured by this configuration
+ * @param commandId the ID of the command that opens this control
+ * @return an information control creator
+ */
+ private IInformationControlCreator getOutlinePresenterControlCreator(ISourceViewer sourceViewer, final String commandId) {
+ return new IInformationControlCreator() {
+ public IInformationControl createInformationControl(Shell parent) {
+ int shellStyle= SWT.RESIZE;
+ int treeStyle= SWT.V_SCROLL | SWT.H_SCROLL;
+
+ return new OutlineInformationControl(parent, shellStyle, treeStyle, commandId, UniversalEditor.this.fLanguage);
+ }
+ };
+ }
+
+ /**
+ * Returns the hierarchy presenter which will determine and shown type hierarchy information requested for the current cursor position.
+ *
+ * @param sourceViewer the source viewer to be configured by this configuration
+ * @param doCodeResolve a boolean which specifies whether code resolve should be used to compute the program element
+ * @return an information presenter
+ */
+ public IInformationPresenter getHierarchyPresenter(ISourceViewer sourceViewer, boolean doCodeResolve) {
+ InformationPresenter presenter= new InformationPresenter(getHierarchyPresenterControlCreator(sourceViewer));
+ presenter.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+ presenter.setAnchor(AbstractInformationControlManager.ANCHOR_GLOBAL);
+ IInformationProvider provider= null; // TODO RMF new HierarchyInformationProvider(this);
+ presenter.setInformationProvider(provider, IDocument.DEFAULT_CONTENT_TYPE);
+ // presenter.setInformationProvider(provider, IJavaPartitions.JAVA_DOC);
+ // presenter.setInformationProvider(provider, IJavaPartitions.JAVA_MULTI_LINE_COMMENT);
+ // presenter.setInformationProvider(provider, IJavaPartitions.JAVA_SINGLE_LINE_COMMENT);
+ // presenter.setInformationProvider(provider, IJavaPartitions.JAVA_STRING);
+ // presenter.setInformationProvider(provider, IJavaPartitions.JAVA_CHARACTER);
+ presenter.setSizeConstraints(50, 20, true, false);
+ presenter.setRestoreInformationControlBounds(getSettings("hierarchy_presenter_bounds"), true, true); //$NON-NLS-1$
+ return presenter;
+ }
+
+ private IInformationControlCreator getHierarchyPresenterControlCreator(ISourceViewer sourceViewer) {
+ return new IInformationControlCreator() {
+ public IInformationControl createInformationControl(Shell parent) {
+ int shellStyle= SWT.RESIZE;
+ int treeStyle= SWT.V_SCROLL | SWT.H_SCROLL;
+
+ return new DefaultInformationControl(parent); // HierarchyInformationControl(parent, shellStyle, treeStyle);
+ }
+ };
+ }
+
+ /**
+ * Returns the settings for the given section.
+ *
+ * @param sectionName the section name
+ * @return the settings
+ * @since 3.0
+ */
+ private IDialogSettings getSettings(String sectionName) {
+ IDialogSettings settings= RuntimePlugin.getInstance().getDialogSettings().getSection(sectionName);
+ if (settings == null)
+ settings= RuntimePlugin.getInstance().getDialogSettings().addNewSection(sectionName);
+ return settings;
+ }
+ }
+
+ private class PresentationDamager implements IPresentationDamager {
+ public IRegion getDamageRegion(ITypedRegion partition, DocumentEvent event, boolean documentPartitioningChanged) {
+ // Ask the language's token colorer how much of the document presentation needs to be recomputed.
+ final ITokenColorer tokenColorer= fLanguageServiceManager.getTokenColorer();
+
+ if (tokenColorer != null)
+ return tokenColorer.calculateDamageExtent(partition, fLanguageServiceManager.getParseController());
+ else
+ return partition;
+ }
+ public void setDocument(IDocument document) {}
+ }
+
+ private class PresentationRepairer implements IPresentationRepairer {
+ // For checking whether the damage region has changed
+ ITypedRegion previousDamage= null;
+
+ private final IProgressMonitor fProgressMonitor= new NullProgressMonitor();
+
+ public void createPresentation(TextPresentation presentation, ITypedRegion damage) {
+ boolean hyperlinkRestore= false;
+
+ // If the given damage region is the same as the previous one, assume it's due to removing a hyperlink decoration
+ if (previousDamage != null && damage.getOffset() == previousDamage.getOffset() && damage.getLength() == previousDamage.getLength()) {
+ hyperlinkRestore= true;
+ }
+
+ // BUG Should we really just ignore the presentation passed in???
+ // JavaDoc says we're responsible for "merging" our changes in...
+ try {
+ if (fServiceControllerManager.getPresentationController() != null) {
+// System.out.println("Scheduling repair for damage to region " + damage.getOffset() + ":" + damage.getLength() + " in doc of length " + fDocument.getLength());
+ fServiceControllerManager.getPresentationController().damage(damage);
+ if (hyperlinkRestore) {
+// System.out.println("** Forcing repair for hyperlink damage to region " + damage.getOffset() + ":" + damage.getLength() + " in doc of length " + fDocument.getLength());
+ fServiceControllerManager.getPresentationController().update(fLanguageServiceManager.getParseController(), fProgressMonitor);
+ }
+ }
+ } catch (Exception e) {
+ ErrorHandler.reportError("Could not repair damage ", e);
+ }
+ previousDamage= damage;
+ }
+
+ public void setDocument(IDocument document) { }
+ }
+
+ private IMessageHandler fAnnotationCreator= new AnnotationCreator(this, PARSE_ANNOTATION_TYPE);
+
+ private final IRegionSelectionService fRegionSelector= new IRegionSelectionService() {
+ public void selectAndReveal(int startOffset, int length) {
+ IEditorPart activeEditor= PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
+ AbstractTextEditor textEditor= (AbstractTextEditor) activeEditor;
+
+ textEditor.selectAndReveal(startOffset, length);
+ }
+ };
+
+ private EditorErrorTickUpdater fEditorErrorTickUpdater;
+
+ private class AnnotationCreatorListener implements IModelListener {
+ public AnalysisRequired getAnalysisRequired() {
+ return AnalysisRequired.NONE; // Even if it doesn't scan, it's ok - this posts the error annotations!
+ }
+ public void update(IParseController parseController, IProgressMonitor monitor) {
+ // SMS 25 Apr 2007
+ // Since parsing has finished, check whether the marker annotations
+ // are up-to-date with the most recent parse annotations.
+ // Assuming that's often enough--i.e., don't refresh the marker
+ // annotations after every update to the document annotation model
+ // since there will be many of these, including possibly many that
+ // don't relate to problem markers.
+ final IAnnotationTypeInfo annotationTypeInfo= fLanguageServiceManager.getParseController().getAnnotationTypeInfo();
+ if (annotationTypeInfo != null) {
+ List problemMarkerTypes = annotationTypeInfo.getProblemMarkerTypes();
+ for (int i = 0; i < problemMarkerTypes.size(); i++) {
+ refreshMarkerAnnotations((String)problemMarkerTypes.get(i));
+ }
+ }
+ }
+ }
+
+ public String getSelectionText() {
+ Point sel= getSelection();
+ IFileEditorInput fileEditorInput= (IFileEditorInput) getEditorInput();
+ IDocument document= getDocumentProvider().getDocument(fileEditorInput);
+
+ try {
+ return document.get(sel.x, sel.y);
+ } catch (BadLocationException e) {
+ e.printStackTrace();
+ return "";
+ }
+ }
+
+ public Point getSelection() {
+ ISelection sel= this.getSelectionProvider().getSelection();
+ ITextSelection textSel= (ITextSelection) sel;
+
+ return new Point(textSel.getOffset(), textSel.getLength());
+ }
+
+ public boolean canPerformFind() {
+ return true;
+ }
+
+ public IParseController getParseController() {
+ return fLanguageServiceManager.getParseController();
+ }
+
+ public IOccurrenceMarker getOccurrenceMarker() {
+ return fLanguageServiceManager.getOccurrenceMarker();
+ }
+
+ // SMS 4 May 2006:
+ // Added this as the only way I could think of (so far) to
+ // remove parser annotations that I expect to be duplicated
+ // if a save triggers a build that leads to the creation
+ // of markers and another set of annotations.
+ public void doSave(IProgressMonitor progressMonitor) {
+ // SMS 25 Apr 2007: Removing parser annotations here
+ // may not hurt but also doesn't seem to be necessary
+ //removeParserAnnotations();
+ super.doSave(progressMonitor);
+ }
+
+ public void removeParserAnnotations() {
+ IAnnotationModel model= getDocumentProvider().getAnnotationModel(getEditorInput());
+
+ for(Iterator i= model.getAnnotationIterator(); i.hasNext(); ) {
+ Annotation a= (Annotation) i.next();
+
+ if (a.getType().equals(PARSE_ANNOTATION_TYPE))
+ model.removeAnnotation(a);
+ }
+ }
+
+ public String toString() {
+ String langName= (fLanguage != null ? " for " + fLanguage.getName() : "");
+ String inputDesc= (fParserScheduler != null && fLanguageServiceManager.getParseController() != null && fLanguageServiceManager.getParseController().getPath() != null) ? "source " + fLanguageServiceManager.getParseController().getPath().toPortableString() : "";
+ return "Universal Editor" + langName + " on " + inputDesc + getEditorInput();
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/AbstractInformationControl.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/AbstractInformationControl.java
new file mode 100644
index 000000000..9e59cfc6b
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/AbstractInformationControl.java
@@ -0,0 +1,1064 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor.internal;
+
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IExecutionListener;
+import org.eclipse.core.commands.NotHandledException;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.imp.editor.ModelTreeNode;
+import org.eclipse.imp.editor.StringMatcher;
+import org.eclipse.imp.editor.UniversalEditor;
+import org.eclipse.imp.parser.ISourcePositionLocator;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.imp.runtime.PluginImages;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.bindings.keys.KeySequence;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlExtension;
+import org.eclipse.jface.text.IInformationControlExtension2;
+import org.eclipse.jface.text.IInformationControlExtension3;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.events.ShellAdapter;
+import org.eclipse.swt.events.ShellEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Item;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Layout;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+import org.eclipse.swt.widgets.Tracker;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IKeyBindingService;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.contexts.IContextService;
+import org.eclipse.ui.ide.IDE;
+
+/**
+ * Abstract class for Show hierarchy in light-weight controls.
+ */
+public abstract class AbstractInformationControl implements IInformationControl, IInformationControlExtension, IInformationControlExtension2,
+ IInformationControlExtension3, DisposeListener {
+
+ /**
+ * The NamePatternFilter selects the elements which
+ * match the given string patterns.
+ */
+ public class NamePatternFilter extends ViewerFilter {
+ public NamePatternFilter() {}
+
+ /* (non-Javadoc)
+ * Method declared on ViewerFilter.
+ */
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ StringMatcher matcher= getMatcher();
+ if (matcher == null || !(viewer instanceof TreeViewer))
+ return true;
+ TreeViewer treeViewer= (TreeViewer) viewer;
+ String matchName= ((ILabelProvider) treeViewer.getLabelProvider()).getText(element);
+ if (matchName != null && matcher.match(matchName))
+ return true;
+ return hasUnfilteredChild(treeViewer, element);
+ }
+
+ private boolean hasUnfilteredChild(TreeViewer viewer, Object element) {
+ Object[] children= ((ITreeContentProvider) viewer.getContentProvider()).getChildren(element);
+ for(int i= 0; i < children.length; i++)
+ if (select(viewer, element, children[i]))
+ return true;
+ return false;
+ }
+ }
+
+ private static class BorderFillLayout extends Layout {
+ /** The border widths. */
+ final int fBorderSize;
+
+ /**
+ * Creates a fill layout with a border.
+ *
+ * @param borderSize the border size
+ */
+ public BorderFillLayout(int borderSize) {
+ if (borderSize < 0)
+ throw new IllegalArgumentException();
+ fBorderSize= borderSize;
+ }
+
+ /**
+ * Returns the border size.
+ *
+ * @return the border size
+ */
+ public int getBorderSize() {
+ return fBorderSize;
+ }
+
+ /*
+ * @see org.eclipse.swt.widgets.Layout#computeSize(org.eclipse.swt.widgets.Composite, int, int, boolean)
+ */
+ protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
+ Control[] children= composite.getChildren();
+ Point minSize= new Point(0, 0);
+ if (children != null) {
+ for(int i= 0; i < children.length; i++) {
+ Point size= children[i].computeSize(wHint, hHint, flushCache);
+ minSize.x= Math.max(minSize.x, size.x);
+ minSize.y= Math.max(minSize.y, size.y);
+ }
+ }
+ minSize.x+= fBorderSize * 2 + RIGHT_MARGIN;
+ minSize.y+= fBorderSize * 2;
+ return minSize;
+ }
+
+ /*
+ * @see org.eclipse.swt.widgets.Layout#layout(org.eclipse.swt.widgets.Composite, boolean)
+ */
+ protected void layout(Composite composite, boolean flushCache) {
+ Control[] children= composite.getChildren();
+ Point minSize= new Point(composite.getClientArea().width, composite.getClientArea().height);
+ if (children != null) {
+ for(int i= 0; i < children.length; i++) {
+ Control child= children[i];
+ child.setSize(minSize.x - fBorderSize * 2, minSize.y - fBorderSize * 2);
+ child.setLocation(fBorderSize, fBorderSize);
+ }
+ }
+ }
+ }
+
+ /**
+ * The view menu's Remember Size and Location action.
+ */
+ private class RememberBoundsAction extends Action {
+ RememberBoundsAction() {
+ super("Remember Size and Location", IAction.AS_CHECK_BOX);
+ setChecked(!getDialogSettings().getBoolean(STORE_DISABLE_RESTORE_LOCATION));
+ }
+
+ /*
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ IDialogSettings settings= getDialogSettings();
+ boolean newValue= !isChecked();
+ // store new value
+ settings.put(STORE_DISABLE_RESTORE_LOCATION, newValue);
+ settings.put(STORE_DISABLE_RESTORE_SIZE, newValue);
+ fIsDecativateListenerActive= true;
+ }
+ }
+
+ /**
+ * The view menu's Resize action.
+ */
+ private class ResizeAction extends Action {
+ ResizeAction() {
+ super("Resize", IAction.AS_PUSH_BUTTON);
+ }
+
+ /*
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ Tracker tracker= new Tracker(fShell.getDisplay(), SWT.RESIZE);
+ tracker.setStippled(true);
+ Rectangle[] r= new Rectangle[] { getFilterText().getShell().getBounds() };
+ tracker.setRectangles(r);
+ if (tracker.open())
+ fShell.setBounds(tracker.getRectangles()[0]);
+ }
+ }
+
+ /**
+ * The view menu's Move action.
+ */
+ private class MoveAction extends Action {
+ MoveAction() {
+ super("Move", IAction.AS_PUSH_BUTTON);
+ }
+
+ /*
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ Tracker tracker= new Tracker(fShell.getDisplay(), SWT.NONE);
+ tracker.setStippled(true);
+ Rectangle[] r= new Rectangle[] { getFilterText().getShell().getBounds() };
+ tracker.setRectangles(r);
+ if (tracker.open())
+ fShell.setBounds(tracker.getRectangles()[0]);
+ }
+ }
+
+ /** Border thickness in pixels. */
+ private static final int BORDER= 1;
+ /** Right margin in pixels. */
+ private static final int RIGHT_MARGIN= 3;
+ /**
+ * Dialog constants telling whether this control can be resized or move.
+ */
+ private static final String STORE_DISABLE_RESTORE_SIZE= "DISABLE_RESTORE_SIZE"; //$NON-NLS-1$
+ private static final String STORE_DISABLE_RESTORE_LOCATION= "DISABLE_RESTORE_LOCATION"; //$NON-NLS-1$
+ /** The control's shell */
+ private Shell fShell;
+ /** The composite */
+ Composite fComposite;
+ /** The control's text widget */
+ private Text fFilterText;
+ /** The control's tree widget */
+ private TreeViewer fTreeViewer;
+ /** The current string matcher */
+ private StringMatcher fStringMatcher;
+ private Command fInvokingCommand;
+ private Label fStatusField;
+ private Font fStatusTextFont;
+ private KeySequence[] fInvokingCommandKeySequences;
+ /**
+ * Remembers the bounds for this information control.
+ * @since 3.0
+ */
+ private Rectangle fBounds;
+ private Rectangle fTrim;
+ /**
+ * Fields for view menu support.
+ * @since 3.0
+ */
+ private Button fViewMenuButton;
+ private ToolBar fToolBar;
+ private Composite fViewMenuButtonComposite;
+ private MenuManager fViewMenuManager;
+ private Listener fDeactivateListener;
+ private boolean fIsDecativateListenerActive= false;
+// private CustomFiltersActionGroup fCustomFiltersActionGroup;
+ private IKeyBindingService fKeyBindingService;
+ private String[] fKeyBindingScopes;
+ private IAction fShowViewMenuAction;
+ private IExecutionListener fShowViewMenuHandlerSubmission;
+
+ /**
+ * Creates a tree information control with the given shell as parent. The given
+ * styles are applied to the shell and the tree widget.
+ *
+ * @param parent the parent shell
+ * @param shellStyle the additional styles for the shell
+ * @param treeStyle the additional styles for the tree widget
+ * @param invokingCommandId the id of the command that invoked this control or <code>null</code>
+ * @param showStatusField <code>true</code> iff the control has a status field at the bottom
+ */
+ public AbstractInformationControl(Shell parent, int shellStyle, int treeStyle, String invokingCommandId, boolean showStatusField) {
+ if (invokingCommandId != null) {
+ ICommandService commandManager= (ICommandService) PlatformUI.getWorkbench().getAdapter(ICommandService.class);
+ fInvokingCommand= commandManager.getCommand(invokingCommandId);
+ if (fInvokingCommand != null && !fInvokingCommand.isDefined())
+ fInvokingCommand= null;
+ else {
+ // Pre-fetch key sequence - do not change because scope will change later.
+// getInvokingCommandKeySequences();
+ }
+ }
+ fShell= new Shell(parent, shellStyle);
+ Display display= fShell.getDisplay();
+ fShell.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
+ // Composite for filter text and tree
+ fComposite= new Composite(fShell, SWT.RESIZE);
+ GridLayout layout= new GridLayout(1, false);
+ fComposite.setLayout(layout);
+ fComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ fViewMenuButtonComposite= new Composite(fComposite, SWT.NONE);
+ layout= new GridLayout(2, false);
+ layout.marginHeight= 0;
+ layout.marginWidth= 0;
+ fViewMenuButtonComposite.setLayout(layout);
+ fViewMenuButtonComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ if (hasHeader()) {
+ createHeader(fViewMenuButtonComposite);
+ fFilterText= createFilterText(fComposite);
+ } else {
+ fFilterText= createFilterText(fViewMenuButtonComposite);
+ }
+ createViewMenu(fViewMenuButtonComposite);
+ createHorizontalSeparator(fComposite);
+ fTreeViewer= createTreeViewer(fComposite, treeStyle);
+// fCustomFiltersActionGroup= new CustomFiltersActionGroup(getId(), fTreeViewer);
+ if (showStatusField)
+ createStatusField(fComposite);
+ final Tree tree= fTreeViewer.getTree();
+ tree.addKeyListener(new KeyListener() {
+ public void keyPressed(KeyEvent e) {
+ if (e.character == 0x1B) // ESC
+ dispose();
+ }
+
+ public void keyReleased(KeyEvent e) {
+ // do nothing
+ }
+ });
+ tree.addSelectionListener(new SelectionListener() {
+ public void widgetSelected(SelectionEvent e) {
+ // do nothing
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ gotoSelectedElement();
+ }
+ });
+ tree.addMouseMoveListener(new MouseMoveListener() {
+ TreeItem fLastItem= null;
+
+ public void mouseMove(MouseEvent e) {
+ if (tree.equals(e.getSource())) {
+ Object o= tree.getItem(new Point(e.x, e.y));
+ if (o instanceof TreeItem) {
+ if (!o.equals(fLastItem)) {
+ fLastItem= (TreeItem) o;
+ tree.setSelection(new TreeItem[] { fLastItem });
+ } else if (e.y < tree.getItemHeight() / 4) {
+ // Scroll up
+ Point p= tree.toDisplay(e.x, e.y);
+ Item item= fTreeViewer.scrollUp(p.x, p.y);
+ if (item instanceof TreeItem) {
+ fLastItem= (TreeItem) item;
+ tree.setSelection(new TreeItem[] { fLastItem });
+ }
+ } else if (e.y > tree.getBounds().height - tree.getItemHeight() / 4) {
+ // Scroll down
+ Point p= tree.toDisplay(e.x, e.y);
+ Item item= fTreeViewer.scrollDown(p.x, p.y);
+ if (item instanceof TreeItem) {
+ fLastItem= (TreeItem) item;
+ tree.setSelection(new TreeItem[] { fLastItem });
+ }
+ }
+ }
+ }
+ }
+ });
+ tree.addMouseListener(new MouseAdapter() {
+ public void mouseUp(MouseEvent e) {
+ if (tree.getSelectionCount() < 1)
+ return;
+ if (e.button != 1)
+ return;
+ if (tree.equals(e.getSource())) {
+ Object o= tree.getItem(new Point(e.x, e.y));
+ TreeItem selection= tree.getSelection()[0];
+ if (selection.equals(o))
+ gotoSelectedElement();
+ }
+ }
+ });
+ int border= ((shellStyle & SWT.NO_TRIM) == 0) ? 0 : BORDER;
+ fShell.setLayout(new BorderFillLayout(border));
+ if (hasHeader()) {
+ fComposite.setTabList(new Control[] { fFilterText, fTreeViewer.getTree() });
+ } else {
+ fViewMenuButtonComposite.setTabList(new Control[] { fFilterText });
+ fComposite.setTabList(new Control[] { fViewMenuButtonComposite, fTreeViewer.getTree() });
+ }
+ setInfoSystemColor();
+ installFilter();
+ addDisposeListener(this);
+ fDeactivateListener= new Listener() {
+ /*
+ * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+ */
+ public void handleEvent(Event event) {
+ if (fIsDecativateListenerActive)
+ dispose();
+ }
+ };
+ fShell.addListener(SWT.Deactivate, fDeactivateListener);
+ fIsDecativateListenerActive= true;
+ fShell.addShellListener(new ShellAdapter() {
+ /*
+ * @see org.eclipse.swt.events.ShellAdapter#shellActivated(org.eclipse.swt.events.ShellEvent)
+ */
+ public void shellActivated(ShellEvent e) {
+ if (e.widget == fShell && fShell.getShells().length == 0)
+ fIsDecativateListenerActive= true;
+ }
+ });
+ fShell.addControlListener(new ControlAdapter() {
+ /**
+ * {@inheritDoc}
+ */
+ public void controlMoved(ControlEvent e) {
+ fBounds= fShell.getBounds();
+ if (fTrim != null) {
+ Point location= fComposite.getLocation();
+ fBounds.x= fBounds.x - fTrim.x + location.x;
+ fBounds.y= fBounds.y - fTrim.y + location.y;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void controlResized(ControlEvent e) {
+ fBounds= fShell.getBounds();
+ if (fTrim != null) {
+ Point location= fComposite.getLocation();
+ fBounds.x= fBounds.x - fTrim.x + location.x;
+ fBounds.y= fBounds.y - fTrim.y + location.y;
+ }
+ }
+ });
+ }
+
+ /**
+ * Creates a tree information control with the given shell as parent. The given
+ * styles are applied to the shell and the tree widget.
+ *
+ * @param parent the parent shell
+ * @param shellStyle the additional styles for the shell
+ * @param treeStyle the additional styles for the tree widget
+ */
+ public AbstractInformationControl(Shell parent, int shellStyle, int treeStyle) {
+ this(parent, shellStyle, treeStyle, null, false);
+ }
+
+ protected abstract TreeViewer createTreeViewer(Composite parent, int style);
+
+ /**
+ * Returns the name of the dialog settings section.
+ *
+ * @return the name of the dialog settings section
+ */
+ protected abstract String getId();
+
+ protected TreeViewer getTreeViewer() {
+ return fTreeViewer;
+ }
+
+ protected boolean hasHeader() {
+ // default is to have no header
+ return false;
+ }
+
+ /**
+ * Creates a header for this information control.
+ * <p>
+ * Note: The header is only be created if {@link #hasHeader()} returns <code>true</code>.
+ * </p>
+ *
+ * @param parent
+ */
+ protected void createHeader(Composite parent) {
+ // default is to have no header
+ }
+
+ protected Text getFilterText() {
+ return fFilterText;
+ }
+
+ protected Text createFilterText(Composite parent) {
+ fFilterText= new Text(parent, SWT.NONE);
+ GridData data= new GridData(GridData.FILL_HORIZONTAL);
+ GC gc= new GC(parent);
+ gc.setFont(parent.getFont());
+ FontMetrics fontMetrics= gc.getFontMetrics();
+ gc.dispose();
+ data.heightHint= Dialog.convertHeightInCharsToPixels(fontMetrics, 1);
+ data.horizontalAlignment= GridData.FILL;
+ data.verticalAlignment= GridData.CENTER;
+ fFilterText.setLayoutData(data);
+ fFilterText.addKeyListener(new KeyListener() {
+ public void keyPressed(KeyEvent e) {
+ if (e.keyCode == 0x0D) // return
+ gotoSelectedElement();
+ if (e.keyCode == SWT.ARROW_DOWN)
+ fTreeViewer.getTree().setFocus();
+ if (e.keyCode == SWT.ARROW_UP)
+ fTreeViewer.getTree().setFocus();
+ if (e.character == 0x1B) // ESC
+ dispose();
+ }
+
+ public void keyReleased(KeyEvent e) {
+ // do nothing
+ }
+ });
+ return fFilterText;
+ }
+
+ protected void createHorizontalSeparator(Composite parent) {
+ Label separator= new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.LINE_DOT);
+ separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ }
+
+ private void createViewMenu(Composite toolbar) {
+ fToolBar= new ToolBar(toolbar, SWT.FLAT);
+ ToolItem viewMenuButton= new ToolItem(fToolBar, SWT.PUSH, 0);
+ GridData data= new GridData();
+ data.horizontalAlignment= GridData.END;
+ data.verticalAlignment= GridData.BEGINNING;
+ fToolBar.setLayoutData(data);
+ viewMenuButton.setImage(PluginImages.get(PluginImages.VIEW_MENU_IMAGE));
+ viewMenuButton.setDisabledImage(PluginImages.get(PluginImages.VIEW_MENU_IMAGE));
+ viewMenuButton.setToolTipText("View Menu");
+ viewMenuButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ showViewMenu();
+ }
+ });
+ // Key binding service
+ IWorkbenchPart part= RuntimePlugin.getInstance().getWorkbench().getActiveWorkbenchWindow().getActivePage().getActivePart();
+ IWorkbenchPartSite site= part.getSite();
+ fKeyBindingService= site.getKeyBindingService();
+ // Remember current scope and then set window context.
+ fKeyBindingScopes= fKeyBindingService.getScopes();
+ fKeyBindingService.setScopes(new String[] { IContextService.CONTEXT_ID_WINDOW });
+ // Create show view menu action
+ fShowViewMenuAction= new Action("showViewMenu") { //$NON-NLS-1$
+ /*
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ showViewMenu();
+ }
+ };
+ fShowViewMenuAction.setEnabled(true);
+ fShowViewMenuAction.setActionDefinitionId("org.eclipse.ui.window.showViewMenu"); //$NON-NLS-1$
+ // Register action with command support
+ fShowViewMenuHandlerSubmission= new ExecutionListener(fShowViewMenuAction.getActionDefinitionId(), fShowViewMenuAction);
+ ((ICommandService) PlatformUI.getWorkbench().getAdapter(ICommandService.class)).addExecutionListener(fShowViewMenuHandlerSubmission);
+ }
+
+ private class ExecutionListener implements IExecutionListener {
+ private final String fCommandDefID;
+ private final IAction fAction;
+ public ExecutionListener(String cmdDefID, IAction action) {
+ fCommandDefID= cmdDefID;
+ fAction= action;
+ }
+ public void notHandled(String commandId, NotHandledException exception) { }
+ public void postExecuteFailure(String commandId, ExecutionException exception) { }
+ public void postExecuteSuccess(String commandId, Object returnValue) { }
+ public void preExecute(String commandId, ExecutionEvent event) {
+ fAction.run();
+ }
+ }
+
+ private MenuManager getViewMenuManager() {
+ if (fViewMenuManager == null) {
+ fViewMenuManager= new MenuManager();
+ fillViewMenu(fViewMenuManager);
+ }
+ return fViewMenuManager;
+ }
+
+ private void showViewMenu() {
+ fIsDecativateListenerActive= false;
+ Menu aMenu= getViewMenuManager().createContextMenu(fShell);
+ Rectangle bounds= fToolBar.getBounds();
+ Point topLeft= new Point(bounds.x, bounds.y + bounds.height);
+ topLeft= fShell.toDisplay(topLeft);
+ aMenu.setLocation(topLeft.x, topLeft.y);
+ aMenu.setVisible(true);
+ }
+
+ private void createStatusField(Composite parent) {
+ Composite composite= new Composite(parent, SWT.NONE);
+ GridLayout layout= new GridLayout(1, false);
+ layout.marginHeight= 0;
+ layout.marginWidth= 0;
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ // Horizontal separator line
+ Label separator= new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.LINE_DOT);
+ separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ // Status field label
+ fStatusField= new Label(parent, SWT.RIGHT);
+ fStatusField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ fStatusField.setText(getStatusFieldText());
+ Font font= fStatusField.getFont();
+ Display display= parent.getDisplay();
+ FontData[] fontDatas= font.getFontData();
+ for(int i= 0; i < fontDatas.length; i++)
+ fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10);
+ fStatusTextFont= new Font(display, fontDatas);
+ fStatusField.setFont(fStatusTextFont);
+ fStatusField.setForeground(display.getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW));
+ }
+
+ protected void updateStatusFieldText() {
+ if (fStatusField != null)
+ fStatusField.setText(getStatusFieldText());
+ }
+
+ /**
+ * Handles click in status field.
+ * <p>
+ * Default does nothing.
+ * </p>
+ */
+ protected void handleStatusFieldClicked() {}
+
+ protected String getStatusFieldText() {
+ return ""; //$NON-NLS-1$
+ }
+
+ private void setInfoSystemColor() {
+ Display display= fShell.getDisplay();
+ setForegroundColor(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
+ setBackgroundColor(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+ }
+
+ private void installFilter() {
+ fFilterText.setText(""); //$NON-NLS-1$
+ fFilterText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String text= ((Text) e.widget).getText();
+ int length= text.length();
+ if (length > 0 && text.charAt(length - 1) != '*') {
+ text= text + '*';
+ }
+ setMatcherString(text);
+ }
+ });
+ }
+
+ /**
+ * The string matcher has been modified. The default implementation
+ * refreshes the view and selects the first matched element
+ */
+ protected void stringMatcherUpdated() {
+ // refresh viewer to re-filter
+ fTreeViewer.getControl().setRedraw(false);
+ fTreeViewer.refresh();
+ fTreeViewer.expandAll();
+ selectFirstMatch();
+ fTreeViewer.getControl().setRedraw(true);
+ }
+
+ /**
+ * Sets the patterns to filter out for the receiver.
+ * <p>
+ * The following characters have special meaning:
+ * ? => any character
+ * * => any string
+ * </p>
+ *
+ * @param pattern the pattern
+ */
+ protected void setMatcherString(String pattern) {
+ if (pattern.length() == 0) {
+ fStringMatcher= null;
+ } else {
+ boolean ignoreCase= pattern.toLowerCase().equals(pattern);
+ fStringMatcher= new StringMatcher(pattern, ignoreCase, false);
+ }
+ stringMatcherUpdated();
+ }
+
+ protected StringMatcher getMatcher() {
+ return fStringMatcher;
+ }
+
+ /**
+ * Implementers can modify
+ *
+ * @return the selected element
+ */
+ protected Object getSelectedElement() {
+ if (fTreeViewer == null)
+ return null;
+ return ((IStructuredSelection) fTreeViewer.getSelection()).getFirstElement();
+ }
+
+ private void gotoSelectedElement() {
+ Object selectedElement= getSelectedElement();
+ if (selectedElement != null) {
+ try {
+ dispose();
+ if (selectedElement instanceof IFile)
+ openInEditor((IFile) selectedElement, true);
+ else {
+ IWorkbenchPage p= RuntimePlugin.getInstance().getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ IEditorPart editor= p.getActiveEditor();
+ UniversalEditor ue= (UniversalEditor) editor;
+ IParseController parseController= ue.getParseController();
+ ISourcePositionLocator locator= parseController.getSourcePositionLocator();
+ Object element= selectedElement;
+
+ if (element instanceof ModelTreeNode)
+ element= ((ModelTreeNode) selectedElement).getASTNode();
+ ue.selectAndReveal(locator.getStartOffset(element), 0 /*pos.length*/);
+ }
+ } catch (CoreException ex) {
+ RuntimePlugin.getInstance().writeErrorMsg(ex.getMessage());
+ }
+ }
+ }
+
+ private static IEditorPart openInEditor(IFile file, boolean activate) throws PartInitException {
+ if (file != null) {
+ IWorkbenchPage p= RuntimePlugin.getInstance().getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ if (p != null) {
+ IEditorPart editorPart= IDE.openEditor(p, file, activate);
+// initializeHighlightRange(editorPart);
+ return editorPart;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Selects the first element in the tree which
+ * matches the current filter pattern.
+ */
+ protected void selectFirstMatch() {
+ Tree tree= fTreeViewer.getTree();
+ Object element= findElement(tree.getItems());
+ if (element != null)
+ fTreeViewer.setSelection(new StructuredSelection(element), true);
+ else
+ fTreeViewer.setSelection(StructuredSelection.EMPTY);
+ }
+
+ private Object findElement(TreeItem[] items) {
+ ILabelProvider labelProvider= (ILabelProvider) fTreeViewer.getLabelProvider();
+ for(int i= 0; i < items.length; i++) {
+ Object element= items[i].getData();
+ if (fStringMatcher == null)
+ return element;
+ if (element != null) {
+ String label= labelProvider.getText(element);
+ if (fStringMatcher.match(label))
+ return element;
+ }
+ element= findElement(items[i].getItems());
+ if (element != null)
+ return element;
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setInformation(String information) {
+ // this method is ignored, see IInformationControlExtension2
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public abstract void setInput(Object information);
+
+ /**
+ * Fills the view menu.
+ * Clients can extend or override.
+ *
+ * @param viewMenu the menu manager that manages the menu
+ * @since 3.0
+ */
+ protected void fillViewMenu(IMenuManager viewMenu) {
+ viewMenu.add(new GroupMarker("SystemMenuStart")); //$NON-NLS-1$
+ viewMenu.add(new MoveAction());
+ viewMenu.add(new ResizeAction());
+ viewMenu.add(new RememberBoundsAction());
+ viewMenu.add(new Separator("SystemMenuEnd")); //$NON-NLS-1$
+// if (fCustomFiltersActionGroup != null)
+// fCustomFiltersActionGroup.fillViewMenu(viewMenu);
+ }
+
+ protected void inputChanged(Object newInput, Object newSelection) {
+ fFilterText.setText(""); //$NON-NLS-1$
+ fTreeViewer.setInput(newInput);
+ if (newSelection != null) {
+ fTreeViewer.setSelection(new StructuredSelection(newSelection));
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setVisible(boolean visible) {
+ if (visible || fIsDecativateListenerActive)
+ fShell.setVisible(visible);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void dispose() {
+ if (fShell != null && !fShell.isDisposed())
+ fShell.dispose();
+ else
+ widgetDisposed(null);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param event can be null
+ * <p>
+ * Subclasses may extend.
+ * </p>
+ */
+ public void widgetDisposed(DisposeEvent event) {
+ if (fStatusTextFont != null && !fStatusTextFont.isDisposed())
+ fStatusTextFont.dispose();
+ fShell= null;
+ fTreeViewer= null;
+ fComposite= null;
+ fFilterText= null;
+ fStatusTextFont= null;
+ // Remove handler submission
+ ((ICommandService) PlatformUI.getWorkbench().getAdapter(ICommandService.class)).removeExecutionListener(fShowViewMenuHandlerSubmission);
+ // Restore editor's key binding scope
+ if (fKeyBindingScopes != null && fKeyBindingService != null) {
+ fKeyBindingService.setScopes(fKeyBindingScopes);
+ fKeyBindingScopes= null;
+ fKeyBindingService= null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasContents() {
+ return fTreeViewer != null && fTreeViewer.getInput() != null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setSizeConstraints(int maxWidth, int maxHeight) {
+ if (maxWidth > -1 && maxHeight > -1) {
+ GridData gd= new GridData(GridData.FILL_BOTH);
+ if (maxWidth > -1)
+ gd.widthHint= maxWidth;
+ if (maxHeight > -1)
+ gd.heightHint= maxHeight;
+ fShell.setLayoutData(gd);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Point computeSizeHint() {
+ return fShell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @since 3.0
+ */
+ public Rectangle getBounds() {
+ return fBounds;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IInformationControlExtension3#restoresLocation()
+ */
+ public boolean restoresLocation() {
+ return !getDialogSettings().getBoolean(STORE_DISABLE_RESTORE_LOCATION);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IInformationControlExtension3#restoresSize()
+ */
+ public boolean restoresSize() {
+ return !getDialogSettings().getBoolean(STORE_DISABLE_RESTORE_SIZE);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IInformationControlExtension3#computeTrim()
+ */
+ public Rectangle computeTrim() {
+ if (fTrim != null)
+ return fTrim;
+ return new Rectangle(0, 0, 0, 0);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setLocation(Point location) {
+ fTrim= fShell.computeTrim(0, 0, 0, 0);
+ Point compositeLocation= fComposite.getLocation();
+ location.x+= fTrim.x - compositeLocation.x;
+ location.y+= fTrim.y - compositeLocation.y;
+ fShell.setLocation(location);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setSize(int width, int height) {
+ fShell.setSize(width, height);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addDisposeListener(DisposeListener listener) {
+ fShell.addDisposeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removeDisposeListener(DisposeListener listener) {
+ fShell.removeDisposeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setForegroundColor(Color foreground) {
+ fTreeViewer.getTree().setForeground(foreground);
+ fFilterText.setForeground(foreground);
+ fComposite.setForeground(foreground);
+ fViewMenuButtonComposite.setForeground(foreground);
+ if (fStatusField != null)
+ fStatusField.getParent().setForeground(foreground);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setBackgroundColor(Color background) {
+ fTreeViewer.getTree().setBackground(background);
+ fFilterText.setBackground(background);
+ fComposite.setBackground(background);
+ fViewMenuButtonComposite.setBackground(background);
+ if (fStatusField != null) {
+ fStatusField.setBackground(background);
+ fStatusField.getParent().setBackground(background);
+ }
+ if (fViewMenuButton != null)
+ fViewMenuButton.setBackground(background);
+ if (fToolBar != null)
+ fToolBar.setBackground(background);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isFocusControl() {
+ return fTreeViewer.getControl().isFocusControl() || fFilterText.isFocusControl();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setFocus() {
+ fShell.forceFocus();
+ fFilterText.setFocus();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addFocusListener(FocusListener listener) {
+ fShell.addFocusListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removeFocusListener(FocusListener listener) {
+ fShell.removeFocusListener(listener);
+ }
+
+ final protected Command getInvokingCommand() {
+ return fInvokingCommand;
+ }
+
+ // RMF 6/1/2006 - don't know how to do this without using deprecated API, so disabled for now...
+// final protected KeySequence[] getInvokingCommandKeySequences() {
+// if (fInvokingCommandKeySequences == null) {
+// if (getInvokingCommand() != null) {
+// List list= getInvokingCommand().getKeySequenceBindings();
+// if (!list.isEmpty()) {
+// fInvokingCommandKeySequences= new KeySequence[list.size()];
+// for(int i= 0; i < fInvokingCommandKeySequences.length; i++) {
+// fInvokingCommandKeySequences[i]= ((IKeySequenceBinding) list.get(i)).getKeySequence();
+// }
+// return fInvokingCommandKeySequences;
+// }
+// }
+// }
+// return fInvokingCommandKeySequences;
+// }
+
+ protected IDialogSettings getDialogSettings() {
+ String sectionName= getId();
+ IDialogSettings settings= RuntimePlugin.getInstance().getDialogSettings().getSection(sectionName);
+ if (settings == null)
+ settings= RuntimePlugin.getInstance().getDialogSettings().addNewSection(sectionName);
+ return settings;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/AnnotationCreator.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/AnnotationCreator.java
new file mode 100644
index 000000000..eb524c7fc
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/AnnotationCreator.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor.internal;
+
+import java.util.Iterator;
+
+import org.eclipse.imp.editor.UniversalEditor;
+import org.eclipse.imp.parser.IMessageHandler;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+public class AnnotationCreator implements IMessageHandler {
+ private final ITextEditor fEditor;
+ private final String fAnnotationType;
+
+ public AnnotationCreator(ITextEditor textEditor, String annotationType) {
+ fEditor= textEditor;
+ if (annotationType == null)
+ fAnnotationType = UniversalEditor.PARSE_ANNOTATION_TYPE;
+ else
+ fAnnotationType= annotationType;
+ }
+
+ public void startMessageGroup(String groupName) { }
+ public void endMessageGroup() { }
+
+ public void handleSimpleMessage(String message, int startOffset, int endOffset,
+ int startCol, int endCol,
+ int startLine, int endLine) {
+
+// public void handleMessage(int errorCode, int [] msgLocation, int[] errorLocation, String filename, String [] errorInfo) {
+// int offset = msgLocation[IMessageHandler.OFFSET_INDEX],
+// length = msgLocation[IMessageHandler.LENGTH_INDEX];
+// String message = "";
+// if (errorCode != ParseErrorCodes.DELETION_CODE &&
+// errorCode != ParseErrorCodes.MISPLACED_CODE)
+// {
+// for (int i = 0; i < errorInfo.length; i++)
+// message += errorInfo[i] + " ";
+// }
+// message += ParseErrorCodes.errorMsgText[errorCode];
+
+ IAnnotationModel model= fEditor.getDocumentProvider().getAnnotationModel(fEditor.getEditorInput());
+ Annotation annotation= new Annotation(fAnnotationType, false, message);
+
+ Position pos= new Position(startOffset, endOffset - startOffset + 1);
+
+ model.addAnnotation(annotation, pos);
+ }
+
+ public void removeAnnotations() {
+ final IDocumentProvider docProvider= fEditor.getDocumentProvider();
+
+ if (docProvider == null) {
+ return;
+ }
+
+ IAnnotationModel model= docProvider.getAnnotationModel(fEditor.getEditorInput());
+
+ if (model == null)
+ return;
+
+ for(Iterator i= model.getAnnotationIterator(); i.hasNext();) {
+ Annotation a= (Annotation) i.next();
+
+ if (a.getType().equals(fAnnotationType))
+ model.removeAnnotation(a);
+ }
+ }
+
+ public void clearMessages() {
+ removeAnnotations();
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/CompletionProcessor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/CompletionProcessor.java
new file mode 100644
index 000000000..1caa1b387
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/CompletionProcessor.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor.internal;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.imp.core.ErrorHandler;
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.language.ServiceFactory;
+import org.eclipse.imp.parser.IModelListener;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.services.IContentProposer;
+import org.eclipse.jface.text.ITextViewer;
+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;
+
+public class CompletionProcessor implements IContentAssistProcessor, IModelListener {
+ private final IContextInformation[] NO_CONTEXTS= new IContextInformation[0];
+
+ private ICompletionProposal[] NO_COMPLETIONS= new ICompletionProposal[0];
+
+ private IParseController parseController;
+
+ private final Language fLanguage;
+
+ private IContentProposer contentProposer;
+
+ // private HippieProposalProcessor hippieProcessor= new HippieProposalProcessor();
+
+ public CompletionProcessor(Language language) {
+ contentProposer= ServiceFactory.getInstance().getContentProposer(language);
+ fLanguage= language;
+ }
+
+ public AnalysisRequired getAnalysisRequired() {
+ return AnalysisRequired.LEXICAL_ANALYSIS;
+ }
+
+ public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
+ try {
+ if (parseController != null && contentProposer != null) {
+ return contentProposer.getContentProposals(parseController, offset, viewer);
+ }
+ // TODO Once we move to 3.2, delegate to the HippieProposalProcessor
+ // return hippieProcessor.computeCompletionProposals(viewer, offset);
+ } catch (Throwable e) {
+ ErrorHandler.reportError("Exception caught from language-specific content proposer implementation", e);
+ }
+ return NO_COMPLETIONS;
+ }
+
+ public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
+ return NO_CONTEXTS;
+ }
+
+ public char[] getCompletionProposalAutoActivationCharacters() {
+ return null;
+ }
+
+ public char[] getContextInformationAutoActivationCharacters() {
+ return null;
+ }
+
+ public IContextInformationValidator getContextInformationValidator() {
+ return null;
+ }
+
+ public String getErrorMessage() {
+ return null;
+ }
+
+ public void update(IParseController parseController, IProgressMonitor monitor) {
+ this.parseController= parseController;
+ }
+
+ public String toString() {
+ return "Completion processor for " + fLanguage.getName() + " on " + parseController.getPath().toPortableString();
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/EditorErrorTickUpdater.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/EditorErrorTickUpdater.java
new file mode 100644
index 000000000..a29dc0e17
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/EditorErrorTickUpdater.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor.internal;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.imp.editor.IProblemChangedListener;
+import org.eclipse.imp.editor.UniversalEditor;
+import org.eclipse.imp.language.ServiceFactory;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IFileEditorInput;
+
+/**
+ * @author Dr. Robert M. Fuhrer
+ */
+public class EditorErrorTickUpdater implements IProblemChangedListener {
+ private UniversalEditor fEditor;
+
+ private ILabelProvider fLabelProvider;
+
+ public EditorErrorTickUpdater(UniversalEditor editor) {
+ Assert.isNotNull(editor);
+ fEditor= editor;
+ fLabelProvider= ServiceFactory.getInstance().getLabelProvider(editor.fLanguage);
+// fLabelProvider.addLabelDecorator(new ProblemsLabelDecorator(null));
+ fEditor.getProblemMarkerManager().addListener(this);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see IProblemChangedListener#problemsChanged(IResource[], boolean)
+ */
+ public void problemsChanged(IResource[] changedResources, boolean isMarkerChange) {
+ if (!isMarkerChange)
+ return;
+
+ IEditorInput input= fEditor.getEditorInput();
+
+ if (input != null) { // might run async, tests needed
+ if (!(input instanceof IFileEditorInput)) // The editor might be looking at something outside the workspace (e.g. system include files).
+ return;
+
+ IFileEditorInput fileInput= (IFileEditorInput) input;
+ IFile file= fileInput.getFile();
+
+ if (file != null) {
+ for(int i= 0; i < changedResources.length; i++) {
+ if (changedResources[i].equals(file)) {
+ updateEditorImage(file);
+ }
+ }
+ }
+ }
+ }
+
+ public void updateEditorImage(IFile file) {
+ Image titleImage= fEditor.getTitleImage();
+ if (titleImage == null) {
+ return;
+ }
+
+ // SMS 9 Aug 2006
+ // fLabelProvider may be null, so check for that
+ if (fLabelProvider == null) {
+ return;
+ }
+
+ Image newImage= fLabelProvider.getImage(file);
+ if (titleImage != newImage) {
+ postImageChange(newImage);
+ }
+ }
+
+ private void postImageChange(final Image newImage) {
+ Shell shell= fEditor.getEditorSite().getShell();
+ if (shell != null && !shell.isDisposed()) {
+ shell.getDisplay().syncExec(new Runnable() {
+ public void run() {
+ fEditor.updatedTitleImage(newImage);
+ }
+ });
+ }
+ }
+
+ public void dispose() {
+ // SMS 9 Aug 2006
+ // as noted above, fLabelProvoider may be referenced when null,
+ // so I've added a guard here for that condition
+ if (fLabelProvider != null) {
+ fLabelProvider.dispose();
+ }
+ fEditor.getProblemMarkerManager().removeListener(this);
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/FoldingController.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/FoldingController.java
new file mode 100644
index 000000000..feebf14ec
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/FoldingController.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor.internal;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.imp.parser.IModelListener;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.imp.services.IFoldingUpdater;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
+
+public class FoldingController implements IModelListener {
+ private final ProjectionAnnotationModel fAnnotationModel;
+ private final IFoldingUpdater fFoldingUpdater;
+
+ public FoldingController(ProjectionAnnotationModel annotationModel, IFoldingUpdater foldingUpdater) {
+ super();
+ this.fAnnotationModel= annotationModel;
+ this.fFoldingUpdater= foldingUpdater;
+ }
+
+ public AnalysisRequired getAnalysisRequired() {
+ return AnalysisRequired.SYNTACTIC_ANALYSIS;
+ }
+
+ public void update(IParseController parseController, IProgressMonitor monitor) {
+ if (fAnnotationModel != null) { // can be null if file is outside workspace
+ try {
+ fFoldingUpdater.updateFoldingStructure(parseController, fAnnotationModel);
+ } catch (Exception e) {
+ RuntimePlugin.getInstance().logException("Error while updating folding annotations for " + parseController.getPath(), e);
+ }
+ }
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/FormattingController.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/FormattingController.java
new file mode 100644
index 000000000..7591b1203
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/FormattingController.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor.internal;
+
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.services.ISourceFormatter;
+import org.eclipse.jface.text.formatter.IFormattingStrategy;
+
+/**
+ * A controller interposed between the Eclipse text framework's IFormattingStrategy
+ * and the language-specific formatter, so that the latter can get its hands on an
+ * IParseController (and therefore an AST), to drive the formatting decisions.
+ * @author Dr. Robert M. Fuhrer
+ */
+public class FormattingController implements IFormattingStrategy {
+ private IParseController fParseController;
+
+ private final ISourceFormatter fFormattingStrategy;
+
+ public FormattingController(ISourceFormatter formattingStrategy) {
+ super();
+ fFormattingStrategy= formattingStrategy;
+ }
+
+ public void formatterStarts(String initialIndentation) {
+ fFormattingStrategy.formatterStarts(initialIndentation);
+ }
+
+ public String format(String content, boolean isLineStart, String indentation, int[] positions) {
+ return fFormattingStrategy.format(fParseController, content, isLineStart, indentation, positions);
+ }
+
+ public void formatterStops() {
+ fFormattingStrategy.formatterStops();
+ }
+
+ public void setParseController(IParseController parseController) {
+ fParseController= parseController;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/HoverHelpController.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/HoverHelpController.java
new file mode 100644
index 000000000..66de7b64c
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/HoverHelpController.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+ *******************************************************************************/
+
+package org.eclipse.imp.editor.internal;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.imp.core.ErrorHandler;
+import org.eclipse.imp.editor.HoverHelper;
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.language.ServiceFactory;
+import org.eclipse.imp.parser.IModelListener;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.services.IHoverHelper;
+import org.eclipse.imp.services.base.HoverHelperBase;
+import org.eclipse.imp.utils.AnnotationUtils;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.source.ISourceViewer;
+
+public class HoverHelpController implements ITextHover, IModelListener {
+ private IParseController controller;
+
+ private IHoverHelper hoverHelper;
+
+ public HoverHelpController(Language language) {
+ hoverHelper= ServiceFactory.getInstance().getHoverHelper(language);
+ if (hoverHelper == null)
+ hoverHelper= new HoverHelper(language);
+ else if (hoverHelper instanceof HoverHelperBase) {
+ ((HoverHelperBase) hoverHelper).setLanguage(language);
+ }
+ }
+
+ public AnalysisRequired getAnalysisRequired() {
+ return AnalysisRequired.NAME_ANALYSIS;
+ }
+
+ public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+ return new Region(offset, 0);
+ }
+
+ public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
+ try {
+ final int offset= hoverRegion.getOffset();
+ String help= null;
+
+ if (controller != null && hoverHelper != null)
+ help= hoverHelper.getHoverHelpAt(controller, (ISourceViewer) textViewer, offset);
+ if (help == null)
+ help= AnnotationUtils.formatAnnotationList(AnnotationUtils.getAnnotationsForOffset((ISourceViewer) textViewer, offset));
+
+ return help;
+ } catch (Throwable e) {
+ ErrorHandler.reportError("Universal Editor Error", e);
+ }
+ return null;
+ }
+
+ public void update(IParseController controller, IProgressMonitor monitor) {
+ this.controller= controller;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/ImageDecoratorController.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/ImageDecoratorController.java
new file mode 100644
index 000000000..4c2bd0dd2
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/ImageDecoratorController.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+* Copyright (c) 2009 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+package org.eclipse.imp.editor.internal;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.imp.editor.SourceEntityImageDescriptor;
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.language.ServiceFactory;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.imp.services.DecorationDescriptor;
+import org.eclipse.imp.services.IEntityImageDecorator;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * This class manages the language's <code>IEntityImageDecorator</code> service, if any.
+ * If none is defined, this controller provides support for error/warning decorations
+ * for resources.
+ * @author rfuhrer@watson.ibm.com
+ */
+public class ImageDecoratorController {
+ /**
+ * Flag to render the warning decoration. Must be distinct from all language-specific
+ * decoration attribute values.
+ */
+ public final static int WARNING= 1 << 0;
+
+ /**
+ * Flag to render the error decoration. Must be distinct from all language-specific
+ * decoration attribute values.
+ */
+ public final static int ERROR= 1 << 1;
+
+ public final static DecorationDescriptor WARNING_DECORATION= new DecorationDescriptor(WARNING, RuntimePlugin.getInstance().getBundle(), "icons/warning_co.gif", DecorationDescriptor.Quadrant.BOTTOM_LEFT);
+
+ public final static DecorationDescriptor ERROR_DECORATION= new DecorationDescriptor(ERROR, RuntimePlugin.getInstance().getBundle(), "icons/error_co.gif", DecorationDescriptor.Quadrant.BOTTOM_LEFT);
+
+ private final IEntityImageDecorator fDecorator;
+
+ private final List<DecorationDescriptor> topLeftDecorations= new LinkedList<DecorationDescriptor>();
+ private final List<DecorationDescriptor> topRightDecorations= new LinkedList<DecorationDescriptor>();
+ private final List<DecorationDescriptor> bottomLeftDecorations= new LinkedList<DecorationDescriptor>();
+ private final List<DecorationDescriptor> bottomRightDecorations= new LinkedList<DecorationDescriptor>();
+
+ public ImageDecoratorController(Language lang) {
+ fDecorator= ServiceFactory.getInstance().getEntityImageDecorator(lang);
+
+ if (fDecorator != null) {
+ DecorationDescriptor[] allDescs= fDecorator.getAllDecorations();
+
+ for(int i= 0; i < allDescs.length; i++) {
+ DecorationDescriptor desc= allDescs[i];
+ if (desc.quadrant == DecorationDescriptor.Quadrant.BOTTOM_LEFT) {
+ bottomLeftDecorations.add(desc);
+ } else if (desc.quadrant == DecorationDescriptor.Quadrant.BOTTOM_RIGHT) {
+ bottomRightDecorations.add(desc);
+ } else if (desc.quadrant == DecorationDescriptor.Quadrant.TOP_LEFT) {
+ topLeftDecorations.add(desc);
+ } else if (desc.quadrant == DecorationDescriptor.Quadrant.TOP_RIGHT) {
+ topRightDecorations.add(desc);
+ }
+ }
+ }
+ bottomRightDecorations.add(WARNING_DECORATION);
+ bottomRightDecorations.add(ERROR_DECORATION);
+ }
+
+ public SourceEntityImageDescriptor getImageDescriptor(ImageDescriptor baseImage, Object entity, Point size) {
+ int attrs= fDecorator.getDecorationAttributes(entity);
+ return new SourceEntityImageDescriptor(baseImage, attrs, size, this);
+ }
+
+ public List<DecorationDescriptor> getBottomLeftDecorations() {
+ return bottomLeftDecorations;
+ }
+
+ public List<DecorationDescriptor> getBottomRightDecorations() {
+ return bottomRightDecorations;
+ }
+
+ public List<DecorationDescriptor> getTopLeftDecorations() {
+ return topLeftDecorations;
+ }
+
+ public List<DecorationDescriptor> getTopRightDecorations() {
+ return topRightDecorations;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/OutlineController.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/OutlineController.java
new file mode 100644
index 000000000..776c833de
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/OutlineController.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor.internal;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.imp.core.ErrorHandler;
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.language.ServiceFactory;
+import org.eclipse.imp.parser.IModelListener;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.services.IOutliner;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.progress.UIJob;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+
+/*
+ * Licensed Materials - Property of IBM,
+ * (c) Copyright IBM Corp. 2005 All Rights Reserved
+ */
+
+/**
+ * @author Claffra
+ * @deprecated This class is no longer needed; the IMP outline view is
+ * now produced using a TreeModelBuilder, if one is available for the
+ * given language.
+ */
+public class OutlineController implements IContentOutlinePage, IModelListener {
+ protected Tree tree;
+
+ private IParseController controller;
+
+ private IOutliner outliner;
+
+ private UIJob job;
+
+ private int DELAY= 50; //500;
+
+ public OutlineController(ITextEditor editor, Language language) {
+ outliner = ServiceFactory.getInstance().getOutliner(language);
+ if (outliner != null) {
+ outliner.setEditor(editor); // SMS 5 Apr 2007
+ }
+ }
+
+ public AnalysisRequired getAnalysisRequired() {
+ return AnalysisRequired.SYNTACTIC_ANALYSIS;
+ }
+
+ public void createControl(Composite parent) {
+ tree= new Tree(parent, SWT.NONE);
+ if (outliner != null)
+ outliner.setTree(tree);
+ }
+
+ public void dispose() {}
+
+ public Control getControl() {
+ return tree;
+ }
+
+ public void setActionBars(IActionBars actionBars) {}
+
+ public void setFocus() {}
+
+ public void addSelectionChangedListener(ISelectionChangedListener listener) {}
+
+ public ISelection getSelection() {
+ return null;
+ }
+
+ public void removeSelectionChangedListener(ISelectionChangedListener listener) {}
+
+ public void setSelection(ISelection selection) {}
+
+ public void update(IParseController result, IProgressMonitor monitor) {
+ // TODO RMF 10/18/2006: Shouldn't even create this controller if we have no
+ // language-specific outliner, but UniversalEditor doesn't know that when it
+ // instantiates this class... What to do?
+ if (outliner == null)
+ return;
+
+ this.controller= result;
+ if (job != null) {
+ job.cancel();
+ }
+ else {
+ job= new UIJob("Outline View Controller" + result.toString()) {
+ public IStatus runInUIThread(IProgressMonitor monitor) {
+ int offset= 0;
+ try {
+ outliner.createOutlinePresentation(controller, offset);
+ } catch (Throwable e) {
+ ErrorHandler.reportError("Outline View Controller", e);
+ }
+ return Status.OK_STATUS;
+ }
+ };
+
+ } // else
+ job.schedule(DELAY);
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/PresentationController.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/PresentationController.java
new file mode 100644
index 000000000..17f35fcba
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/PresentationController.java
@@ -0,0 +1,362 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.editor.internal;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Stack;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.imp.core.ErrorHandler;
+import org.eclipse.imp.editor.LanguageServiceManager;
+import org.eclipse.imp.parser.IModelListener;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.parser.ISourcePositionLocator;
+import org.eclipse.imp.preferences.PreferenceCache;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.imp.services.ITokenColorer;
+import org.eclipse.imp.utils.ConsoleUtil;
+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.TextAttribute;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * A class that does the real work of repairing the text presentation for an associated ISourceViewer.
+ * Calls to damage(IRegion) simply accumulate damaged regions into a work queue, which is processed
+ * at the subsequent call to update(IParseController, IProgressMonitor).
+ * @author Claffra
+ * @author rfuhrer@watson.ibm.com
+ */
+public class PresentationController implements IModelListener {
+ public static final String CONSOLE_NAME= "Source Tokens";
+
+ private final ISourceViewer fSourceViewer;
+
+ private final ITokenColorer fColorer;
+
+ private final IParseController fParseCtlr;
+
+ private final Stack<IRegion> fWorkItems= new Stack<IRegion>();
+
+ public PresentationController(ISourceViewer sourceViewer, LanguageServiceManager langServiceMgr) {
+ fSourceViewer= sourceViewer;
+ this.fParseCtlr= langServiceMgr.getParseController();
+ fColorer= langServiceMgr.getTokenColorer();
+ }
+
+ public AnalysisRequired getAnalysisRequired() {
+ return AnalysisRequired.LEXICAL_ANALYSIS;
+ }
+
+ private void dumpToken(Object token, ISourcePositionLocator locator, PrintStream ps) {
+ if (locator != null) {
+ try {
+ final IDocument document= fSourceViewer.getDocument();
+ final int startOffset= locator.getStartOffset(token);
+// ps.print( " (" + prs.getKind(i) + ")");
+ ps.print(" \t" + startOffset);
+ ps.print(" \t" + locator.getLength(token));
+ int line = document.getLineOfOffset(startOffset);
+ ps.print(" \t" + line);
+ ps.print(" \t" + (startOffset - document.getLineOffset(line)));
+ } catch (BadLocationException e) {
+ RuntimePlugin.getInstance().logException("Error computing position of token", e);
+ }
+ }
+ ps.print(" \t" + token);
+ ps.println();
+ }
+
+ private void dumpTokens(Iterator<Object> tokenIter, PrintStream ps) {
+ ISourcePositionLocator locator = fParseCtlr.getSourcePositionLocator();
+
+ if (locator != null) {
+ ps.println(" Offset \tLen \tLine \tCol \tText");
+ } else {
+ ps.println(" Text");
+ }
+ for(; tokenIter.hasNext(); ) {
+ dumpToken(tokenIter.next(), locator, ps);
+ }
+ }
+
+ /**
+ * Push the damaged area onto the work queue for repair when we get scheduled to process the queue.
+ * @param region the damaged area
+ */
+ public void damage(IRegion region) {
+ if (fColorer == null)
+ return;
+
+ IRegion bigRegion= fColorer.calculateDamageExtent(region, fParseCtlr);
+
+ if (bigRegion != null) {
+ fWorkItems.push(bigRegion);
+ }
+ }
+
+ public void update(IParseController controller, IProgressMonitor monitor) {
+ if (!monitor.isCanceled()) {
+// if (fWorkItems.size() == 0) {
+// ConsoleUtil.findConsoleStream(PresentationController.CONSOLE_NAME).println("PresentationController.update() called, but no damage in the work queue?");
+// }
+ synchronized (fWorkItems) {
+ for(int n= fWorkItems.size() - 1; !monitor.isCanceled() && n >= 0; n--) {
+ Region damage= (Region) fWorkItems.get(n);
+ changeTextPresentationForRegion(controller, monitor, damage);
+ }
+ if (!monitor.isCanceled())
+ fWorkItems.removeAllElements();
+ }
+ }
+ }
+
+ private void changeTextPresentationForRegion(IParseController parseController, IProgressMonitor monitor, IRegion damage) {
+ if (parseController == null) {
+ return;
+ }
+ if (PreferenceCache.dumpTokens) { // RuntimePlugin.getPreferencesService().getBooleanPreference(PreferenceConstants.P_DUMP_TOKENS)
+ PrintStream ps= ConsoleUtil.findConsoleStream(PresentationController.CONSOLE_NAME);
+
+ dumpTokens(parseController.getTokenIterator(damage), ps);
+ }
+
+ final TextPresentation presentation= new TextPresentation();
+ ISourcePositionLocator locator= parseController.getSourcePositionLocator();
+
+ aggregateTextPresentation(parseController, monitor, damage, presentation, locator);
+ if (!monitor.isCanceled() && !presentation.isEmpty()) {
+ submitTextPresentation(presentation);
+ }
+ }
+
+ private void aggregateTextPresentation(IParseController parseController, IProgressMonitor monitor, IRegion damage, TextPresentation presentation,
+ ISourcePositionLocator locator) {
+ int prevOffset= -1;
+ int prevEnd= -1;
+ for(Iterator<Object> iter= parseController.getTokenIterator(damage); iter.hasNext() && !monitor.isCanceled(); ) {
+ Object token= iter.next();
+ int offset= locator.getStartOffset(token);
+ int end= locator.getEndOffset(token);
+
+ if (offset <= prevEnd && end >= prevOffset) {
+ continue;
+ }
+ else {
+ TextAttribute attribute= fColorer.getColoring(parseController, token);
+ if (attribute != null) {
+ changeTokenPresentation(parseController, presentation, offset, attribute, end);
+ }
+ }
+ prevOffset= offset;
+ prevEnd= end;
+ }
+ }
+
+ private void changeTokenPresentation(IParseController controller, TextPresentation presentation, int startOffset, TextAttribute attribute, int endOffset) {
+ StyleRange styleRange= new StyleRange(startOffset, endOffset - startOffset + 1,
+ attribute == null ? null : attribute.getForeground(),
+ attribute == null ? null : attribute.getBackground(),
+ attribute == null ? SWT.NORMAL : attribute.getStyle());
+
+ // SMS 21 Jun 2007: negative (possibly 0) length style ranges seem to cause problems;
+ // but if you have one it should lead to an IllegalArgumentException in changeTextPresentation(..)
+ if (styleRange.length <= 0 || styleRange.start + styleRange.length > this.fSourceViewer.getDocument().getLength()) {
+ } else {
+ presentation.addStyleRange(styleRange);
+ }
+ }
+
+ private void submitTextPresentation(final TextPresentation uncheckedPresentation) {
+ int charCount = 0;
+ if (fSourceViewer != null) {
+ IDocument document = fSourceViewer.getDocument();
+ if (document != null) // EDW 27 Sep 2008 May be null after file deleted
+ charCount = document.getLength();
+ }
+ final TextPresentation presentation;
+ if (!checkPresentation(uncheckedPresentation, charCount))
+ presentation = correctPresentation(uncheckedPresentation, charCount);
+ else
+ presentation = uncheckedPresentation;
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+
+ // SMS 16 Sep 2008
+ int charCount = 0;
+ if (fSourceViewer != null) {
+ IDocument document = fSourceViewer.getDocument();
+ if (document != null) // EDW 27 Sep 2008 May be null after file deleted
+ charCount = document.getLength();
+ }
+
+ // Attempt to head off exception due to final range extending beyond
+ // last character in text
+ int lastStart = presentation.getLastStyleRange().start;
+ int lastLength = presentation.getLastStyleRange().length;
+ int end = lastStart + lastLength;
+ TextPresentation newPresentation = null;
+ if (end >= charCount) {
+ newPresentation = new TextPresentation();
+ Iterator presIt = presentation.getAllStyleRangeIterator();
+ while (presIt.hasNext()) {
+ StyleRange nextRange = (StyleRange) presIt.next();
+ if (nextRange.start + nextRange.length <= charCount)
+ newPresentation.addStyleRange(nextRange);
+ }
+ } else {
+ newPresentation = presentation;
+ }
+
+ // SMS 21 Jun 2007 added try-catch block
+ // Note: It doesn't work to just eat the exception here; if there is a problematic token
+ // then an exception is likely to arise downstream in the computation anyway
+ try {
+ if (fSourceViewer != null)
+ fSourceViewer.changeTextPresentation(newPresentation, true);
+ } catch (IllegalArgumentException e) {
+ // Possible causes (not necessarily exclusive:
+ // - negative length in a style range
+ // - overlapping ranges
+ // - range extends beyond last character in file
+ Iterator<StyleRange> ranges = presentation.getAllStyleRangeIterator();
+ List<StyleRange> rangesList = new ArrayList<StyleRange>();
+ while(ranges.hasNext())
+ rangesList.add((StyleRange)ranges.next());
+ String explanation = null;
+ if (rangesList.size() > 0) {
+ StyleRange firstRange = rangesList.get(0);
+ if (firstRange.length < 0)
+ explanation = "Style range with start = " + firstRange.start + " has negative length = " + firstRange.length;
+ if (explanation == null) {
+ for (int i = 1; i < rangesList.size(); i++) {
+ int currStart = rangesList.get(i).start;
+ int currLength = rangesList.get(i).length;
+ if (currLength <0) {
+ explanation = "Style range with start = " + currStart + " has negative length = " + currLength;
+ break;
+ }
+
+ int prevStart = rangesList.get(i-1).start;
+ int prevLength = rangesList.get(i-1).length;
+ if (prevStart + prevLength - 1 >= currStart) {
+ explanation = "Style range with start = " + prevStart + " and length = " + prevLength +
+ "overlaps style range with start = " + currStart;
+ break;
+ }
+ }
+ }
+ if (explanation == null) {
+ int finalStart = presentation.getLastStyleRange().start;
+ int finalLength = presentation.getLastStyleRange().length;
+ int finalEnd = finalStart + finalLength;
+ if (finalEnd >= charCount) {
+ explanation = "Final style range with start = " + finalStart + " and length = " + finalLength +
+ "extends beyond last character (character count = " + charCount + ")";
+ }
+ }
+ if (explanation == null)
+ explanation = "Cause not identified";
+ }
+
+ ErrorHandler.logError("PresentationController.submitTextPresentation: IllegalArgumentException: " + explanation, e);
+ throw e;
+ }
+ }
+ });
+ }
+
+ private boolean checkPresentation(TextPresentation presentation, int charCount) { // EDW
+ Iterator presIt = presentation.getAllStyleRangeIterator();
+ int end = -1;
+ while (presIt.hasNext()) {
+ StyleRange nextRange = (StyleRange) presIt.next();
+ int start = nextRange.start;
+ int length = nextRange.length;
+ if (start < end) {
+ System.out.println("Unexpected style start " + start + ":" + length + ":" + (start + length) + "/" + charCount);
+ return false;
+ }
+ if (length < 1) {
+ System.out.println("Unexpected style length " + start + ":" + length + ":" + (start + length) + "/" + charCount);
+ return false;
+ }
+ end = start + length;
+ if (end > charCount) {
+ System.out.println("Unexpected style end " + start + ":" + length + ":" + (start + length) + "/" + charCount);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private TextPresentation correctPresentation(TextPresentation presentation, int charCount) { // EDW
+ List<StyleRange> ranges = new ArrayList<StyleRange>();
+ Iterator presIt = presentation.getAllStyleRangeIterator();
+ for (int styleNumber = 0; presIt.hasNext(); styleNumber++) {
+ StyleRange range = (StyleRange) presIt.next();
+ int start = range.start;
+ int length = range.length;
+ if (length <= 0)
+ System.out.println("Ignored -ve length style " + styleNumber + ": " + range.start + ":" + range.length + ":" + (range.start + range.length) + "/" + charCount);
+ else if (start >= charCount)
+ System.out.println("Ignored past-end style " + styleNumber + ": " + range.start + ":" + range.length + ":" + (range.start + range.length) + "/" + charCount);
+ else {
+ int end = start + length;
+ if (end > charCount) {
+ System.out.println("Truncated over-end style " + styleNumber + ": " + range.start + ":" + range.length + ":" + (range.start + range.length) + "/" + charCount);
+ range.length = charCount - start;
+ }
+ ranges.add(range);
+ }
+ }
+ Collections.sort(ranges, new Comparator<StyleRange>()
+ {
+ public int compare(StyleRange o1, StyleRange o2) {
+ return o1.start - o2.start;
+ }
+ });
+ IDocument document = fSourceViewer.getDocument();
+ TextPresentation newPresentation = new TextPresentation();
+ int iMax = ranges.size();
+ for (int i = 0; i < iMax; i++) {
+ StyleRange thisRange = ranges.get(i);
+ if ((i+1) < iMax) {
+ StyleRange nextRange = ranges.get(i+1);
+ int end = thisRange.start + thisRange.length;
+ if (end > nextRange.start) {
+ try {
+ System.out.println("Truncated over-lap style " + i + " " +
+ thisRange.start + ":" + thisRange.length + ":" + (thisRange.start + thisRange.length) + ":'" + document.get(thisRange.start, thisRange.length) + "' " +
+ nextRange.start + ":" + nextRange.length + ":" + (nextRange.start + nextRange.length) + ":'" + document.get(nextRange.start, nextRange.length) + "'");
+ } catch (BadLocationException e) {
+ e.printStackTrace();
+ }
+ thisRange.length = nextRange.start - thisRange.start;
+ }
+ }
+ newPresentation.addStyleRange(thisRange);
+ }
+ return newPresentation;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/ProblemMarkerManager.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/ProblemMarkerManager.java
new file mode 100644
index 000000000..3df2866fd
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/ProblemMarkerManager.java
@@ -0,0 +1,193 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor.internal;
+
+import java.util.HashSet;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IMarkerDelta;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.imp.editor.IProblemChangedListener;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.jface.text.source.AnnotationModelEvent;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.IAnnotationModelListener;
+import org.eclipse.jface.text.source.IAnnotationModelListenerExtension;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Listens to resource deltas and filters for marker changes of type IMarker.PROBLEM Viewers showing error ticks should
+ * register as listener to this type. Based on class of the same name from JDT/UI.
+ *
+ * @author Dr. Robert M. Fuhrer
+ */
+public class ProblemMarkerManager implements IResourceChangeListener, IAnnotationModelListener, IAnnotationModelListenerExtension {
+
+ /**
+ * Visitors used to look if the element change delta contains a marker change.
+ */
+ private static class ProjectErrorVisitor implements IResourceDeltaVisitor {
+ private HashSet<IResource> fChangedElements;
+
+ public ProjectErrorVisitor(HashSet<IResource> changedElements) {
+ fChangedElements= changedElements;
+ }
+
+ public boolean visit(IResourceDelta delta) throws CoreException {
+ IResource res= delta.getResource();
+ if (res instanceof IProject && delta.getKind() == IResourceDelta.CHANGED) {
+ IProject project= (IProject) res;
+ if (!project.isAccessible()) {
+ // only track open Java projects
+ return false;
+ }
+ }
+ checkInvalidate(delta, res);
+ return true;
+ }
+
+ private void checkInvalidate(IResourceDelta delta, IResource resource) {
+ int kind= delta.getKind();
+ if (kind == IResourceDelta.REMOVED || kind == IResourceDelta.ADDED || (kind == IResourceDelta.CHANGED && isErrorDelta(delta))) {
+ // invalidate the resource and all parents
+ while (resource.getType() != IResource.ROOT && fChangedElements.add(resource)) {
+ resource= resource.getParent();
+ }
+ }
+ }
+
+ private boolean isErrorDelta(IResourceDelta delta) {
+ if ((delta.getFlags() & IResourceDelta.MARKERS) != 0) {
+ IMarkerDelta[] markerDeltas= delta.getMarkerDeltas();
+ for(int i= 0; i < markerDeltas.length; i++) {
+ if (markerDeltas[i].isSubtypeOf(IMarker.PROBLEM)) {
+ int kind= markerDeltas[i].getKind();
+ if (kind == IResourceDelta.ADDED || kind == IResourceDelta.REMOVED)
+ return true;
+ int severity= markerDeltas[i].getAttribute(IMarker.SEVERITY, -1);
+ int newSeverity= markerDeltas[i].getMarker().getAttribute(IMarker.SEVERITY, -1);
+ if (newSeverity != severity)
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ private ListenerList fListeners;
+
+ public ProblemMarkerManager() {
+ fListeners= new ListenerList();
+ }
+
+ /*
+ * @see IResourceChangeListener#resourceChanged
+ */
+ public void resourceChanged(IResourceChangeEvent event) {
+ HashSet<IResource> changedElements= new HashSet<IResource>();
+
+ try {
+ IResourceDelta delta= event.getDelta();
+ if (delta != null)
+ delta.accept(new ProjectErrorVisitor(changedElements));
+ } catch (CoreException e) {
+ RuntimePlugin.getInstance().logException("", e);
+ }
+
+ if (!changedElements.isEmpty()) {
+ IResource[] changes= (IResource[]) changedElements.toArray(new IResource[changedElements.size()]);
+ fireChanges(changes, true);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see IAnnotationModelListener#modelChanged(IAnnotationModel)
+ */
+ public void modelChanged(IAnnotationModel model) {
+ // no action
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see IAnnotationModelListenerExtension#modelChanged(AnnotationModelEvent)
+ */
+ public void modelChanged(AnnotationModelEvent event) {
+ // TODO Need to create the analogous bit of logic here... need more stuff in UniversalEditor and friends...
+// if (event instanceof CompilationUnitAnnotationModelEvent) {
+// CompilationUnitAnnotationModelEvent cuEvent= (CompilationUnitAnnotationModelEvent) event;
+// if (cuEvent.includesProblemMarkerAnnotationChanges()) {
+// IResource[] changes= new IResource[] { event.getUnderlyingResource() };
+//
+// fireChanges(changes, false);
+// }
+// }
+ }
+
+ /**
+ * Adds a listener for problem marker changes.
+ */
+ public void addListener(IProblemChangedListener listener) {
+ if (fListeners.isEmpty()) {
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
+ // TODO Need to create the analogous bit of logic here... need more stuff in UniversalEditor and friends...
+// RuntimePlugin.getInstance().getCompilationUnitDocumentProvider().addGlobalAnnotationModelListener(this);
+ }
+ fListeners.add(listener);
+ }
+
+ /**
+ * Removes a <code>IProblemChangedListener</code>.
+ */
+ public void removeListener(IProblemChangedListener listener) {
+ fListeners.remove(listener);
+ if (fListeners.isEmpty()) {
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
+ // TODO Need to create the analogous bit of logic here... need more stuff in UniversalEditor and friends...
+// RuntimePlugin.getInstance().getCompilationUnitDocumentProvider().removeGlobalAnnotationModelListener(this);
+ }
+ }
+
+ private void fireChanges(final IResource[] changes, final boolean isMarkerChange) {
+ //Display display= SWTUtil.getStandardDisplay();
+ Display display = Display.getCurrent();
+ if (display == null)
+ display= Display.getDefault();
+
+
+ if (display != null && !display.isDisposed()) {
+ display.asyncExec(new Runnable() {
+ public void run() {
+ Object[] listeners= fListeners.getListeners();
+
+ for(int i= 0; i < listeners.length; i++) {
+ IProblemChangedListener curr= (IProblemChangedListener) listeners[i];
+
+ curr.problemsChanged(changes, isMarkerChange);
+ }
+ }
+ });
+ }
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/SourceHyperlinkController.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/SourceHyperlinkController.java
new file mode 100644
index 000000000..2bd119ddc
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/SourceHyperlinkController.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+/*
+ * Created on Feb 8, 2006
+ */
+package org.eclipse.imp.editor.internal;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.imp.parser.IModelListener;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.services.ISourceHyperlinkDetector;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+public class SourceHyperlinkController implements IHyperlinkDetector, IModelListener {
+ private final ISourceHyperlinkDetector fSourceHyperlinkDetector;
+ private IParseController fParseController;
+ private final ITextEditor fEditor;
+
+ public SourceHyperlinkController(ISourceHyperlinkDetector sourceHyperlinkDetector, ITextEditor editor) {
+ fSourceHyperlinkDetector= sourceHyperlinkDetector;
+ fEditor= editor;
+ }
+
+ public AnalysisRequired getAnalysisRequired() {
+ return AnalysisRequired.NAME_ANALYSIS;
+ }
+
+ public IHyperlink[] detectHyperlinks(final ITextViewer textViewer, final IRegion region, boolean canShowMultipleHyperlinks) {
+ return fSourceHyperlinkDetector.detectHyperlinks(region, fEditor, textViewer, fParseController);
+ }
+
+ public void update(IParseController parseController, IProgressMonitor monitor) {
+ fParseController= parseController;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/TextEditorActionContributor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/TextEditorActionContributor.java
new file mode 100644
index 000000000..017133f90
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/TextEditorActionContributor.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.editor.internal;
+
+import java.util.ResourceBundle;
+
+import org.eclipse.imp.editor.GotoAnnotationAction;
+import org.eclipse.imp.editor.IEditorActionDefinitionIds;
+import org.eclipse.imp.editor.UniversalEditor;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.texteditor.BasicTextEditorActionContributor;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.texteditor.RetargetTextEditorAction;
+
+public class TextEditorActionContributor extends BasicTextEditorActionContributor {
+ private GotoAnnotationAction fNextAnnotation;
+
+ private GotoAnnotationAction fPreviousAnnotation;
+
+ private RetargetTextEditorAction fShowOutline;
+
+ private RetargetTextEditorAction fToggleComment;
+
+ // mmk 4/8/08
+ private RetargetTextEditorAction fIndentSelection;
+
+ public TextEditorActionContributor() {
+ super();
+ fPreviousAnnotation= new GotoAnnotationAction("PreviousAnnotation.", false); //$NON-NLS-1$
+ fNextAnnotation= new GotoAnnotationAction("NextAnnotation.", true); //$NON-NLS-1$
+ fShowOutline= new RetargetTextEditorAction(ResourceBundle.getBundle(UniversalEditor.MESSAGE_BUNDLE), "ShowOutline."); //$NON-NLS-1$
+ fShowOutline.setActionDefinitionId(UniversalEditor.SHOW_OUTLINE_COMMAND);
+ fToggleComment= new RetargetTextEditorAction(ResourceBundle.getBundle(UniversalEditor.MESSAGE_BUNDLE), "ToggleComment."); //$NON-NLS-1$
+ fToggleComment.setActionDefinitionId(UniversalEditor.TOGGLE_COMMENT_COMMAND);
+
+ // mmk 4/8/08
+ fIndentSelection= new RetargetTextEditorAction(ResourceBundle.getBundle(UniversalEditor.MESSAGE_BUNDLE), "IndentSelection."); //$NON-NLS-1$
+ fIndentSelection.setActionDefinitionId(UniversalEditor.INDENT_SELECTION_COMMAND);
+ }
+
+ public void init(IActionBars bars, IWorkbenchPage page) {
+ super.init(bars, page);
+ bars.setGlobalActionHandler(ITextEditorActionDefinitionIds.GOTO_NEXT_ANNOTATION, fNextAnnotation);
+ bars.setGlobalActionHandler(ITextEditorActionDefinitionIds.GOTO_PREVIOUS_ANNOTATION, fPreviousAnnotation);
+ bars.setGlobalActionHandler(ActionFactory.NEXT.getId(), fNextAnnotation);
+ bars.setGlobalActionHandler(ActionFactory.PREVIOUS.getId(), fPreviousAnnotation);
+ bars.setGlobalActionHandler(UniversalEditor.SHOW_OUTLINE_COMMAND, fShowOutline);
+ bars.setGlobalActionHandler(UniversalEditor.TOGGLE_COMMENT_COMMAND, fToggleComment);
+
+ // mmk 4/8/08
+ bars.setGlobalActionHandler(UniversalEditor.INDENT_SELECTION_COMMAND, fIndentSelection);
+ }
+
+ /*
+ * @see org.eclipse.ui.part.EditorActionBarContributor#contributeToMenu(org.eclipse.jface.action.IMenuManager)
+ */
+ public void contributeToMenu(IMenuManager menu) {
+ super.contributeToMenu(menu);
+
+ IMenuManager navigateMenu= menu.findMenuUsingPath(IWorkbenchActionConstants.M_NAVIGATE);
+
+ if (navigateMenu != null) {
+ navigateMenu.appendToGroup(IWorkbenchActionConstants.SHOW_EXT, fShowOutline);
+ }
+
+ IMenuManager editMenu= menu.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT);
+
+ if (editMenu != null) {
+ editMenu.appendToGroup(IWorkbenchActionConstants.EDIT_END, fToggleComment);
+ editMenu.appendToGroup(IWorkbenchActionConstants.EDIT_END, fIndentSelection);
+ }
+ }
+
+ public void setActiveEditor(IEditorPart part) {
+ super.setActiveEditor(part);
+
+ ITextEditor textEditor= null;
+
+ if (part instanceof ITextEditor)
+ textEditor= (ITextEditor) part;
+
+ fPreviousAnnotation.setEditor(textEditor);
+ fNextAnnotation.setEditor(textEditor);
+ fShowOutline.setAction(getAction(textEditor, UniversalEditor.SHOW_OUTLINE_COMMAND));
+ fToggleComment.setAction(getAction(textEditor, UniversalEditor.TOGGLE_COMMENT_COMMAND));
+
+ // mmk 4/8/08
+ fIndentSelection.setAction(getAction(textEditor, UniversalEditor.INDENT_SELECTION_COMMAND));
+
+ IActionBars bars= getActionBars();
+
+ bars.setGlobalActionHandler(IEditorActionDefinitionIds.FORMAT, getAction(textEditor, "Format")); //$NON-NLS-1$
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/ToggleBreakpointsAdapter.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/ToggleBreakpointsAdapter.java
new file mode 100644
index 000000000..c323896db
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/ToggleBreakpointsAdapter.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.editor.internal;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IMarkerDelta;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IBreakpointListener;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget;
+import org.eclipse.imp.editor.UniversalEditor;
+import org.eclipse.imp.services.IToggleBreakpointsHandler;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPart;
+
+/**
+ * Stan Sutton, suttons@us.ibm.com:
+ *
+ * Modified constructor to take a UniversalEditor (presumably the one creating
+ * the adapter and to save that editor and the filename extension of the source
+ * file opened in that editor (the "original" source file).
+ *
+ * The original filename extension is useful for methods that may need
+ * the extension but that don't have access to the original file or to an
+ * editor (or other IWorkbenchPart) from which to obtain the extension.
+ *
+ * The editor that created the adapter may serve as a convenient replacement
+ * for the IWorkbenchParts that are passed into the methods that control toggling.
+ * The interface IToggleBreakpointsTarget requires that each of these methods
+ * be passed an IWorkbenchPart, so we can't eliminate those parameters from
+ * the method signatures in which they occur. Another consideration is whether
+ * the IWorkbenchParts that are passed into these methods are guaranteed to be
+ * the same as the editor that created the adapter. I guess that in general
+ * the adapters might be created by things other than the parts on which they
+ * may operate (consider that a single adapter should be able to handle multiple
+ * parts). However, I also suspect that in our usage the editors that create
+ * the adapters are likely to be the only parts that get passed into these
+ * methods (at least so far). In any case, the editor is availble here for
+ * future implementors of these methods to use or not as they see fit.
+ */
+public class ToggleBreakpointsAdapter implements IToggleBreakpointsTarget, IBreakpointListener {
+ private final IToggleBreakpointsHandler fHandler;
+
+ public ToggleBreakpointsAdapter(UniversalEditor editor, IToggleBreakpointsHandler handler) {
+ fHandler= handler;
+
+ DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(this);
+ }
+
+ public void toggleLineBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
+ if (selection instanceof ITextSelection) {
+ ITextSelection textSel= (ITextSelection) selection;
+
+ IEditorPart editorPart= (IEditorPart) part.getAdapter(IEditorPart.class);
+ IFileEditorInput fileInput= (IFileEditorInput) editorPart.getEditorInput();
+ final IFile origSrcFile= fileInput.getFile();
+ final int lineNumber = textSel.getStartLine()+1;
+
+ IWorkspaceRunnable wr= new IWorkspaceRunnable() {
+ public void run(IProgressMonitor monitor) throws CoreException {
+ IMarker marker = findBreakpointMarker(origSrcFile, lineNumber);
+
+ if (marker != null) {
+ // The following will delete the associated marker
+ fHandler.clearLineBreakpoint(origSrcFile, lineNumber);
+ } else {
+ // The following will create a marker as a side-effect
+ fHandler.setLineBreakpoint(origSrcFile, lineNumber);
+ }
+ }
+ };
+ try {
+ ResourcesPlugin.getWorkspace().run(wr, null);
+ } catch (CoreException e) {
+ throw new DebugException(e.getStatus());
+ }
+ }
+ }
+
+ private IMarker findBreakpointMarker(IFile srcFile, int lineNumber) throws CoreException {
+ IMarker[] markers = srcFile.findMarkers(IBreakpoint.LINE_BREAKPOINT_MARKER, true, IResource.DEPTH_INFINITE);
+
+ for (int k = 0; k < markers.length; k++ ){
+ if (((Integer) markers[k].getAttribute(IMarker.LINE_NUMBER)).intValue() == lineNumber){
+ return markers[k];
+ }
+ }
+ return null;
+ }
+
+ public boolean canToggleLineBreakpoints(IWorkbenchPart part, ISelection selection) {
+ return true;
+ }
+
+ public void toggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
+ }
+
+ public boolean canToggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) {
+ return false;
+ }
+
+ public void toggleWatchpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
+ }
+
+ public boolean canToggleWatchpoints(IWorkbenchPart part, ISelection selection) {
+ return false;
+ }
+
+ public void breakpointAdded(IBreakpoint breakpoint) { }
+
+ public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) { }
+
+ public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) { }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/TreeDiffer.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/TreeDiffer.java
new file mode 100644
index 000000000..8aa8686c7
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/internal/TreeDiffer.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.editor.internal;
+
+import org.eclipse.imp.editor.ModelTreeNode;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+
+public class TreeDiffer {
+ private final TreeViewer fTreeViewer;
+ private final ILabelProvider fLabelProvider;
+
+// private static final String[] ALL_PROPS= new String[0];
+
+ public TreeDiffer(TreeViewer viewer, ILabelProvider labelProvider) {
+ fTreeViewer= viewer;
+ fLabelProvider= labelProvider;
+ }
+
+ public void diff(ModelTreeNode oldNode, ModelTreeNode newNode) {
+ if (1 == 1) return;
+ if (oldNode == newNode)
+ return;
+ if (fLabelProvider.getText(oldNode).equals(fLabelProvider.getText(newNode)))
+ return;
+ fTreeViewer.update(newNode, null);
+ ModelTreeNode[] oldChildren= oldNode.getChildren();
+ ModelTreeNode[] newChildren= newNode.getChildren();
+ int oi= 0, ni= 0;
+ for(; oi < oldChildren.length && ni < newChildren.length; ) {
+ ModelTreeNode oldChild= oldChildren[oi];
+ ModelTreeNode newChild= newChildren[ni];
+
+ if (oldChild == newChild || fLabelProvider.getText(oldChild).equals(fLabelProvider.getText(newChild))) {
+
+ }
+ }
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/messages.properties b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/messages.properties
new file mode 100644
index 000000000..f2314922b
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/editor/messages.properties
@@ -0,0 +1,24 @@
+#
+# This file was auto-generated by the LPG Eclipse Tooling.
+# It is safe to edit this file. It will not be overwritten.
+#
+ContentAssistProposal.label=Content assist
+ContentAssistProposal.tooltip=Content assist
+ContentAssistProposal.description=Provides content assistance
+
+Format.label=Format source
+Format.tooltip=Automatically formats the current source file
+Format.description=Automatically formats the current source file
+
+ShowOutline.label=Show &Outline
+ShowOutline.tooltip=Shows a popup view displaying an outline of the source file's contents
+ShowOutline.description=Shows a popup view displaying an outline of the source file's contents
+
+ToggleComment.label=Toggle Comment
+ToggleComment.tooltip=Comments/uncomments the currently selected text
+ToggleComment.description=Comments/uncomments the currently selected text
+
+# mmk 4/8/08
+IndentSelection.label=Indent Selection
+IndentSelection.tooltip=Indents all lines in selection
+IndentSelection.description=Indents all lines in selection
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/help/IMPHelp.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/help/IMPHelp.java
new file mode 100644
index 000000000..1712c66ce
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/help/IMPHelp.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+* Copyright (c) 2008 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.help;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.help.IContextProvider;
+import org.eclipse.imp.editor.LanguageServiceManager;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.parser.ISourcePositionLocator;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.imp.services.IHelpService;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.HelpEvent;
+import org.eclipse.swt.events.HelpListener;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+public class IMPHelp {
+ private final static Object[] NO_ELEMENTS= new Object[0];
+
+ public static void setHelp(LanguageServiceManager svcMgr, StructuredViewer viewer, String contextId) {
+ IMPViewerHelpListener listener= new IMPViewerHelpListener(svcMgr, viewer, contextId);
+ viewer.getControl().addHelpListener(listener);
+ }
+
+ public static void setHelp(LanguageServiceManager svcMgr, ITextEditor editor, StyledText text, String contextId) {
+ IMPEditorHelpListener listener= new IMPEditorHelpListener(svcMgr, editor, contextId);
+ text.addHelpListener(listener);
+ }
+
+ private static abstract class IMPHelpListenerBase implements HelpListener {
+ protected String fContextId;
+
+ public IMPHelpListenerBase(String contextId) {
+ fContextId= contextId;
+ }
+ }
+
+ private static class IMPViewerHelpListener extends IMPHelpListenerBase {
+ private StructuredViewer fViewer;
+ private final IHelpService fHelpService;
+ private final IParseController fParseController;
+
+ public IMPViewerHelpListener(LanguageServiceManager svcManager, StructuredViewer viewer, String contextId) {
+ super(contextId);
+ fHelpService= svcManager.getContextHelp();
+ fParseController= svcManager.getParseController();
+ fViewer= viewer;
+ }
+
+ /*
+ * @see HelpListener#helpRequested(HelpEvent)
+ *
+ */
+ public void helpRequested(HelpEvent e) {
+ try {
+ Object[] selected= null;
+ if (fViewer != null) {
+ ISelection selection= fViewer.getSelection();
+ if (selection instanceof IStructuredSelection) {
+ selected= ((IStructuredSelection) selection).toArray();
+ }
+ }
+ IMPHelpContext.displayHelp(fHelpService, fParseController, fContextId, selected);
+ } catch (CoreException x) {
+ RuntimePlugin.getInstance().logException(x.getMessage(), x);
+ }
+ }
+ }
+
+ private static class IMPEditorHelpListener extends IMPHelpListenerBase {
+ private final ITextEditor fEditor;
+ private final IHelpService fHelpService;
+ private final ISourcePositionLocator fLocator;
+ private final IParseController fParseController;
+
+ public IMPEditorHelpListener(LanguageServiceManager svcManager, ITextEditor editor, String contextId) {
+ super(contextId);
+ fHelpService= svcManager.getContextHelp();
+ fParseController= svcManager.getParseController();
+ fLocator= fParseController.getSourcePositionLocator();
+ fEditor= editor;
+ }
+
+ /*
+ * @see HelpListener#helpRequested(HelpEvent)
+ *
+ */
+ public void helpRequested(HelpEvent e) {
+ try {
+ Object[] selected= null;
+
+ if (fEditor != null) {
+ ITextSelection textSel= (ITextSelection) fEditor.getSelectionProvider().getSelection();
+ Object node= fLocator.findNode(fParseController.getCurrentAst(), textSel.getOffset());
+
+ selected= new Object[] { node };
+ }
+ IMPHelpContext.displayHelp(fHelpService, fParseController, fContextId, selected);
+ } catch (CoreException x) {
+ RuntimePlugin.getInstance().logException(x.getMessage(), x);
+ }
+ }
+ }
+
+ /**
+ * Creates and returns a help context provider for the given part.
+ *
+ * @param part the part for which to create the help context provider
+ * @param contextId the optional context ID used to retrieve static help
+ * @return the help context provider
+ */
+ public static IContextProvider getHelpContextProvider(IWorkbenchPart part, LanguageServiceManager srvcMgr, String contextId) {
+ ISelectionProvider provider= part.getSite().getSelectionProvider();
+ if (provider != null) {
+ ISelection sel= provider.getSelection();
+ if (sel instanceof IStructuredSelection) {
+ IStructuredSelection selection= (IStructuredSelection) sel;
+
+ return new IMPHelpContextProvider(srvcMgr, contextId, selection.toArray());
+ } else if (sel instanceof ITextSelection) {
+ ITextSelection textSel= (ITextSelection) sel;
+// IParseController parseController= srvcMgr.getParseController();
+
+ return new IMPHelpContextProvider(srvcMgr, contextId, new Region(textSel.getOffset(), textSel.getLength()));
+// ISourcePositionLocator nodeLocator= parseController.getNodeLocator();
+// Object node= nodeLocator.findNode(parseController.getCurrentAst(), textSel.getOffset(), textSel.getOffset() + textSel.getLength());
+//
+// if (node != null) {
+// elements= new Object[] { node };
+// } else {
+// elements= NO_ELEMENTS;
+// }
+ }
+ }
+ return null;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/help/IMPHelpContext.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/help/IMPHelpContext.java
new file mode 100644
index 000000000..0c1a12971
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/help/IMPHelpContext.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+* Copyright (c) 2008 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.help;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.help.HelpSystem;
+import org.eclipse.help.IContext;
+import org.eclipse.help.IContext2;
+import org.eclipse.help.IHelpResource;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.services.IHelpService;
+import org.eclipse.ui.PlatformUI;
+
+public class IMPHelpContext implements IContext2 {
+ private final String fHelpText;
+ private final String fTitle;
+
+ public static void displayHelp(IHelpService helpSrvc, IParseController parseController, String contextId, Object[] selected) throws CoreException {
+ IContext context= HelpSystem.getContext(contextId);
+
+ if (context != null) {
+ if (selected != null && selected.length > 0) {
+ String helpText= IMPHelpContextProvider.buildHelpString(selected, helpSrvc, parseController);
+
+ context= new IMPHelpContext(context, helpText);
+ }
+ PlatformUI.getWorkbench().getHelpSystem().displayHelp(context);
+ }
+ }
+
+ public IMPHelpContext(IContext context, String helpText) {
+ fHelpText= helpText;
+ fTitle= (context instanceof IContext2) ? ((IContext2) context).getTitle() : "";
+ }
+
+ public IHelpResource[] getRelatedTopics() {
+ return new IHelpResource[0];
+ }
+
+ public String getText() {
+ return fHelpText;
+ }
+
+ public String getCategory(IHelpResource topic) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getStyledText() {
+ return fHelpText;
+ }
+
+ public String getTitle() {
+ return fTitle;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/help/IMPHelpContextProvider.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/help/IMPHelpContextProvider.java
new file mode 100644
index 000000000..7ca8ee651
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/help/IMPHelpContextProvider.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+* Copyright (c) 2008 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.help;
+
+import org.eclipse.help.HelpSystem;
+import org.eclipse.help.IContext;
+import org.eclipse.help.IContextProvider;
+import org.eclipse.imp.editor.LanguageServiceManager;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.services.IHelpService;
+import org.eclipse.jface.text.IRegion;
+
+public class IMPHelpContextProvider implements IContextProvider {
+ private final IHelpService fHelpContextSrvc;
+ private final IParseController fParseController;
+ private final String fContextID;
+ private final Object[] fSelected;
+ private final IRegion fSelection;
+
+ public IMPHelpContextProvider(LanguageServiceManager srvcMgr, String helpContextID, Object[] selected) {
+ fHelpContextSrvc= srvcMgr.getContextHelp();
+ fParseController= srvcMgr.getParseController();
+ fContextID= helpContextID;
+ fSelected= selected;
+ fSelection= null;
+ }
+
+ public IMPHelpContextProvider(LanguageServiceManager srvcMgr, String helpContextID, IRegion selection) {
+ fHelpContextSrvc= srvcMgr.getContextHelp();
+ fParseController= srvcMgr.getParseController();
+ fContextID= helpContextID;
+ fSelected= null;
+ fSelection= selection;
+ }
+
+ public IContext getContext(Object target) {
+ IContext context= HelpSystem.getContext(fContextID);
+
+ if (fHelpContextSrvc != null) {
+ context= HelpSystem.getContext(fHelpContextSrvc.getContextId(fContextID));
+ if (fSelected != null && fSelected.length > 0) {
+ context= new IMPHelpContext(context, buildHelpString(fSelected, fHelpContextSrvc, fParseController));
+ } else if (fSelection != null) {
+ context= new IMPHelpContext(context, buildHelpString(fSelection, fHelpContextSrvc, fParseController));
+ }
+ }
+ return context;
+ }
+
+ public static String buildHelpString(Object[] entities, IHelpService helpService, IParseController parseController) {
+ StringBuilder sb= new StringBuilder();
+ for(int i= 0; i < entities.length; i++) {
+ sb.append(helpService.getHelp(entities[i], parseController));
+ }
+ String result= sb.toString();
+ return result;
+ }
+
+ public static String buildHelpString(IRegion selection, IHelpService helpService, IParseController parseController) {
+ return helpService.getHelp(selection, parseController);
+ }
+
+ public int getContextChangeMask() {
+ return SELECTION;
+ }
+
+ public String getSearchExpression(Object target) {
+ return null;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/DefinitionIndexEntry.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/DefinitionIndexEntry.java
new file mode 100644
index 000000000..7a0a0b276
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/DefinitionIndexEntry.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.indexing;
+
+import java.io.FileWriter;
+import java.io.IOException;
+
+import org.eclipse.core.resources.IFile;
+
+public class DefinitionIndexEntry extends IndexEntry {
+ public final static char DEFINITION_TYPE= 'D';
+
+ private int fModifiers;
+
+ public DefinitionIndexEntry() { }
+
+ public DefinitionIndexEntry(int type, String name, int modifiers, IFile file, int start, int end) {
+ super(type, name, file, start, end);
+ }
+
+ public void saveToStream(FileWriter writer) throws IOException {
+ super.saveToStream(writer);
+ writer.write(':');
+ writer.write(Integer.toString(fModifiers));
+ }
+
+ public void readExtraFields(String[] fields) {
+ fModifiers= Integer.parseInt(fields[6]);
+ }
+
+ public char getEntryKind() {
+ return DEFINITION_TYPE;
+ }
+
+ public Object findASTNode(Object ast) {
+ return null;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/IndexContributorBase.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/IndexContributorBase.java
new file mode 100644
index 000000000..5ed9a1aaf
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/IndexContributorBase.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.indexing;
+
+import org.eclipse.imp.language.ILanguageService;
+
+
+/**
+ * Base class for implementations of the indexContributor language service extension point.
+ * @author Dr. Robert M. Fuhrer
+ *
+ */
+public abstract class IndexContributorBase implements ILanguageService {
+ public IndexContributorBase() {
+ super();
+ }
+
+ /**
+ * Create index entries for entities in the given AST and add them to the given Indexer,
+ * by means of calls to Indexer.addEntry().
+ */
+ public abstract void contributeEntries(Object ast, Indexer indexer);
+
+ /**
+ * Parse the given entry string
+ * @param s
+ * @return
+ */
+ public IndexEntry parseEntry(String s) {
+ char kind= s.charAt(0);
+ IndexEntry entry;
+
+ if (kind == DefinitionIndexEntry.DEFINITION_TYPE)
+ entry= new DefinitionIndexEntry();
+ else if (kind == ReferenceIndexEntry.REFERENCE_TYPE)
+ entry= new ReferenceIndexEntry();
+ else
+ return null;
+
+ entry.parseFromString(s);
+ return entry;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/IndexEntry.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/IndexEntry.java
new file mode 100644
index 000000000..4e5dcc2b9
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/IndexEntry.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.indexing;
+
+import java.io.FileWriter;
+import java.io.IOException;
+
+import org.eclipse.core.resources.IFile;
+
+public abstract class IndexEntry {
+ // TODO would be nice to make these 'final'...
+ protected int fType;
+ protected String fName;
+ protected int fStart;
+ protected int fEnd;
+ protected String fPath;
+
+ public IndexEntry() { }
+
+ public IndexEntry(int type, String name, IFile file, int start, int end) {
+ fType= type;
+ fName= name;
+ fPath= file.getFullPath().toString();
+ fStart= start;
+ fEnd= end;
+ }
+
+ public abstract char getEntryKind();
+
+ public void saveToStream(FileWriter writer) throws IOException {
+ writer.write(getEntryKind());
+ writer.write(':');
+ writer.write(fType);
+ writer.write(':');
+ writer.write(fPath);
+ writer.write(':');
+ writer.write(fName);
+ writer.write(':');
+ writer.write(fStart);
+ writer.write(':');
+ writer.write(fEnd);
+ }
+
+ public final void parseFromString(String s) {
+ String[] fields= s.split(":");
+
+ fType= Integer.parseInt(fields[1]);
+ fPath= fields[2];
+ fName= fields[3];
+ fStart= Integer.parseInt(fields[4]);
+ fEnd= Integer.parseInt(fields[5]);
+ readExtraFields(fields);
+ }
+
+ protected abstract void readExtraFields(String[] fields);
+
+ public abstract Object findASTNode(Object ast);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/Indexer.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/Indexer.java
new file mode 100644
index 000000000..ec59d5bce
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/Indexer.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.indexing;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.imp.core.ErrorHandler;
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.language.LanguageRegistry;
+import org.eclipse.imp.language.ServiceFactory;
+import org.eclipse.imp.language.LanguageValidator;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.imp.utils.StreamUtils;
+
+/*
+ * Licensed Materials - Property of IBM,
+ * (c) Copyright IBM Corp. 2005 All Rights Reserved
+ */
+
+/**
+ * @author rfuhrer@watson.ibm.com
+ */
+public class Indexer {
+ private final Language fLanguage; // used to locate the index file
+
+ private IndexContributorBase fIndexer;
+
+ private IParseController fParser;
+
+ /**
+ * The set of index entries for the current project being indexed
+ */
+ private Set/*<IndexEntry>*/ fProjectEntries= new HashSet();
+
+ /**
+ * Creates an index for the shared elements in this language
+ */
+ public Indexer(String languageName) {
+ fLanguage= LanguageRegistry.findLanguage(languageName);
+ fIndexer= ServiceFactory.getInstance().getIndexContributor(fLanguage);
+ fParser= ServiceFactory.getInstance().getParseController(fLanguage);
+ }
+
+ // Probably don't ever want to do this; the complete set of indexes is huge.
+ // Instead, each project index should probably be loaded and then searched
+ // from within the top-level search loop.
+ public void loadAll() {
+ IProject[] projects= ResourcesPlugin.getWorkspace().getRoot().getProjects();
+
+ for(int i= 0; i < projects.length; i++) {
+ load(projects[i]);
+ }
+ }
+
+ /**
+ * Opens the index file for reading. The index file is stored in the plug-in's state location. If this is the first
+ * time the index is opened, it will be created. The inputstream has to be closed after usage.
+ *
+ * @return an inputstream containing the index file
+ */
+ public void load(IProject project) {
+ try {
+ File file= getPersistentIndexFile(project);
+
+ readEntries(new BufferedReader(new FileReader(file)));
+ } catch (IOException e) {
+ ErrorHandler.reportError("Cannot open persistent index for " + fLanguage);
+ }
+ }
+
+ private void readEntries(BufferedReader reader) throws IOException {
+ String line;
+
+ while ((line= reader.readLine()) != null) {
+ IndexEntry entry= fIndexer.parseEntry(line);
+
+ addEntry(entry);
+ }
+ }
+
+ public void clearEntries() {
+ fProjectEntries.clear();
+ }
+
+ public void addEntry(IndexEntry entry) {
+ fProjectEntries.add(entry);
+ }
+
+ public void createAllIndexes() {
+ if (fParser == null) {
+ RuntimePlugin.getInstance().writeErrorMsg("No parser for language " + fLanguage + "; indexing disabled.");
+ return;
+ }
+
+ IProject[] projects= ResourcesPlugin.getWorkspace().getRoot().getProjects();
+
+ for(int i= 0; i < projects.length; i++) {
+ clearEntries(); // no turds from previous projects
+ createProjectIndex(projects[i]);
+ save(projects[i]);
+ }
+ }
+
+ public void createProjectIndex(IProject project) {
+ final LanguageValidator validator= fLanguage.getValidator();
+ final IProgressMonitor monitor= new NullProgressMonitor();
+
+ try {
+ project.accept(new IResourceProxyVisitor() {
+ public boolean visit(IResourceProxy proxy) throws CoreException {
+ if (proxy.getType() == IResource.FILE) {
+ String name= proxy.getName();
+
+ if (fLanguage.hasExtension(name.substring(name.lastIndexOf('.') + 1))) {
+ IFile file= (IFile) proxy.requestResource();
+
+ if (validator == null || validator.validate(file)) {
+ String contents= StreamUtils.readStreamContents(file.getContents(), file.getCharset());
+ Object ast= fParser.parse(contents, monitor);
+
+ if (ast != null)
+ fIndexer.contributeEntries(ast, Indexer.this);
+ else
+ RuntimePlugin.getInstance().writeErrorMsg("Unable to parse file " + file.getFullPath() + "; indexing suppressed.");
+ }
+ }
+ }
+ return false;
+ }
+ }, 0);
+ } catch (CoreException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Open the index file for saving. The output stream should be closed after usage.
+ *
+ * @return an outputStream the user can write to.
+ */
+ public void save(IProject project) {
+ try {
+ File file= getPersistentIndexFile(project);
+ FileWriter writer= new FileWriter(file);
+
+ for(Iterator iter= fProjectEntries.iterator(); iter.hasNext(); ) {
+ IndexEntry entry= (IndexEntry) iter.next();
+
+ entry.saveToStream(writer);
+ }
+ } catch (IOException e) {
+ ErrorHandler.reportError("Cannot open persistent index for " + fLanguage + " and project " + project.getName(), e);
+ }
+ }
+
+ /**
+ * Returns the index file. The index file is stored in the plug-in's state location. If this is the first time the
+ * index is opened, it will be created.
+ * @param project the project whose index file should be loaded
+ *
+ * @return the file where the persistent index is stored
+ * @return null when the file cannot be created
+ */
+ private File getPersistentIndexFile(IProject project) {
+ try {
+ IPath path= RuntimePlugin.getInstance().getStateLocation().append(project.getName());
+ File file= new File(path.toFile(), fLanguage + ".index");
+
+ if (!file.exists()) {
+ file.createNewFile();
+ }
+ return file;
+ } catch (IOException e) {
+ ErrorHandler.reportError("Cannot locate index file for " + fLanguage + " and project " + project.getName(), e);
+ return null;
+ }
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/ReferenceIndexEntry.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/ReferenceIndexEntry.java
new file mode 100644
index 000000000..8518e2310
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/indexing/ReferenceIndexEntry.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.indexing;
+
+import org.eclipse.core.resources.IFile;
+
+public class ReferenceIndexEntry extends IndexEntry {
+ public final static char REFERENCE_TYPE= 'R';
+
+ public ReferenceIndexEntry() { }
+
+ // TODO This isn't right: we need to uniquely identify both the referee and the referent.
+ // The 'file' field can't serve both purposes, so we need another, along with another
+ // 'name' field.
+ // Also, is the 'name' field used to identify the parent entity containing the reference?
+ public ReferenceIndexEntry(int type, String name, IFile file, int start, int end) {
+ super(type, name, file, start, end);
+ }
+
+ public char getEntryKind() {
+ return REFERENCE_TYPE;
+ }
+
+ protected void readExtraFields(String[] fields) {
+ // do nothing
+ }
+
+ public Object findASTNode(Object ast) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/CachingServiceFactory.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/CachingServiceFactory.java
new file mode 100644
index 000000000..c392de319
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/CachingServiceFactory.java
@@ -0,0 +1,262 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.language;
+
+import java.util.Set;
+
+import org.eclipse.imp.editor.OutlineContentProviderBase;
+import org.eclipse.imp.editor.OutlineLabelProvider.IElementImageProvider;
+import org.eclipse.imp.indexing.IndexContributorBase;
+import org.eclipse.imp.parser.IModelListener;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.services.IASTAdapter;
+import org.eclipse.imp.services.IAnnotationHover;
+import org.eclipse.imp.services.IAutoEditStrategy;
+import org.eclipse.imp.services.IContentProposer;
+import org.eclipse.imp.services.IDocumentationProvider;
+import org.eclipse.imp.services.IEntityNameLocator;
+import org.eclipse.imp.services.IFoldingUpdater;
+import org.eclipse.imp.services.IHoverHelper;
+import org.eclipse.imp.services.ILabelProvider;
+import org.eclipse.imp.services.ILanguageActionsContributor;
+import org.eclipse.imp.services.ILanguageSyntaxProperties;
+import org.eclipse.imp.services.IOccurrenceMarker;
+import org.eclipse.imp.services.IOutliner;
+import org.eclipse.imp.services.IRefactoringContributor;
+import org.eclipse.imp.services.IReferenceResolver;
+import org.eclipse.imp.services.ISourceFormatter;
+import org.eclipse.imp.services.ISourceHyperlinkDetector;
+import org.eclipse.imp.services.ITokenColorer;
+import org.eclipse.imp.services.base.TreeModelBuilderBase;
+
+public class CachingServiceFactory extends ServiceFactory {
+ private IContentProposer contentProposer;
+ private IOutliner outliner;
+ private IElementImageProvider elementImageProvider;
+ private ILanguageSyntaxProperties syntaxProperties;
+ private IOccurrenceMarker occurrenceMarker;
+ private IDocumentationProvider documentationProvider;
+ private Set<ILanguageActionsContributor> languageActionsContributors;
+ private IReferenceResolver referenceResolver;
+ private Set<IRefactoringContributor> refactoringContributors;
+ private OutlineContentProviderBase outlineContentProvider;
+ private ILabelProvider labelProvider;
+ private ISourceHyperlinkDetector sourceHyperlinkDetector;
+ private ISourceFormatter sourceFormatter;
+ private IAnnotationHover annotationHover;
+ private IFoldingUpdater foldingUpdater;
+ private Set<IAutoEditStrategy> autoEditStrategies;
+ private IModelListener modelListener;
+ private TreeModelBuilderBase treeModelBuilder;
+ private IParseController parseController;
+ private IndexContributorBase indexContributor;
+ private ITokenColorer tokenColorer;
+ private IHoverHelper hoverHelper;
+ private IASTAdapter astAdapter;
+ private IEntityNameLocator entityNameLocator;
+
+ public CachingServiceFactory() { }
+
+ @Override
+ public IContentProposer getContentProposer(Language lang) {
+ if (contentProposer == null) {
+ contentProposer = super.getContentProposer(lang);
+ }
+ return contentProposer;
+ }
+
+ @Override
+ public IHoverHelper getHoverHelper(Language lang) {
+ if (hoverHelper == null) {
+ hoverHelper = super.getHoverHelper(lang);
+ }
+ return hoverHelper;
+ }
+
+ @Override
+ public ITokenColorer getTokenColorer(Language lang) {
+ if (tokenColorer == null) {
+ tokenColorer = super.getTokenColorer(lang);
+ }
+ return tokenColorer;
+ }
+
+ @Override
+ public IndexContributorBase getIndexContributor(Language lang) {
+ if (indexContributor == null) {
+ indexContributor = super.getIndexContributor(lang);
+ }
+ return indexContributor;
+ }
+
+ @Override
+ public IParseController getParseController(Language lang) {
+ if (parseController == null) {
+ parseController = super.getParseController(lang);
+ }
+ return parseController;
+ }
+
+ @Override
+ public TreeModelBuilderBase getTreeModelBuilder(Language lang) {
+ if (treeModelBuilder == null) {
+ treeModelBuilder = super.getTreeModelBuilder(lang);
+ }
+ return treeModelBuilder;
+ }
+
+ @Override
+ public IModelListener getModelListener(Language lang) {
+ if (modelListener == null) {
+ modelListener = super.getModelListener(lang);
+ }
+ return modelListener;
+ }
+
+ @Override
+ public Set<IAutoEditStrategy> getAutoEditStrategies(Language lang) {
+ if (autoEditStrategies == null) {
+ autoEditStrategies = super.getAutoEditStrategies(lang);
+ }
+ return autoEditStrategies;
+ }
+
+ @Override
+ public IFoldingUpdater getFoldingUpdater(Language lang) {
+ if (foldingUpdater == null) {
+ foldingUpdater = super.getFoldingUpdater(lang);
+ }
+ return foldingUpdater;
+ }
+
+ @Override
+ public IAnnotationHover getAnnotationHover(Language lang) {
+ if (annotationHover == null) {
+ annotationHover = super.getAnnotationHover(lang);
+ }
+ return annotationHover;
+ }
+
+ @Override
+ public ISourceFormatter getSourceFormatter(Language lang) {
+ if (sourceFormatter == null) {
+ sourceFormatter = super.getSourceFormatter(lang);
+ }
+ return sourceFormatter;
+ }
+
+ @Override
+ public ISourceHyperlinkDetector getSourceHyperlinkDetector(Language lang) {
+ if (sourceHyperlinkDetector == null) {
+ sourceHyperlinkDetector = super.getSourceHyperlinkDetector(lang);
+ }
+ return sourceHyperlinkDetector;
+ }
+
+ @Override
+ public ILabelProvider getLabelProvider(Language lang) {
+ if (labelProvider == null) {
+ labelProvider = super.getLabelProvider(lang);
+ }
+ return labelProvider;
+ }
+
+ @Override
+ public OutlineContentProviderBase getOutlineContentProvider(Language lang) {
+ if (outlineContentProvider == null) {
+ outlineContentProvider = super.getOutlineContentProvider(lang);
+ }
+ return outlineContentProvider;
+ }
+
+ @Override
+ public Set<IRefactoringContributor> getRefactoringContributors(Language lang) {
+ if (refactoringContributors == null) {
+ refactoringContributors = super.getRefactoringContributors(lang);
+ }
+ return refactoringContributors;
+ }
+
+ @Override
+ public IReferenceResolver getReferenceResolver(Language lang) {
+ if (referenceResolver == null) {
+ referenceResolver = super.getReferenceResolver(lang);
+ }
+ return referenceResolver;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Set<ILanguageActionsContributor> getLanguageActionsContributors(Language lang) {
+ if (languageActionsContributors == null) {
+ languageActionsContributors = super
+ .getLanguageActionsContributors(lang);
+ }
+ return languageActionsContributors;
+ }
+
+ @Override
+ public IDocumentationProvider getDocumentationProvider(Language lang) {
+ if (documentationProvider == null) {
+ documentationProvider = super.getDocumentationProvider(lang);
+ }
+ return documentationProvider;
+ }
+
+ @Override
+ public IOccurrenceMarker getOccurrenceMarker(Language lang) {
+ if (occurrenceMarker == null) {
+ occurrenceMarker = super.getOccurrenceMarker(lang);
+ }
+ return occurrenceMarker;
+ }
+
+ @Override
+ public ILanguageSyntaxProperties getSyntaxProperties(Language lang) {
+ if (syntaxProperties == null) {
+ syntaxProperties = super.getSyntaxProperties(lang);
+ }
+ return syntaxProperties;
+ }
+
+ @Override
+ public IElementImageProvider getElementImageProvider(Language lang) {
+ if (elementImageProvider == null) {
+ elementImageProvider = super.getElementImageProvider(lang);
+ }
+ return elementImageProvider;
+ }
+
+ @Override
+ public IOutliner getOutliner(Language lang) {
+ if (outliner == null) {
+ outliner = super.getOutliner(lang);
+ }
+ return outliner;
+ }
+
+ @Override
+ public IASTAdapter getASTAdapter(Language lang) {
+ if (astAdapter == null) {
+ astAdapter = super.getASTAdapter(lang);
+ }
+ return astAdapter;
+ }
+
+ @Override
+ public IEntityNameLocator getEntityNameLocator(Language lang) {
+ if (entityNameLocator == null) {
+ entityNameLocator = super.getEntityNameLocator(lang);
+ }
+ return entityNameLocator;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/ILanguageService.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/ILanguageService.java
new file mode 100644
index 000000000..80f41c590
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/ILanguageService.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.language;
+
+
+/*
+ * Licensed Materials - Property of IBM, (c) Copyright IBM Corp. 1998, 2004 All
+ * Rights Reserved
+ */
+
+/**
+ * This interface is to be implemented by language services used by IMP
+ */
+public interface ILanguageService {
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/Language.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/Language.java
new file mode 100644
index 000000000..e50dc70fb
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/Language.java
@@ -0,0 +1,288 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.language;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.imp.core.ErrorHandler;
+
+/**
+ * @author Claffra
+ * @author jurgen@vinju.org
+ *
+ * API representation for org.eclipse.imp.runtime.languageDescription
+ * contributor. Used by org.eclipse.imp.language.LanguageRegistry to discover and
+ * manage a language registry.
+ */
+public class Language {
+ /**
+ * Extension element attribute ID for the language ID associated with a
+ * given language descriptor.
+ */
+ public static final String LANGUAGE_ID_ATTR = "language";
+
+ private String fLanguage;
+
+ /**
+ * Extension element attribute ID for the base language ID associated with a
+ * given language descriptor.
+ */
+ public static final String DERIVED_FROM_ATTR = "derivedFrom";
+
+ private String fDerivedFrom;
+
+ /**
+ * Extension element attribute ID for the list of file-name extensions
+ * associated with a given language descriptor.
+ */
+ public static final String EXTENSIONS_ATTR = "extensions";
+
+ private Collection<String> fFilenameExtensions;
+
+ /**
+ * Extension element attribute ID for the validator associated with a given
+ * language descriptor.
+ */
+ public static final String VALIDATOR_ATTR = "validator";
+
+ private LanguageValidator fValidator;
+
+ /**
+ * Extension element attribute ID for the user-readable description of a
+ * given language descriptor.
+ */
+ public static final String DESCRIPTION_ATTR = "description";
+
+ private String fDescription;
+
+ /**
+ * Extension element attribute ID for the optional nature ID associated with
+ * a given language descriptor.
+ */
+ public static final String NATURE_ID_ATTR = "natureID";
+
+ private String fNatureId;
+
+ /**
+ * Extension element attribute ID for the optional list of synonyms
+ * associated with a given language descriptor.
+ */
+ public static final String SYNONYMS_ATTR = "synonyms";
+
+ private Collection<String> fSynonyms;
+
+ /**
+ * Extension element attribute ID for the optional icon associated with a
+ * given language descriptor.
+ */
+ public static final String ICON_ATTR = "icon";
+
+ private String fIconPath;
+
+ /**
+ * Extension element attribute ID for the optional URL associated with a
+ * given language descriptor.
+ */
+ public static final String URL_ATTR = "url";
+
+ private String fURL;
+
+ private String fBundleID;
+
+ /**
+ * Creates a language from an extension point contribution
+ *
+ * @param element the extension point contribution this language belongs to
+ */
+ Language(IConfigurationElement element) {
+ try {
+ fLanguage = element.getAttribute(LANGUAGE_ID_ATTR);
+ fNatureId = element.getAttribute(NATURE_ID_ATTR);
+ fDescription = element.getAttribute(DESCRIPTION_ATTR);
+ fDerivedFrom = element.getAttribute(DERIVED_FROM_ATTR);
+ fIconPath = element.getAttribute(ICON_ATTR);
+ fBundleID = element.getNamespaceIdentifier();
+ fURL = element.getAttribute(URL_ATTR);
+ fFilenameExtensions = parseList(element.getAttribute(EXTENSIONS_ATTR));
+ fSynonyms = parseList(element.getAttribute(SYNONYMS_ATTR));
+ fValidator = (LanguageValidator) element.createExecutableExtension(VALIDATOR_ATTR);
+ } catch (CoreException e) {
+ fValidator = null;
+ }
+ }
+
+ public Language(String language, String natureId, String description,
+ String derivedFrom, String iconPath, String url, String bundleID, String fileNameExtensions,
+ String synonyms, LanguageValidator validator) {
+ this.fLanguage = language;
+ this.fNatureId = natureId;
+ this.fDescription = description;
+ this.fDerivedFrom = derivedFrom;
+ this.fIconPath = iconPath;
+ this.fBundleID = bundleID;
+ this.fURL = url;
+ this.fFilenameExtensions = parseList(fileNameExtensions);
+ this.fSynonyms = parseList(synonyms);
+ this.fValidator = validator;
+ }
+
+ /**
+ * Gets the canonical name for this language
+ *
+ * @return the canonical language name
+ */
+ public String getName() {
+ return fLanguage;
+ }
+
+ public String getNatureID() {
+ return fNatureId;
+ }
+
+ /**
+ * Gets a human-readable description of the language. Not used for
+ * discovery.
+ *
+ * @return a description for this language
+ */
+ public String getDescription() {
+ return fDescription;
+ }
+
+ /**
+ * Returns the language this language is derived from. For example, HTML is
+ * derived from XML.
+ *
+ * @return the canonical language name this language is derived from
+ */
+ public String getDerivedFrom() {
+ return fDerivedFrom;
+ }
+
+ /**
+ * Returns the file path to the icon to be used for source files in this language
+ *
+ * @return the file path to the icon for this language
+ */
+ public String getIconPath() {
+ return fIconPath;
+ }
+
+ /**
+ * @return the ID of the bundle containing the language descriptor and icon for this language
+ */
+ public String getBundleID() {
+ return fBundleID;
+ }
+
+ /**
+ * Returns the website with more information about this language
+ *
+ * @return something like http://www.php.org
+ */
+ public String getUrl() {
+ return fURL;
+ }
+
+ /**
+ * Returns whether this language supports a given file extension. If the
+ * language is "Java", hasExtension("java") yields true.
+ *
+ * @param extension
+ * the file extension (excluding the '.')
+ * @return
+ */
+ public boolean hasExtension(String extension) {
+ return fFilenameExtensions.contains(extension);
+ }
+
+ /**
+ * Returns the file extensions that are customary for this language.
+ *
+ */
+ public Collection<String> getFilenameExtensions() {
+ return fFilenameExtensions;
+ }
+
+ /**
+ * Returns the synonyms for the canonical name of this language. If the
+ * language is "Pascal", its synonyms could be "PASCAL,pascal"
+ *
+ * @return comma-separated list of synonyms
+ */
+ @Deprecated public Collection<String> getSynonyms() {
+ return fSynonyms;
+ }
+
+ /**
+ * A convenience method for
+ * LanguageRegistry.findLanguage(lang.getDerivedFrom()).
+ *
+ * @return the base Language, if known to the LanguageRegistry; otherwise,
+ * null
+ */
+ public Language getBaseLanguage() {
+ String baseLangName = getDerivedFrom();
+ if (baseLangName != null) {
+ return LanguageRegistry.findLanguage(baseLangName);
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns an instance of a class that can validate a given IFile to ensure
+ * its contents is really for this language. For instance, Ant build files
+ * have extension "xml". However, when opening any XML file, possible
+ * candidates need to be consulted to verify the actual content before
+ * activating the corresponding language services.
+ *
+ * @return the language validator instance, if declared by the contributor
+ * @return null if no validator was specified
+ */
+ public LanguageValidator getValidator() {
+ return fValidator;
+ }
+
+ /*
+ * Convert "cxx, cpp,hxx, hpp " into ["cxx", "cpp", "hxx", "hpp"]
+ */
+ protected Collection<String> parseList(String list) {
+ Collection<String> result = new ArrayList<String>();
+
+ if (list != null) {
+ StringTokenizer st = new StringTokenizer(list, ",");
+
+ for (int n = 0; st.hasMoreElements(); n++) {
+ String exten = st.nextToken().trim();
+
+ if (exten.startsWith(".")) {
+ ErrorHandler.logMessage("Ignoring leading '.' in file-name extension "
+ + exten + " for language '" + getName() + "'.", null);
+ exten = exten.substring(1);
+ }
+ result.add(exten);
+ }
+ }
+ return result;
+ }
+
+ public String toString() {
+ return "Language[name=" + getName() + ",description="
+ + getDescription() + ",filename extensions="
+ + getFilenameExtensions() + "]";
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/LanguageRegistry.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/LanguageRegistry.java
new file mode 100644
index 000000000..043c8ee1f
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/LanguageRegistry.java
@@ -0,0 +1,531 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.language;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.InvalidRegistryObjectException;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.imp.core.ErrorHandler;
+import org.eclipse.imp.editor.EditorInputUtils;
+import org.eclipse.imp.editor.UniversalEditor;
+import org.eclipse.imp.preferences.PreferenceCache;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorMatchingStrategy;
+import org.eclipse.ui.IFileEditorMapping;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.internal.registry.EditorDescriptor;
+import org.eclipse.ui.internal.registry.EditorRegistry;
+import org.eclipse.ui.internal.registry.FileEditorMapping;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.osgi.framework.Bundle;
+
+/**
+ * @author Claffra
+ * @author rfuhrer@watson.ibm.com
+ * @author jurgen@vinju.org
+ * @author Stan Sutton (suttons@us.ibm.com)
+ *
+ * Registry for IMP language contributors.
+ */
+@SuppressWarnings("restriction")
+public class LanguageRegistry {
+ private static final String EXTENSION = "languageDescription";
+
+ private static Object sStatusCheckMutex = new Object();
+ private static boolean sIsFullyInitialized = false;
+
+ private static Map<String, Language> sRegister;
+
+ private static IEditorDescriptor sUniversalEditor;
+
+ private static EditorRegistry sEditorRegistry;
+
+ /*
+ * No one should instantiate this class.
+ * TODO: Perhaps should be a singleton class.
+ */
+ private LanguageRegistry() {}
+
+ private static Map<String, Language> getRegister() {
+ if(sRegister == null) {
+ sRegister = new HashMap<String, Language>();
+ }
+ return sRegister;
+ }
+
+ /**
+ * Initialize the registry. Discover all contributors to the
+ * languageDescription extension point. The registry will not be fully
+ * initialized until the registerLanguages() method has been called.
+ */
+ private static void preInitEditorRegistry() {
+ try {
+ sEditorRegistry = (EditorRegistry) PlatformUI.getWorkbench().getEditorRegistry();
+ initializeUniversalEditorDescriptor(sEditorRegistry);
+
+ IExtensionPoint extensionPoint =
+ Platform.getExtensionRegistry().getExtensionPoint(RuntimePlugin.IMP_RUNTIME, EXTENSION);
+
+ if (extensionPoint == null) {
+ ErrorHandler.reportError("Nonexistent extension point called \"" +
+ RuntimePlugin.IMP_RUNTIME + "." + EXTENSION);
+ } else {
+ IConfigurationElement[] elements = extensionPoint.getConfigurationElements();
+
+ if (elements != null) {
+ for (IConfigurationElement element : elements) {
+ Bundle bundle = Platform.getBundle(element.getDeclaringExtension().getNamespaceIdentifier());
+
+ if (bundle != null) {
+ register(new Language(element));
+ }
+ }
+ }
+ }
+ } catch (InvalidRegistryObjectException e) {
+ if (PreferenceCache.emitMessages) {
+ RuntimePlugin.getInstance().writeErrorMsg(
+ "IMP LanguageRegistry error in preInitEditorRegistry(): InvalidRegistryObjectException: " + e);
+ } else {
+ ErrorHandler.reportError("IMP LanguageRegistry error", e);
+ }
+ }
+ }
+
+ /**
+ * Returns the language description for a given editor input. First the file
+ * extension is used to discover registered languages. Then each language is
+ * used to ensure it actually supports the content of the file.
+ *
+ * @param editorInput
+ * the editorInput to be opened
+ * @return the contributed language description
+ * @return null if no language is contributed with the given
+ * extension/content
+ */
+ public static Language findLanguage(IEditorInput editorInput, IDocumentProvider docProvider) {
+ if (!sIsFullyInitialized)
+ initializeRegistryAsNeeded();
+ IPath path= EditorInputUtils.getPath(editorInput);
+
+ return findLanguage(path, docProvider.getDocument(editorInput));
+ }
+
+ /**
+ * Determine the source language contained by the resource at the given
+ * path.
+ *
+ * @param path
+ * @param file if non-null, may be used to validate the contents of the file
+ * (e.g. to distinguish dialects)
+ * @return
+ */
+ public static Language findLanguage(IPath path, IDocument doc) {
+ // TODO: use Eclipse content type instead
+ if (!isFullyInitialized())
+ initializeRegistryAsNeeded();
+ String extension= path.getFileExtension();
+ String docContents= (doc != null) ? doc.get() : null;
+
+ // N.B. It's ok for multiple language descriptors to specify the same
+ // file name extension; the associated validators should use the file
+ // contents to identify the dialects.
+ if (extension != null) {
+ for (Language lang : getRegister().values()) {
+ if (lang.hasExtension(extension)) {
+ LanguageValidator validator = lang.getValidator();
+
+ if (validator != null && docContents != null) {
+ if (validator.validate(docContents)) {
+ return lang;
+ }
+ } else {
+ return lang;
+ }
+ }
+ }
+ }
+
+ if (PreferenceCache.emitMessages) {
+ RuntimePlugin.getInstance().writeErrorMsg("No language support for text/source file of type '" +
+ extension + "'.");
+ } else {
+ ErrorHandler.reportError("No language support for text/source file of type '" +
+ extension + "'.");
+ }
+
+ return null;
+ }
+
+ public static Language findLanguageByNature(String natureID) {
+ if (!isFullyInitialized())
+ initializeRegistryAsNeeded();
+ for (Language lang : getRegister().values()) {
+ String aNatureID = lang.getNatureID();
+
+ if (aNatureID != null && aNatureID.equals(natureID)) {
+ return lang;
+ }
+ }
+ return null;
+ }
+
+ public static Collection<Language> getLanguages() {
+ if (!isFullyInitialized())
+ initializeRegistryAsNeeded();
+ return Collections.unmodifiableCollection(getRegister().values());
+ }
+
+ public static Language findLanguage(String languageName) {
+ if (!isFullyInitialized())
+ initializeRegistryAsNeeded();
+ return getRegister().get(languageName.toLowerCase());
+ }
+
+
+ /**
+ * Registers a language dynamically (as opposed to using an extension
+ * point). This binds the file extensions associated with the language to
+ * the IMP Universal editor.
+ *
+ * @param language
+ */
+ public static void registerLanguage(Language language) {
+ if (!isFullyInitialized())
+ initializeRegistryAsNeeded();
+ register(language);
+
+ List<IFileEditorMapping> mappings = new ArrayList<IFileEditorMapping>();
+ Collections.addAll(mappings, getEditorRegistry().getFileEditorMappings());
+ addUniversalEditorMappings(language.getName(), language.getIconPath(), language.getFilenameExtensions(), language.getBundleID(), mappings);
+ updateEditorRegistry(mappings);
+ }
+
+ private static EditorRegistry getEditorRegistry() {
+ return sEditorRegistry;
+ }
+
+ /**
+ * Removes stale registrations and then registers all languages declared
+ * using the IMP languageDescription extension point. The file extensions of
+ * all registered languages are bound to the IMP universal editor.
+ *
+ * This method is called at earlyStartup time to initialize the registry.
+ * It is also called from within UniversalEditor.createPartControl(..)
+ * (probably as a way to make sure that the registry is initialized if it
+ * hasn't been already). It is also called from various accessor methods
+ * of the LanguageRegistry class to similarly assure that the registry is
+ * initialized.
+ *
+ * To prevent thread access errors and other possible concurrency conflicts,
+ * this method executes within a synchronized block. It both tests and sets
+ * isFullyInitialized within this block, as a means to assure that the registry
+ * will be initialized serially and only once. Although isFullyInitialized
+ * can be tested from anywhere, this is the only place that it should be set.
+ */
+ public static void initializeRegistryAsNeeded() {
+ synchronized(sStatusCheckMutex) {
+ if(isFullyInitialized()) {
+ return;
+ }
+ preInitEditorRegistry();
+
+ if (PreferenceCache.emitMessages) {
+ RuntimePlugin.getInstance().writeInfoMsg(
+ "Looking for IMP language description extensions...");
+ }
+
+// List<String> langExtens= collectAllLanguageFileNameExtensions();
+ List<IFileEditorMapping> newMap = new ArrayList<IFileEditorMapping>();
+
+ addNonUniversalEditorMappings(newMap);
+ for(Language lang : getRegister().values()) {
+ addUniversalEditorMappings(lang.getName(), lang.getIconPath(), lang.getFilenameExtensions(), lang.getBundleID(), newMap);
+ }
+ updateEditorRegistry(newMap);
+
+ setFullyInitialized();
+ }
+ }
+
+ private static void addNonUniversalEditorMappings(List<IFileEditorMapping> newMap) {
+ for (IFileEditorMapping mapping : getEditorRegistry().getFileEditorMappings()) {
+ IEditorDescriptor defaultEditor = mapping.getDefaultEditor();
+ if (defaultEditor == null
+ || !defaultEditor.getId().equals(UniversalEditor.EDITOR_ID)) {
+ newMap.add(mapping);
+ }
+ }
+ }
+
+ public static class BundleImageDescriptor extends ImageDescriptor {
+ private final Bundle bundle;
+ private final String iconPath;
+ private final String langName;
+
+ public BundleImageDescriptor(String iconPath, Bundle bundle, String langName) {
+ this.langName= langName;
+ this.bundle= bundle;
+ this.iconPath= iconPath;
+ }
+
+ @Override
+ public ImageData getImageData() {
+ InputStream in = getStream();
+ ImageData result = null;
+ if (in != null) {
+ try {
+ result = new ImageData(in);
+ } catch (SWTException e) {
+ if (e.code != SWT.ERROR_INVALID_IMAGE) {
+ throw e;
+ // fall through otherwise
+ }
+ } finally {
+ try {
+ in.close();
+ } catch (IOException e) {
+ //System.err.println(getClass().getName()+".getImageData(): "+
+ // "Exception while closing InputStream : "+e);
+ }
+ }
+ }
+ return result;
+ }
+
+ private InputStream getStream() {
+ InputStream is = null;
+
+ try {
+ if (this.iconPath != null) {
+ is = bundle.getResource(iconPath).openStream();
+ }
+ } catch (IOException e) {
+ RuntimePlugin.getInstance().logException("Unable to find icon for language " + langName, e);
+ return null;
+ }
+
+ if (is == null) {
+ return null;
+ } else {
+ return new BufferedInputStream(is);
+ }
+ }
+ }
+
+ private static class IMPFileEditorMapping extends FileEditorMapping {
+ private ImageDescriptor fImageDescriptor;
+ private IEditorDescriptor fEditor;
+
+ public IMPFileEditorMapping(final String langName, String extension, final String iconPath, String bundleID) {
+ super(extension);
+ final Bundle bundle= Platform.getBundle(bundleID);
+ fImageDescriptor= new BundleImageDescriptor(iconPath, bundle, langName);
+ }
+
+ public void setTheDefaultEditor(IEditorDescriptor editor) {
+ fEditor= editor;
+ }
+
+ @Override
+ public IEditorDescriptor getDefaultEditor() {
+ return fEditor;
+ }
+
+ @Override
+ public ImageDescriptor getImageDescriptor() {
+ return fImageDescriptor;
+ }
+ }
+
+ /**
+ * Adds new mappings to the universal editor for a set of extensions
+ * @param extensions
+ * @param newMap
+ */
+ private static void addUniversalEditorMappings(String langName, String langIcon,
+ Iterable<String> extensions, String bundleID, List<IFileEditorMapping> newMap) {
+ IFileEditorMapping[] mappings= sEditorRegistry.getFileEditorMappings();
+ // RMF 3/25/2009 - There doesn't seem to be a way to set the editor's label
+ // programmatically; (1) IEditorDescriptor doesn't expose enough API, (2) the
+ // EditorDescriptor ctor is not visible, (3) the class EditorDescriptor is final,
+ // (4) getEditorRegistry().setFileEditorMappings() will only accept an array
+ // of FileEditorMappings, and (5) FileEditorMapping requires an EditorDescriptor.
+
+ for (String ext : extensions) {
+ IFileEditorMapping mapping= findMappingFor(ext, mappings);
+
+ if (mapping == null || mapping.getDefaultEditor().getId().equals(sUniversalEditor.getId())) {
+ // Replace the file editor mapping even if it already pointed to the universal editor,
+ // since the persisted association turns into a FileEditorMapping when re-read, thus
+ // losing the icon (which FileEditorMapping gets from the IEditorDescriptor).
+ mapping= new IMPFileEditorMapping(langName, ext, langIcon, bundleID);
+ }
+ IEditorDescriptor defaultEditor= mapping.getDefaultEditor();
+
+ if (defaultEditor == null || defaultEditor.getId().equals("")) {
+ ((FileEditorMapping) mapping).setDefaultEditor((EditorDescriptor) sUniversalEditor);
+ } else {
+ // SMS 19 Nov 2008
+ // Revised else branch according to patch provided by Edward Willink
+ // Bug #242967, attachment id=109002
+ boolean gotIt = false;
+ for (IEditorDescriptor editor : mapping.getEditors()) {
+ if (editor == sUniversalEditor) {
+ gotIt = true;
+ break;
+ }
+ }
+ if (!gotIt) {
+ for (IEditorDescriptor editor : mapping.getEditors()) { // Search for an implicit copy of a derived UniversalEditor
+ EditorDescriptor editorDescriptor = (EditorDescriptor) editor;
+ String className = editorDescriptor.getClassName();
+ IConfigurationElement configurationElement = editorDescriptor.getConfigurationElement();
+ IExtension declaringExtension = configurationElement.getDeclaringExtension();
+ String namespaceIdentifier = declaringExtension.getNamespaceIdentifier();
+ Bundle bundle = Platform.getBundle(namespaceIdentifier);
+ try {
+ Class<?> editorClass = bundle.loadClass(className);
+ if (UniversalEditor.class.isAssignableFrom(editorClass)) {
+ gotIt = true;
+ break;
+ }
+ } catch (ClassNotFoundException e) {
+ }
+ }
+ }
+ if (!gotIt)
+ ((FileEditorMapping) mapping).addEditor((EditorDescriptor) sUniversalEditor);
+ }
+ newMap.add(mapping);
+ }
+ }
+
+ private void addEditorIfNeeded(IMPFileEditorMapping fem, EditorDescriptor editor) {
+ // SMS 19 Nov 2008
+ // Revised else branch according to patch provided by Edward Willink
+ // Bug #242967, attachment id=109002
+ boolean gotIt = false;
+ for (IEditorDescriptor fileEditor : fem.getEditors()) {
+ if (fileEditor.getId().equals(editor.getId())) {
+ gotIt = true;
+ break;
+ }
+ }
+ if (!gotIt) {
+ fem.addEditor(editor);
+ }
+ }
+
+ private static IFileEditorMapping findMappingFor(String ext, IFileEditorMapping[] mappings) {
+ for(int i= 0; i < mappings.length; i++) {
+ if (mappings[i].getExtension().equals(ext)) {
+ return mappings[i];
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ * Commits a new list of editor mappings to the editorRegistry
+ * @param newMap
+ */
+ private static void updateEditorRegistry(final List<IFileEditorMapping> newMap) {
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+ getEditorRegistry().setFileEditorMappings(newMap.toArray(new FileEditorMapping[newMap.size()]));
+ // TODO Do we really want to save the associations persistently?
+ getEditorRegistry().saveAssociations();
+ }
+ });
+ }
+
+ private static List<String> collectAllLanguageFileNameExtensions() {
+ List<String> allExtens = new ArrayList<String>(getRegister().size());
+
+ for (Language lang : getRegister().values()) {
+ allExtens.addAll(lang.getFilenameExtensions());
+ }
+
+ return allExtens;
+ }
+
+ private static void initializeUniversalEditorDescriptor(EditorRegistry editorRegistry) {
+ final IEditorDescriptor[] allEditors = editorRegistry.getSortedEditorsFromPlugins();
+
+ for (IEditorDescriptor editor : allEditors) {
+ if (editor.getId().equals(UniversalEditor.EDITOR_ID)) {
+ sUniversalEditor = editor;
+
+ if (PreferenceCache.emitMessages) {
+ RuntimePlugin.getInstance().writeInfoMsg(
+ "Universal editor descriptor: " +
+ sUniversalEditor.getId() + ":" +
+ sUniversalEditor.getLabel());
+ }
+ return;
+ }
+ }
+
+ if (sUniversalEditor == null) {
+ if (PreferenceCache.emitMessages) {
+ RuntimePlugin.getInstance().writeErrorMsg(
+ "IMP LanguageRegistry error in initializeUniversalEditorDescroptor(): unable to initialize Universal Editor");
+ } else {
+ ErrorHandler.reportError(
+ "Unable to locate Universal Editor descriptor", null);
+ }
+ }
+ }
+
+ private static void register(Language language) {
+ getRegister().put(language.getName().toLowerCase(), language);
+
+ if (PreferenceCache.emitMessages) {
+ RuntimePlugin.getInstance().writeInfoMsg(
+ "Registered language description: " + language.getName());
+ }
+ }
+
+
+ private static void setFullyInitialized() {
+ sIsFullyInitialized = true;
+ }
+
+ private static boolean isFullyInitialized() {
+ return sIsFullyInitialized;
+ }
+
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/LanguageValidator.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/LanguageValidator.java
new file mode 100644
index 000000000..71aa13d98
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/LanguageValidator.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.language;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.imp.core.ErrorHandler;
+
+/*
+ * Licensed Materials - Property of IBM,
+ * (c) Copyright IBM Corp. 2005 All Rights Reserved
+ */
+
+/**
+ * @author Claffra
+ *
+ * The interface to be implemented by contributors of the org.eclipse.imp.runtime.languageDescription extension point.
+ */
+public abstract class LanguageValidator {
+
+ /**
+ * Validate a given file in a given project whether it implements the programming language
+ * defined in this extension point contribution. For most languages, a quick check to the
+ * project nature would be sufficient. For others, the file may have to be opened to verify
+ * its contents.
+ *
+ * @param file the file to be opened
+ * @return whether the file actually contains text for this programming language
+ */
+ public abstract boolean validate(IFile file);
+
+ /**
+ * Validate a given text buffer whether it implements the programming language
+ * defined in this extension point contribution.
+ *
+ * @param buffer the contents to be verified
+ * @return whether the text actually matches this programming language
+ */
+ public abstract boolean validate(String buffer);
+
+ /**
+ * See if this file contains a given search string. Warning: may cause
+ * excessive reading if files are large.
+ * @param file the file to check
+ * @param searchString the unique string to search for
+ * @return whether the file contains the given search string
+ */
+ protected boolean contains(IFile file, String searchString) {
+ try {
+ DataInputStream is = new DataInputStream(file.getContents());
+ byte bytes[] = new byte[is.available()];
+ is.readFully(bytes);
+ String contents = new String(bytes);
+ return contents.indexOf(searchString) != -1;
+ }
+ catch (CoreException e) {
+ return false;
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ /**
+ * See if the project has a given nature added to it.
+ * @param project the project to check
+ * @param natureId the id of the nature
+ * @return whether the project has the nature added to it
+ */
+ protected boolean hasNature(IProject project, String natureId) {
+ try {
+ return project.getNature(natureId) != null;
+ }
+ catch (CoreException e) {
+ ErrorHandler.reportError("LanguageValidator Error", e);
+ return false;
+ }
+ }
+
+ /**
+ * Get the natures for this project
+ * @param project the project to inspect
+ * @return the list of nature ids for this project
+ */
+ protected String[] getNatures(IProject project) {
+ try {
+ return project.getDescription().getNatureIds();
+ }
+ catch (CoreException e) {
+ ErrorHandler.reportError("LanguageValidator Error", e);
+ return new String[0];
+ }
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/ServiceFactory.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/ServiceFactory.java
new file mode 100644
index 000000000..6efd52b24
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/language/ServiceFactory.java
@@ -0,0 +1,556 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.language;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.imp.editor.OutlineContentProviderBase;
+import org.eclipse.imp.editor.OutlineLabelProvider.IElementImageProvider;
+import org.eclipse.imp.indexing.IndexContributorBase;
+import org.eclipse.imp.parser.IModelListener;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.imp.services.IASTAdapter;
+import org.eclipse.imp.services.IAnnotationHover;
+import org.eclipse.imp.services.IAutoEditStrategy;
+import org.eclipse.imp.services.IContentProposer;
+import org.eclipse.imp.services.IDocumentationProvider;
+import org.eclipse.imp.services.IEntityImageDecorator;
+import org.eclipse.imp.services.IEntityNameLocator;
+import org.eclipse.imp.services.IFoldingUpdater;
+import org.eclipse.imp.services.IHelpService;
+import org.eclipse.imp.services.IHoverHelper;
+import org.eclipse.imp.services.ILabelProvider;
+import org.eclipse.imp.services.ILanguageActionsContributor;
+import org.eclipse.imp.services.ILanguageSyntaxProperties;
+import org.eclipse.imp.services.IOccurrenceMarker;
+import org.eclipse.imp.services.IOutliner;
+import org.eclipse.imp.services.IRefactoringContributor;
+import org.eclipse.imp.services.IReferenceResolver;
+import org.eclipse.imp.services.ISourceFormatter;
+import org.eclipse.imp.services.ISourceHyperlinkDetector;
+import org.eclipse.imp.services.IToggleBreakpointsHandler;
+import org.eclipse.imp.services.ITokenColorer;
+import org.eclipse.imp.services.base.TreeModelBuilderBase;
+import org.eclipse.imp.utils.ExtensionException;
+import org.eclipse.imp.utils.ExtensionFactory;
+
+/**
+ * This class stores language services. IMP services are configured with
+ * language specific extension points. This registry provides implementations
+ * for them. It finds the implementations by looking for Eclipse extensions for
+ * IMP's extension points.
+ *
+ * If IMP is extended with a new kind of language service, this class must be
+ * extended.
+ *
+ * The getter methods of this class return 'null' when a service does not exist
+ * (i.e. an extension has not been provided yet)
+ *
+ * The getter methods of this class will throw unchecked exceptions when the
+ * extension implementations are not well formed.
+ *
+ * The getter methods only load the extension implementations the first time
+ * somebody asks for them. After that they are cached in the registry. This lazy
+ * behavior is necessary to optimize the startup time of Eclipse.
+ *
+ * @author jurgenv
+ */
+public class ServiceFactory {
+ private static ServiceFactory sInstance;
+
+ /**
+ * The unqualified extension point ID for IMP language descriptors.
+ */
+ public static final String LANGUAGE_DESCRIPTION_POINT_ID = "languageDescription";
+
+ /**
+ * The qualified extension point ID for IMP language descriptors.
+ */
+ public static final String LANGUAGE_DESCRIPTION_QUALIFIED_POINT_ID = RuntimePlugin.IMP_RUNTIME + ".languageDescription";
+
+ static final String AUTO_EDIT_STRATEGY_SERVICE = "autoEditStrategy";
+
+ static final String ANNOTATION_HOVER_SERVICE = "annotationHover";
+
+ static final String AST_ADAPTER_SERVICE = "astAdapter";
+
+ static final String CONTENT_PROPOSER_SERVICE = "contentProposer";
+
+ static final String CONTEXT_HELPER_SERVICE= "contextHelper";
+
+ static final String DOCUMENTATION_PROVIDER_SERVICE = "documentationProvider";
+
+ static final String EDITOR_ACTION_CONTRIBUTIONS_SERVICE = "editorActionContributions";
+
+ static final String EDITOR_SERVICE= "editorService";
+
+ static final String ENTITY_IMAGE_DECORATOR_SERVICE = "entityImageDecorator";
+
+ static final String ENTITY_NAME_LOCATOR_SERVICE = "entityNameLocator";
+
+ static final String FOLDING_UPDATER_SERVICE = "foldingUpdater";
+
+ static final String FORMATTER_SERVICE = "formatter";
+
+ static final String HOVER_HELPER_SERVICE = "hoverHelper";
+
+ static final String HYPER_LINK_SERVICE = "hyperLink";
+
+ static final String IMAGE_DECORATOR_SERVICE = "imageDecorator";
+
+ static final String INDEX_CONTRIBUTOR_SERVICE = "indexContributor";
+
+ static final String LABEL_PROVIDER_SERVICE = "labelProvider";
+
+ static final String MODEL_LISTENER_SERVICE = "modelListener";
+
+ static final String MODEL_TREE_BUILDER_SERVICE = "modelTreeBuilder";
+
+ static final String MARK_OCCURRENCES_SERVICE = "markOccurrences";
+
+ static final String OUTLINE_CONTENT_PROVIDER_SERVICE = "outlineContentProvider";
+
+ static final String OUTLINER_SERVICE = "outliner";
+
+ static final String PARSER_SERVICE = "parser";
+
+ static final String PREFERENCES_SERVICE = "preferencesDialog";
+
+ static final String PREFERENCES_SPECIFICATION = "preferencesSpecification";
+
+ static final String REFACTORING_CONTRIBUTIONS_SERVICE = "refactoringContributions";
+
+ static final String REFERENCE_RESOLVER_SERVICE = "referenceResolvers";
+
+ static final String SYNTAX_PROPS_SERVICE = "syntaxProps";
+
+ static final String TOGGLE_BREAKPOINTS_HANDLER_SERVICE= "toggleBreakpointHandler";
+
+ static final String TOKEN_COLORER_SERVICE = "tokenColorer";
+
+ static final String VIEWER_FILTER_SERVICE = "viewerFilter";
+
+ /**
+ * The list of fully-qualified extension point IDs for all IMP language services.
+ * Does not include the language descriptor extension point ID.
+ */
+ public static final List<String> ALL_SERVICES= new LinkedList<String>();
+
+ static {
+ Class<ServiceFactory> clazz= ServiceFactory.class;
+ Field[] fields= clazz.getDeclaredFields();
+ for(int i= 0; i < fields.length; i++) {
+ Field field= fields[i];
+ if (field.getName().endsWith("_SERVICE") && Modifier.isStatic(field.getModifiers())) {
+ try {
+ String val= (String) field.get(null);
+ ALL_SERVICES.add(RuntimePlugin.IMP_RUNTIME + "." + val);
+ } catch (IllegalArgumentException e) {
+ } catch (IllegalAccessException e) {
+ }
+ }
+ }
+ }
+
+ protected ServiceFactory() { }
+
+ /**
+ * Returns the {@link ServiceFactory}. IMP services are configured with
+ * language specific extension points. This registry provides the
+ * implementations for them. This class finds these implementations via
+ * Eclipse's extension point mechanism.
+ *
+ * @return
+ */
+ public static ServiceFactory getInstance() {
+ if (sInstance == null) {
+ sInstance = new ServiceFactory();
+ }
+ return sInstance;
+ }
+
+ public static ServiceFactory otherGetInstance() {
+ return sInstance;
+ }
+
+ public IAnnotationHover getAnnotationHover(Language lang) {
+ try {
+ return (IAnnotationHover) loadService(lang, ANNOTATION_HOVER_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of ANNOTATION_HOVER_SERVICE does not implement IAnnotationHover",
+ e);
+ return null;
+ }
+ }
+
+ public IASTAdapter getASTAdapter(Language lang) {
+ try {
+ return (IASTAdapter) loadService(lang, AST_ADAPTER_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of AST_ADAPTER_SERVICE does not implement IASTAdapter",
+ e);
+ return null;
+ }
+ }
+
+ public Set<IAutoEditStrategy> getAutoEditStrategies(Language lang) {
+ try {
+ Set<ILanguageService> services = loadServices(lang, AUTO_EDIT_STRATEGY_SERVICE);
+ Set<IAutoEditStrategy> autoEditStrategies = new HashSet<IAutoEditStrategy>();
+
+ for (ILanguageService s : services) {
+ autoEditStrategies.add((IAutoEditStrategy) s);
+ }
+
+ return autoEditStrategies;
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of AUTO_EDIT_SERVICE does not implement IAutoEditStrategy",
+ e);
+ return null;
+ }
+ }
+
+ public IContentProposer getContentProposer(Language lang) {
+ try {
+ return (IContentProposer) loadService(lang, CONTENT_PROPOSER_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of CONTENT_PROPOSER_SERVICE does not implement IContentProposer",
+ e);
+ return null;
+ }
+ }
+
+ public IHelpService getContextHelper(Language lang) {
+ try {
+ return (IHelpService) loadService(lang, CONTEXT_HELPER_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of CONTEXT_HELPER_SERVICE does not implement IHelpService",
+ e);
+ return null;
+ }
+ }
+
+ public IDocumentationProvider getDocumentationProvider(Language lang) {
+ try {
+ return (IDocumentationProvider) loadService(lang, DOCUMENTATION_PROVIDER_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of DOCUMENTATION_PROVIDER_SERVICE does not implement IDocumentationProvider",
+ e);
+ return null;
+ }
+ }
+
+ public Set<IModelListener> getEditorServices(Language lang) {
+ Set<IModelListener> result= new HashSet<IModelListener>();
+ for(ILanguageService service: createExtensions(lang, EDITOR_SERVICE)) {
+ result.add((IModelListener) service);
+ }
+ return result;
+ }
+
+ public IElementImageProvider getElementImageProvider(Language lang) {
+ try {
+ return (IElementImageProvider) loadService(lang, IMAGE_DECORATOR_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of IMAGE_DECORATOR_SERVICE does not implement IElementImageProvider",
+ e);
+ return null;
+ }
+ }
+
+ public IEntityImageDecorator getEntityImageDecorator(Language lang) {
+ try {
+ return (IEntityImageDecorator) loadService(lang, ENTITY_IMAGE_DECORATOR_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of ENTITY_IMAGE_DECORATOR_SERVICE does not implement IEntityImageDecorator",
+ e);
+ return null;
+ }
+ }
+
+ public IEntityNameLocator getEntityNameLocator(Language lang) {
+ try {
+ return (IEntityNameLocator) loadService(lang, ENTITY_NAME_LOCATOR_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of ENTITY_NAME_LOCATOR_SERVICE does not implement IEntityNameLocator",
+ e);
+ return null;
+ }
+ }
+
+ public IFoldingUpdater getFoldingUpdater(Language lang) {
+ try {
+ return (IFoldingUpdater) loadService(lang, FOLDING_UPDATER_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of FOLDING_SERVICE does not implement IFoldingUpdater",
+ e);
+ return null;
+ }
+ }
+
+ public IHoverHelper getHoverHelper(Language lang) {
+ try {
+ return (IHoverHelper) loadService(lang, HOVER_HELPER_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of HOVER_HELPER_SERVICE does not implement IHoverHelper",
+ e);
+ return null;
+ }
+ }
+
+ public IndexContributorBase getIndexContributor(Language lang) {
+ try {
+ return (IndexContributorBase) loadService(lang,
+ INDEX_CONTRIBUTOR_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of INDEX_CONTRIBUTOR_SERVICE does not implement IndexContributorBase",
+ e);
+ return null;
+ }
+ }
+
+ public ILabelProvider getLabelProvider(Language lang) {
+ try {
+ return (ILabelProvider) loadService(lang, LABEL_PROVIDER_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of LABEL_PROVIDER_SERVICE does not implement ILabelProvider",
+ e);
+ return null;
+ }
+ }
+
+ public Set<ILanguageActionsContributor> getLanguageActionsContributors(
+ Language lang) {
+ try {
+ Set<ILanguageService> services = loadServices(lang, EDITOR_ACTION_CONTRIBUTIONS_SERVICE);
+
+ Set<ILanguageActionsContributor> actionContributors = new HashSet<ILanguageActionsContributor>();
+
+ for (ILanguageService s : services) {
+ actionContributors.add((ILanguageActionsContributor) s);
+ }
+
+ return actionContributors;
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of EDITOR_ACTION_SERVICE does not implement ILanguageActionConstributor",
+ e);
+ return null;
+ }
+ }
+
+ public IModelListener getModelListener(Language lang) {
+ try {
+ return (IModelListener) loadService(lang, MODEL_LISTENER_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of LISTENER_SERVICE does not implement IModelListener",
+ e);
+ return null;
+ }
+ }
+
+ public IOccurrenceMarker getOccurrenceMarker(Language lang) {
+ try {
+ return (IOccurrenceMarker) loadService(lang, MARK_OCCURRENCES_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of OCCURRENCE_MARKER does not implement IOccurrenceMarker",
+ e);
+ return null;
+ }
+ }
+
+ public OutlineContentProviderBase getOutlineContentProvider(Language lang) {
+ try {
+ return (OutlineContentProviderBase) loadService(lang, OUTLINE_CONTENT_PROVIDER_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of OUTLINE_CONTENT_PROVIDER_SERVICE does not implement OutlineContentProviderBase",
+ e);
+ return null;
+ }
+ }
+
+ public IOutliner getOutliner(Language lang) {
+ try {
+ return (IOutliner) loadService(lang, OUTLINER_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of OLD_OUTLINER_SERVICE does not implement IOutliner",
+ e);
+ return null;
+ }
+ }
+
+ public IParseController getParseController(Language lang) {
+ try {
+ return (IParseController) loadService(lang, PARSER_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of PARSER_SERVICE does not implement IParseController",
+ e);
+ return null;
+ }
+ }
+
+ public Set<IRefactoringContributor> getRefactoringContributors(Language lang) {
+ try {
+ Set<ILanguageService> services = loadServices(lang, REFACTORING_CONTRIBUTIONS_SERVICE);
+ Set<IRefactoringContributor> refactoringContribs = new HashSet<IRefactoringContributor>();
+
+ for (ILanguageService s : services) {
+ refactoringContribs.add((IRefactoringContributor) s);
+ }
+
+ return refactoringContribs;
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of SERVICE does not implement Set<ILanguageSerivice>",
+ e);
+ return null;
+ }
+ }
+
+ public IReferenceResolver getReferenceResolver(Language lang) {
+ try {
+ return (IReferenceResolver) loadService(lang, REFERENCE_RESOLVER_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of REFERENCE_RESOLVER_SERVICE does not implement IReferenceResolver",
+ e);
+ return null;
+ }
+ }
+
+ public ISourceFormatter getSourceFormatter(Language lang) {
+ try {
+ return (ISourceFormatter) loadService(lang, FORMATTER_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of FORMATTER_SERVICE does not implement ISourceFormatter",
+ e);
+ return null;
+ }
+ }
+
+ public ISourceHyperlinkDetector getSourceHyperlinkDetector(Language lang) {
+ try {
+ return (ISourceHyperlinkDetector) loadService(lang, HYPER_LINK_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of HYPERLINK_SERVICE does not implement ISourceHyperlinkDetector",
+ e);
+ return null;
+ }
+ }
+
+ public ILanguageSyntaxProperties getSyntaxProperties(Language lang) {
+ try {
+ return (ILanguageSyntaxProperties) loadService(lang, SYNTAX_PROPS_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of SYNTAX_PROPS does not implement ILanguageSyntaxProperties",
+ e);
+ return null;
+ }
+ }
+
+ public IToggleBreakpointsHandler getToggleBreakpointsHandler(Language lang) {
+ try {
+ return (IToggleBreakpointsHandler) loadService(lang, TOGGLE_BREAKPOINTS_HANDLER_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of TOGGLE_BREAKPOINTS_HANDLER_SERVICE does not implement IToggleBreakpointsHandler",
+ e);
+ return null;
+ }
+ }
+
+ public ITokenColorer getTokenColorer(Language lang) {
+ try {
+ return (ITokenColorer) loadService(lang, TOKEN_COLORER_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of TOKEN_COLORER_SERVICE does not implement ITokenColorer",
+ e);
+ return null;
+ }
+ }
+
+ public TreeModelBuilderBase getTreeModelBuilder(Language lang) {
+ try {
+ return (TreeModelBuilderBase) loadService(lang, MODEL_TREE_BUILDER_SERVICE);
+ } catch (ClassCastException e) {
+ RuntimePlugin.getInstance().logException(
+ "Alleged implementation of MODEL_BUILDER_SERVICE does not implement TreeModelBuilderBase",
+ e);
+ return null;
+ }
+ }
+
+ private ILanguageService createExtension(Language lang, String id) {
+ try {
+ return ExtensionFactory.createServiceExtension(lang, id);
+ } catch (ExtensionException e) {
+ RuntimePlugin.getInstance().logException(
+ "Failed to create extension: " + id, e);
+ return null;
+ }
+ }
+
+ private Set<ILanguageService> createExtensions(Language lang, String id) {
+ try {
+ return ExtensionFactory.createServiceExtensionSet(lang, id);
+ }
+ catch (ExtensionException e) {
+ RuntimePlugin.getInstance().logException(
+ "Failed to create set of extensions for: " + id, e);
+ return new HashSet<ILanguageService>();
+ }
+ }
+
+ private Set<ILanguageService> loadServices(Language lang, String serviceId) {
+ return createExtensions(lang, serviceId);
+ }
+
+ private ILanguageService loadService(Language lang, String name) {
+ if (lang == null) {
+ RuntimePlugin.getInstance().writeErrorMsg("Null language for service = " + name);
+ return null;
+ }
+ if (name == null) {
+ RuntimePlugin.getInstance().writeErrorMsg("Null service for language = " + lang);
+ return null;
+ }
+ return createExtension(lang, name);
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ICompilationUnit.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ICompilationUnit.java
new file mode 100644
index 000000000..c77fe53ab
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ICompilationUnit.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+/*
+ * Created on Mar 13, 2007
+ */
+package org.eclipse.imp.model;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.imp.parser.IMessageHandler;
+
+public interface ICompilationUnit extends ISourceEntity {
+ ISourceProject getProject();
+
+ IPath getPath();
+
+ /**
+ * @return the file corresponding to the receiver, if possible, or null if not.
+ */
+ IFile getFile();
+
+ String getSource();
+
+ Object getAST(IMessageHandler msgHandler, IProgressMonitor monitor);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/IPathEntry.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/IPathEntry.java
new file mode 100644
index 000000000..44f558281
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/IPathEntry.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+/*
+ * Created on Mar 13, 2007
+ */
+package org.eclipse.imp.model;
+
+import org.eclipse.core.runtime.IPath;
+
+public interface IPathEntry {
+ public enum PathEntryType {
+ /**
+ * Path entry corresponding to a source folder in the referencing project. The
+ * associated path must be absolute (not project-relative).
+ **/
+ SOURCE_FOLDER,
+ /**
+ * Path entry corresponding to an archive (jar, zip) somewhere in the workspace.
+ * The associated path must be absolute (not project-relative).
+ **/
+ ARCHIVE,
+ /**
+ * Path entry corresponding to a project dependency. The
+ * associated path must be absolute (not project-relative).
+ **/
+ PROJECT,
+ /**
+ * Path entry corresponding to some form of pseudo-container (not an archive),
+ * e.g. the set of plugin dependencies. Not sure what the path means in this
+ * case.
+ **/
+ CONTAINER
+ }
+
+ /**
+ * @return the type of this path entry
+ */
+ PathEntryType getEntryType();
+
+ /**
+ * @return the path associated with this path entry. Different entry types may have
+ * different interpretations for the associated path. @see PathEntryType
+ */
+ IPath getPath();
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ISourceContainer.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ISourceContainer.java
new file mode 100644
index 000000000..700a23195
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ISourceContainer.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.model;
+
+public interface ISourceContainer extends ISourceEntity {
+ ISourceEntity[] getChildren();
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ISourceEntity.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ISourceEntity.java
new file mode 100644
index 000000000..2beb77d46
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ISourceEntity.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+/*
+ * Created on Mar 30, 2007
+ */
+package org.eclipse.imp.model;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+public interface ISourceEntity {
+ String getName();
+
+ ISourceEntity getParent();
+
+ ISourceEntity getAncestor(Class ofType);
+
+ IResource getResource();
+
+ /**
+ * Commit any pending changes to the given entity to disk.
+ * @param monitor
+ */
+ void commit(IProgressMonitor monitor);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ISourceFolder.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ISourceFolder.java
new file mode 100644
index 000000000..ca9bf8460
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ISourceFolder.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.model;
+
+public interface ISourceFolder extends ISourceContainer {
+ String getName();
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ISourceProject.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ISourceProject.java
new file mode 100644
index 000000000..b96b66e7b
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ISourceProject.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.model;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+
+public interface ISourceProject extends ISourceContainer {
+ /**
+ * @return the build path, a List of IPathEntry's
+ */
+ List<IPathEntry> getBuildPath();
+
+ /**
+ * @param buildPath the new build path for this project; entries are copied into the project's
+ * build path list
+ */
+ void setBuildPath(List<IPathEntry> buildPath);
+
+ /**
+ * @return the underlying IProject
+ */
+ IProject getRawProject();
+
+ /**
+ * @return the resolved and possibly filesystem-absolute path corresponding to the given IPath
+ */
+ IPath resolvePath(IPath path);
+
+ /**
+ * @return an array of <code>ISourceFolder</code> corresponding to the configured source folders
+ * for this project
+ */
+ ISourceFolder[] getSourceRoots();
+
+ /**
+ * @return an array of the direct children of this <code>ISourceEntity</code>; returns an empty
+ * list (not null) if this entity has no children
+ */
+ ISourceEntity[] getChildren();
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/IWorkspaceModel.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/IWorkspaceModel.java
new file mode 100644
index 000000000..e026b0433
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/IWorkspaceModel.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.model;
+
+public interface IWorkspaceModel extends ISourceContainer {
+ ISourceProject[] getProjects();
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ModelFactory.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ModelFactory.java
new file mode 100644
index 000000000..232933c6d
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/ModelFactory.java
@@ -0,0 +1,337 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.model;
+
+import java.util.HashMap;
+import java.util.Map;
+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.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.imp.core.ErrorHandler;
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.language.LanguageRegistry;
+import org.eclipse.imp.model.IPathEntry.PathEntryType;
+import org.eclipse.imp.model.internal.CompilationUnitRef;
+import org.eclipse.imp.model.internal.PathEntry;
+import org.eclipse.imp.model.internal.SourceFolder;
+import org.eclipse.imp.model.internal.SourceProject;
+import org.eclipse.imp.model.internal.WorkspaceModel;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.ui.editors.text.TextFileDocumentProvider;
+
+/**
+ * A factory for implementations of the various common model interfaces, e.g., ISourceProject,
+ * ICompilationUnit, and so on.
+ * @author rfuhrer
+ */
+public class ModelFactory {
+ public class ModelException extends Exception {
+ private static final long serialVersionUID= -1051581958821533299L;
+
+ public ModelException() {
+ super();
+ }
+ public ModelException(String message) {
+ super(message);
+ }
+ public ModelException(String message, Throwable cause) {
+ super(message, cause);
+ }
+ public ModelException(Throwable cause) {
+ super(cause);
+ }
+ }
+
+ public static final String NO_SUCH_ELEMENT= "No such element: ";
+
+ public static final String ELEMENT_ALREADY_EXISTS= "Element already exists: ";
+
+ private static ModelFactory sInstance= new ModelFactory();
+
+ public static ModelFactory getInstance() {
+ return sInstance;
+ }
+
+ /**
+ * Implementations of this interface, once registered, can augment the model entities
+ * created by the factory before they are returned to the client.<br>
+ * This provides a mechanism for language-specific customization of core model entity
+ * properties. E.g, the project's search path can be augmented based on a global
+ * language-specific preference setting.
+ */
+ // TODO Implementations of this interface should probably be provided via an extension point
+ public interface IFactoryExtender {
+ /**
+ * This method gets called for the extender corresponding to each language nature
+ * configured on the given project.
+ */
+ void extend(ISourceProject project);
+
+ /**
+ * This method gets called only for the extender of the "host language" contained
+ * within the given compilation unit (i.e. for the language to which the associated
+ * content type maps).
+ */
+ void extend(ICompilationUnit unit);
+ }
+
+ private ModelFactory() {}
+
+ private IWorkspaceModel fModelRoot= new WorkspaceModel(ResourcesPlugin.getWorkspace().getRoot());
+
+ private Map<IProject, ISourceProject> fProjectMap= new HashMap<IProject, ISourceProject>();
+
+ private Map<Language, IFactoryExtender> fExtenderMap= new HashMap<Language, IFactoryExtender>();
+
+ public void installExtender(IFactoryExtender extender, Language language) {
+ fExtenderMap.put(language, extender);
+ }
+
+ public static IWorkspaceModel getModelRoot() {
+ return getInstance().fModelRoot;
+ }
+
+// public static IWorkspaceModel open(IWorkspaceRoot wsRoot) throws ModelException {
+// return getInstance().doOpen(wsRoot);
+// }
+//
+// private IWorkspaceModel doOpen(IWorkspaceRoot wsRoot) throws ModelException {
+// if (!wsRoot.exists())
+// throw new ModelException(NO_SUCH_ELEMENT);
+//
+// return new WorkspaceModel(wsRoot);
+// }
+
+ public static ISourceProject open(IProject project) throws ModelException {
+ return getInstance().doOpen(project);
+ }
+
+ private ISourceProject doOpen(IProject project) throws ModelException {
+ if (!project.exists())
+ throw new ModelException(NO_SUCH_ELEMENT);
+
+ ISourceProject sp= fProjectMap.get(project);
+
+ if (sp == null) {
+ fProjectMap.put(project, sp= new SourceProject(project));
+
+ // Find each language nature configured on the underlying project, find the
+ // corresponding factory extender, and invoke it before returning the project.
+ try {
+ String[] natures= project.getDescription().getNatureIds();
+
+ for(int i= 0; i < natures.length; i++) {
+ String natureID= natures[i];
+ Language lang= LanguageRegistry.findLanguageByNature(natureID);
+
+ if (lang != null) {
+ IFactoryExtender ext= fExtenderMap.get(lang);
+
+ if (ext != null) {
+ ext.extend(sp);
+ }
+ }
+ }
+ } catch (CoreException e) {
+ ErrorHandler.reportError(e.getMessage());
+ }
+ }
+ return sp;
+ }
+
+ // TODO needs a progress monitor
+ public static ISourceProject create(IProject project) throws ModelException {
+ return getInstance().doCreate(project);
+ }
+
+ // TODO needs a progress monitor
+ private ISourceProject doCreate(IProject project) throws ModelException {
+ throw new ModelException(ELEMENT_ALREADY_EXISTS);
+ }
+
+ public static ISourceEntity open(IContainer container) throws ModelException {
+ return getInstance().doOpen(container);
+ }
+
+ public static ISourceEntity open(IResource resource) throws ModelException {
+ if (resource instanceof IContainer) {
+ return getInstance().doOpen((IContainer) resource);
+ } else if (resource instanceof IFile) {
+ ISourceProject srcProject= getInstance().doOpen(resource.getProject());
+ return getInstance().doOpen((IFile) resource, srcProject);
+ }
+ return null;
+ }
+
+ private ISourceEntity doOpen(IContainer container) throws ModelException {
+ if (container instanceof IProject) {
+ return doOpen((IProject) container);
+ } else if (container instanceof IFolder) {
+ return doOpen((IFolder) container);
+ } else if (container instanceof IWorkspaceRoot) {
+ return fModelRoot; // doOpen((IWorkspaceRoot) container);
+ }
+ throw new ModelException("Inappropriate argument type " + container.getClass() + " to ModelFactory.doOpen(IContainer).");
+ }
+
+ // TODO needs a progress monitor
+ public static ISourceEntity create(IContainer container) throws ModelException {
+ return getInstance().doCreate(container);
+ }
+
+ // TODO needs a progress monitor
+ private ISourceEntity doCreate(IContainer container) throws ModelException {
+ if (container instanceof IProject) {
+ return doCreate((IProject) container);
+ } else if (container instanceof IFolder) {
+ return doOpen((IFolder) container);
+ } else if (container instanceof IWorkspaceRoot) {
+ return fModelRoot; // doOpen((IWorkspaceRoot) container);
+ }
+ throw new ModelException("Inappropriate argument type " + container.getClass() + " to ModelFactory.doOpen(IContainer).");
+ }
+
+ public static ISourceFolder open(IFolder folder) throws ModelException {
+ return getInstance().doOpen(folder);
+ }
+
+ private ISourceFolder doOpen(IFolder folder) throws ModelException {
+ if (!folder.exists()) {
+ throw new ModelException(NO_SUCH_ELEMENT);
+ }
+ ISourceProject sp= doOpen(folder.getProject());
+ SourceFolder sf= new SourceFolder(sp, folder.getProjectRelativePath());
+
+ return sf;
+ }
+
+ /**
+ * Creates a source folder. Must not already exist. Containing project
+ * must already exist.
+ */
+ // TODO needs a progress monitor
+ public static ISourceFolder create(IFolder folder) throws ModelException {
+ return getInstance().doCreate(folder);
+ }
+
+ // TODO needs a progress monitor
+ private ISourceFolder doCreate(IFolder folder) throws ModelException {
+ ISourceProject sp= doOpen(folder.getProject());
+
+ if (!folder.exists()) {
+ try {
+ folder.create(true, false, null);
+ } catch (CoreException e) {
+ throw new ModelException("Unable to create underlying folder for source folder " + folder.getLocation().toPortableString(), e);
+ }
+ }
+
+ SourceFolder sf= new SourceFolder(sp, folder.getProjectRelativePath());
+
+ return sf;
+ }
+
+ public static ICompilationUnit open(IPath path, ISourceProject srcProject) {
+ return getInstance().doOpen(path, srcProject);
+ }
+
+ private ICompilationUnit doOpen(IPath path, ISourceProject srcProject) {
+ ICompilationUnit unit;
+ IPath resolvedPath;
+
+ if (path.isAbsolute())
+ unit= new CompilationUnitRef(resolvedPath= path, null);
+ else {
+ resolvedPath= srcProject.resolvePath(path);
+
+ if (resolvedPath == null)
+ return null;
+ unit= new CompilationUnitRef(resolvedPath, srcProject);
+ }
+
+ // Determine the language of this compilation unit, find the corresponding
+ // factory extender, and invoke it before returning the compilation unit.
+ Language lang= LanguageRegistry.findLanguage(resolvedPath, null);
+ IFactoryExtender ext= fExtenderMap.get(lang);
+
+ if (ext != null)
+ ext.extend(unit);
+
+ return unit;
+ }
+
+ public static ICompilationUnit open(IFile file, ISourceProject srcProject) {
+ return getInstance().doOpen(file, srcProject);
+ }
+
+ private ICompilationUnit doOpen(IFile file, ISourceProject srcProject) {
+ if (!file.exists())
+ return null;
+
+ ICompilationUnit unit= new CompilationUnitRef(file.getFullPath(), srcProject);
+
+ // Determine the language of this compilation unit, find the corresponding
+ // factory extender, and invoke it before returning the compilation unit.
+ TextFileDocumentProvider tfdp= new TextFileDocumentProvider(); // TODO perhaps this should be in a field? or another type of doc provider?
+ IDocument doc= tfdp.getDocument(file);
+ Language lang= LanguageRegistry.findLanguage(file.getLocation(), doc);
+ IFactoryExtender ext= fExtenderMap.get(lang);
+
+ if (ext != null)
+ ext.extend(unit);
+
+ return unit;
+ }
+
+ /**
+ *
+ * @param projRelPath
+ * @param srcProject
+ * @return never returns null
+ */
+ // TODO needs a progress monitor
+ public static ICompilationUnit create(IPath projRelPath, ISourceProject srcProject) throws ModelException {
+ return getInstance().doCreate(projRelPath, srcProject);
+ }
+
+ // TODO needs a progress monitor
+ private ICompilationUnit doCreate(IPath projRelPath, ISourceProject srcProject) throws ModelException {
+ throw new ModelException(ELEMENT_ALREADY_EXISTS);
+ }
+
+ /**
+ * @param file
+ * @param srcProject
+ * @return the new ICompilationUnit corresponding to the given file
+ */
+ // TODO needs a progress monitor
+ public static ICompilationUnit create(IFile file, ISourceProject srcProject) throws ModelException {
+ return getInstance().doCreate(file, srcProject);
+ }
+
+ // TODO needs a progress monitor
+ private ICompilationUnit doCreate(IFile file, ISourceProject srcProject) throws ModelException {
+ return doCreate(file.getProjectRelativePath(), srcProject);
+ }
+
+ // TODO needs a progress monitor
+ public static IPathEntry createPathEntry(PathEntryType type, IPath path) {
+ return new PathEntry(type, path);
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/CompilationUnitRef.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/CompilationUnitRef.java
new file mode 100644
index 000000000..dad51edeb
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/CompilationUnitRef.java
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.imp.model.internal;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.imp.core.ErrorHandler;
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.language.LanguageRegistry;
+import org.eclipse.imp.language.ServiceFactory;
+import org.eclipse.imp.model.ICompilationUnit;
+import org.eclipse.imp.model.ISourceEntity;
+import org.eclipse.imp.model.ISourceFolder;
+import org.eclipse.imp.model.ISourceProject;
+import org.eclipse.imp.model.IWorkspaceModel;
+import org.eclipse.imp.model.ModelFactory;
+import org.eclipse.imp.model.ModelFactory.ModelException;
+import org.eclipse.imp.parser.IMessageHandler;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.ui.editors.text.TextFileDocumentProvider;
+
+public class CompilationUnitRef implements ICompilationUnit {
+ /**
+ * The containing ISourceProject. May be null if the associated path is
+ * workspace-absolute.
+ */
+ final ISourceProject fProject;
+
+ /**
+ * Path may be either workspace-absolute or project-relative. If
+ * workspace-absolute, fProject will be null.
+ */
+ final IPath fPath; // possibly src-folder-relative?
+
+ // TODO This should be created lazily
+ private IParseController fParseCtrlr;
+
+ /**
+ * @param path
+ * may be either workspace-absolute or project-relative
+ * @param proj
+ * may be null if path is workspace-absolute
+ */
+ public CompilationUnitRef(IPath path, ISourceProject proj) {
+ fProject= proj;
+ fPath= path;
+ }
+
+ /**
+ * @return the associated ISourceProject. May be null if the unit's path is
+ * workspace-absolute.
+ */
+ public ISourceProject getProject() {
+ return fProject;
+ }
+
+ /**
+ * @return the associated IPath, which may be either workspace-absolute or
+ * project-relative
+ */
+ public IPath getPath() {
+ return fPath;
+ }
+
+ public String getName() {
+ return fPath.lastSegment();
+ // if (fPath.isAbsolute())
+ // return fPath.toPortableString();
+ // return fProject.getRawProject().getName() + ":" + fPath;
+ }
+
+ public ISourceEntity getParent() {
+ IContainer parent= (IContainer) fProject.getRawProject().findMember(
+ fPath.removeLastSegments(1));
+
+ try {
+ return ModelFactory.open(parent);
+ } catch (ModelException e) {
+ RuntimePlugin.getInstance().logException(
+ "Error obtaining parent of " + getName(), e);
+ return null;
+ }
+ }
+
+ public ISourceEntity getAncestor(Class ofType) {
+ if (ofType == ICompilationUnit.class) {
+ return this;
+ } else if (ofType == ISourceProject.class) {
+ return fProject;
+ } else if (ofType == IWorkspaceModel.class) {
+ return ModelFactory.getModelRoot();
+ } else if (ofType == ISourceFolder.class) {
+ return getParent();
+ }
+ return null;
+ }
+
+ public IResource getResource() {
+ return getFile();
+ }
+
+ public IFile getFile() {
+ if (fPath.getDevice() != null && fPath.getDevice().length() > 0)
+ return null; // This is a filesystem-absolute path; can't build
+ // an IFile for that
+ if (fPath.isAbsolute())
+ return fProject.getRawProject().getWorkspace().getRoot().getFile(
+ fPath);
+ return fProject.getRawProject().getFile(fPath);
+ }
+
+ public Object getAST(IMessageHandler msgHandler, IProgressMonitor monitor) {
+ IFile file= getFile();
+ TextFileDocumentProvider tfdp= new TextFileDocumentProvider();
+ IDocument doc= (file != null) ? tfdp.getDocument(file) : null;
+
+ // if (file == null)
+ // return null;
+
+ if (fParseCtrlr == null) {
+ Language lang= LanguageRegistry.findLanguage(fPath, doc);
+
+ fParseCtrlr= ServiceFactory.getInstance().getParseController(lang);
+ }
+ IPath projRelPath= fPath.isAbsolute() ? fPath.removeFirstSegments(1)
+ : fPath;
+ fParseCtrlr.initialize(projRelPath, fProject, msgHandler);
+ return fParseCtrlr.parse(getSource(), monitor);
+ }
+
+ public String getSource() {
+ String absPath= (fPath.getDevice() != null) ? fPath.toOSString()
+ : (fPath.isAbsolute() ? ResourcesPlugin.getWorkspace()
+ .getRoot().getLocation().append(fPath).toOSString()
+ : fProject.getRawProject().getLocation().append(fPath)
+ .toOSString());
+ File inFile= new File(absPath);
+
+ if (!inFile.exists() || !inFile.canRead()) {
+ throw new IllegalArgumentException(
+ "CompilationUnitRef.getSource(): file does not exist or cannot be read: "
+ + this);
+ }
+
+ // Get a buffered reader for the input file
+ FileReader fileReader= null;
+ long fileLen= inFile.length();
+ try {
+ fileReader= new FileReader(inFile);
+ char[] buffer= new char[(int) fileLen];
+ fileReader.read(buffer);
+ return new String(buffer);
+ } catch (FileNotFoundException e) {
+ ErrorHandler
+ .reportError("CompilationUnitRef.getSource(): file not found: "
+ + this);
+ return null;
+ } catch (IOException e) {
+ ErrorHandler
+ .reportError("CompilationUnitRef.getSource(): cannot read file: "
+ + this);
+ return null;
+ }
+ }
+
+ public void commit(IProgressMonitor mon) {
+ // do nothing
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof CompilationUnitRef))
+ return false;
+ CompilationUnitRef other= (CompilationUnitRef) obj;
+ return fProject.equals(other.fProject) && fPath.equals(other.fPath);
+ }
+
+ @Override
+ public int hashCode() {
+ int result= 4831;
+ result= result * 4933 + (fProject != null ? fProject.hashCode() : 13);
+ result= result * 1627 + fPath.hashCode();
+ return result;
+ }
+
+ public String toString() {
+ return "<compilation unit " + getPath().toPortableString() + ">";
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/PathEntry.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/PathEntry.java
new file mode 100644
index 000000000..89c4cf46c
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/PathEntry.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+/*
+ * Created on Mar 13, 2007
+ */
+package org.eclipse.imp.model.internal;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.imp.model.IPathEntry;
+
+public class PathEntry implements IPathEntry {
+ private final IPath fPath;
+ private final PathEntryType fType;
+
+ public PathEntry(PathEntryType type, IPath path) {
+ fType= type;
+ fPath= path;
+ }
+
+ public PathEntryType getEntryType() {
+ return fType;
+ }
+
+ public IPath getPath() {
+ return fPath;
+ }
+
+ public String toString() {
+ return "<" + fType + ": " + fPath.toPortableString() + ">";
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/ResourceUtility.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/ResourceUtility.java
new file mode 100644
index 000000000..9916594f9
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/ResourceUtility.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.model.internal;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.imp.runtime.RuntimePlugin;
+
+public class ResourceUtility {
+ private ResourceUtility() { } // Not instantiatable
+
+ /*package*/ static Set<IResource> getImmediateChildren(final IResource r) {
+ final Set<IResource> result= new HashSet<IResource>();
+ try {
+ r.accept(new IResourceVisitor() {
+ public boolean visit(IResource resource) throws CoreException {
+ if (resource == r || resource.getFullPath().equals(r.getFullPath()))
+ return true;
+ result.add(resource);
+ return false;
+ }
+ });
+ } catch (CoreException e) {
+ RuntimePlugin.getInstance().logException("Error enumerating resource children", e);
+ }
+ return result;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/SourceFolder.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/SourceFolder.java
new file mode 100644
index 000000000..b5ec6447d
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/SourceFolder.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.model.internal;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.imp.model.ISourceEntity;
+import org.eclipse.imp.model.ISourceFolder;
+import org.eclipse.imp.model.ISourceProject;
+import org.eclipse.imp.model.IWorkspaceModel;
+import org.eclipse.imp.model.ModelFactory;
+import org.eclipse.imp.model.ModelFactory.ModelException;
+import org.eclipse.imp.runtime.RuntimePlugin;
+
+public class SourceFolder implements ISourceFolder {
+ private static final ISourceEntity[] NO_CHILDREN= new ISourceEntity[0];
+
+ private final ISourceProject fSrcProject;
+
+ private final IPath fProjRelPath;
+
+ public SourceFolder(ISourceProject srcProject, IPath projRelPath) {
+ fSrcProject= srcProject;
+ fProjRelPath= projRelPath;
+ }
+
+ public String getName() {
+ return fProjRelPath.lastSegment();
+ }
+
+ public ISourceEntity[] getChildren() {
+ Set<IResource> children= ResourceUtility.getImmediateChildren(fSrcProject.getRawProject().findMember(fProjRelPath));
+ Set<ISourceEntity> result= new HashSet<ISourceEntity>();
+
+ for(IResource child : children) {
+ try {
+ result.add(ModelFactory.open(child));
+ } catch (ModelException e) {
+ RuntimePlugin.getInstance().logException(e.getMessage(), e);
+ }
+ }
+ return result.toArray(new ISourceEntity[children.size()]);
+ }
+
+ public ISourceEntity getParent() {
+ try {
+ if (fProjRelPath.segmentCount() > 1)
+ return ModelFactory.open(fSrcProject.getRawProject().findMember(fProjRelPath.removeLastSegments(1)));
+ else
+ return fSrcProject;
+ } catch (ModelException e) {
+ RuntimePlugin.getInstance().logException("Error retrieving parent of source folder " + this, e);
+ return null;
+ }
+ }
+
+ public ISourceEntity getAncestor(Class ofType) {
+ if (ofType == ISourceProject.class) {
+ return fSrcProject;
+ } else if (ofType == IWorkspaceModel.class) {
+ return ModelFactory.getModelRoot();
+ } else if (ofType == ISourceFolder.class) {
+ return this;
+ }
+ return null;
+ }
+
+ public IPath getPath() {
+ return fProjRelPath;
+ }
+
+ public ISourceProject getSrcProject() {
+ return fSrcProject;
+ }
+
+ public IResource getResource() {
+ return fSrcProject.getRawProject().findMember(fProjRelPath);
+ }
+
+ public void commit(IProgressMonitor monitor) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof SourceFolder))
+ return false;
+ SourceFolder other= (SourceFolder) obj;
+ return fSrcProject.equals(other.fSrcProject) && fProjRelPath.equals(other.fProjRelPath);
+ }
+
+ @Override
+ public int hashCode() {
+ int result= 199;
+ result= result * 5827 + fSrcProject.hashCode();
+ result= result * 4639 + fProjRelPath.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "<source folder @ " + fSrcProject.getRawProject().getName() + " : " + fProjRelPath.toPortableString() + ">";
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/SourceProject.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/SourceProject.java
new file mode 100644
index 000000000..ecb83f819
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/SourceProject.java
@@ -0,0 +1,320 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.model.internal;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+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.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.imp.core.ErrorHandler;
+import org.eclipse.imp.model.IPathEntry;
+import org.eclipse.imp.model.ISourceEntity;
+import org.eclipse.imp.model.ISourceFolder;
+import org.eclipse.imp.model.ISourceProject;
+import org.eclipse.imp.model.IWorkspaceModel;
+import org.eclipse.imp.model.ModelFactory;
+import org.eclipse.imp.model.IPathEntry.PathEntryType;
+import org.eclipse.imp.model.ModelFactory.ModelException;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+public class SourceProject implements ISourceProject {
+ private static final String CONFIG_FILE_NAME= ".projectConfig";
+ private final IProject fProject;
+ private final List<IPathEntry> fBuildPath= new ArrayList<IPathEntry>();
+
+ public SourceProject(IProject project) {
+ fProject= project;
+
+ if (!readMetaData()) {
+// initializeFromJavaProject();
+ }
+ }
+
+ public void setBuildPath(List<IPathEntry> buildPath) {
+ fBuildPath.clear();
+ fBuildPath.addAll(buildPath);
+ }
+
+ public String getName() {
+ return fProject.getName();
+ }
+
+ private void saveMetaData(IProgressMonitor monitor) {
+ IFile file= fProject.getFile(CONFIG_FILE_NAME);
+ String metaData= createProjectMetaData();
+ try {
+ InputStream is= new ByteArrayInputStream(metaData.getBytes(file.getCharset()));
+ file.setContents(is, true, true, monitor);
+ } catch (CoreException e) {
+ ErrorHandler.reportError(e.getMessage(), e);
+ } catch (UnsupportedEncodingException e) {
+ ErrorHandler.reportError(e.getMessage(), e);
+ }
+ }
+
+ private String createProjectMetaData() {
+ StringBuffer buff= new StringBuffer();
+ buff.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ buff.append("<project>\n");
+ buff.append(" <searchPath>\n");
+ for(IPathEntry path: fBuildPath) {
+ buff.append(" <pathEntry type=\"" + path.getEntryType() + "\"\n");
+ buff.append(" loc=\"" + path.getPath().toPortableString() + "\"/>\n");
+ }
+ buff.append(" </searchPath>\n");
+ buff.append("</project>\n");
+ return buff.toString();
+ }
+
+ private boolean readMetaData() {
+ IFile file= fProject.getFile(CONFIG_FILE_NAME);
+ if (file.exists()) {
+ try {
+ InputStream contents= file.getContents();
+ DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder= factory.newDocumentBuilder();
+ Document document= builder.parse(contents);
+ NodeList children= document.getChildNodes();
+ Node project= children.item(0);
+
+// String projLabel= project.getNodeName();
+ NodeList configItems= project.getChildNodes();
+
+ for(int i= 0; i < configItems.getLength(); i++) {
+ Node configItem= configItems.item(i);
+ String itemName= configItem.getNodeName();
+
+ if (itemName.equals("searchPath")) {
+ NodeList pathItems= configItem.getChildNodes();
+
+ for(int p= 0; p < pathItems.getLength(); p++) {
+ Node pathItem= pathItems.item(p);
+ String nodeName= pathItem.getNodeName();
+
+ if (nodeName.equals("#text"))
+ continue;
+ if (!nodeName.equals("pathEntry")) {
+ ErrorHandler.reportError("Unexpected child " + nodeName + " of <searchPath> in " + fProject.getFullPath().toPortableString()
+ + "/" + CONFIG_FILE_NAME);
+ continue;
+ }
+
+ NamedNodeMap attribs= pathItem.getAttributes();
+ Node typeNode= attribs.getNamedItem("type");
+ Node locNode= attribs.getNamedItem("loc");
+
+ if (typeNode == null || locNode == null) {
+ ErrorHandler.reportError("<pathEntry> missing type or location in " + fProject.getFullPath().toPortableString() + "/"
+ + CONFIG_FILE_NAME);
+ continue;
+ }
+ String pathType= typeNode.getNodeValue();
+ String pathLoc= locNode.getNodeValue();
+ IPathEntry entry= new PathEntry(PathEntryType.valueOf(pathType), new Path(pathLoc));
+
+ fBuildPath.add(entry);
+ }
+ } else if (itemName.equals("#text")) {
+ // skip over these; should be empty anyway
+ } else
+ ErrorHandler.reportError("Unrecognized project configuration item: " + itemName);
+ }
+ return true;
+ } catch (CoreException e) {
+ ErrorHandler.reportError(e.getMessage(), e);
+ } catch (ParserConfigurationException e) {
+ ErrorHandler.reportError(e.getMessage(), e);
+ } catch (SAXException e) {
+ ErrorHandler.reportError(e.getMessage(), e);
+ } catch (IOException e) {
+ ErrorHandler.reportError(e.getMessage(), e);
+ }
+ }
+ return false;
+ }
+
+ public IPath resolvePath(IPath path) {
+ List<IPathEntry> buildPath= getBuildPath();
+ IProject rawProject= fProject;
+
+ if (path.isAbsolute()) {
+ return path;
+ }
+ IFile projRelFile= rawProject.getFile(path);
+
+ if (projRelFile.exists())
+ return rawProject.getFullPath().append(path);
+
+ for(IPathEntry pathEntry: buildPath) {
+ IPath entryPath= pathEntry.getPath();
+ IPathEntry.PathEntryType type= pathEntry.getEntryType();
+
+ if (type == IPathEntry.PathEntryType.SOURCE_FOLDER) {
+ if (!entryPath.isAbsolute()) {
+ IPath filePath= entryPath.removeFirstSegments(1).append(path);
+ IFile file= rawProject.getFile(filePath);
+ if (file.exists()) {
+ return filePath;
+ }
+ } else {
+ // This is a pseudo source folder, not really contained within the project.
+ // The path points outside the workspace, and an IFile can't live outside the
+ // workspace. So use an ordinary Java File to determine whether this path is
+ // resolved.
+ IPath filePath= entryPath.append(path);
+ File f= new File(filePath.toOSString());
+ if (f.exists())
+ return filePath;
+ }
+ } else if (type == IPathEntry.PathEntryType.PROJECT) {
+ try {
+ IProject defProject= ResourcesPlugin.getWorkspace().getRoot().getProject(entryPath.toPortableString());
+ ISourceProject defSrcProject= ModelFactory.open(defProject);
+ IPath defPath= scanSourceFoldersFor(defSrcProject, path);
+
+ if (defPath != null)
+ return defPath;
+ } catch (ModelException e) {
+ ErrorHandler.reportError(e.getMessage());
+ }
+ } else if (type == IPathEntry.PathEntryType.ARCHIVE) {
+ // ???
+ }
+ }
+ return null;
+ }
+
+ private IPath scanSourceFoldersFor(ISourceProject srcProject, IPath path) {
+ List<IPathEntry> buildPath= srcProject.getBuildPath();
+ IProject rawProject= srcProject.getRawProject();
+
+ for(IPathEntry pathEntry: buildPath) {
+ IPath entryPath= pathEntry.getPath();
+ IPathEntry.PathEntryType type= pathEntry.getEntryType();
+
+ if (type == IPathEntry.PathEntryType.SOURCE_FOLDER) {
+ entryPath= entryPath.removeFirstSegments(1); // make project-relative
+ IPath filePath= entryPath.append(path);
+ IFile f= rawProject.getFile(filePath);
+
+ if (f.exists()) {
+ return filePath;
+ }
+ }
+ }
+ return null;
+ }
+
+ public List<IPathEntry> getBuildPath() {
+ return fBuildPath;
+ }
+
+ public IProject getRawProject() {
+ return fProject;
+ }
+
+ public IResource getResource() {
+ return fProject;
+ }
+
+ public ISourceFolder[] getSourceRoots() {
+ // TODO Bogus: considers ALL folders as source roots; need to read project config
+ final Set<ISourceFolder> result= new HashSet<ISourceFolder>();
+ Set<IResource> children= ResourceUtility.getImmediateChildren(fProject);
+
+ for(IResource child: children) {
+ if (child instanceof IFolder) {
+ try {
+ result.add(ModelFactory.open((IFolder) child));
+ } catch (ModelException e) {
+ RuntimePlugin.getInstance().logException(e.getMessage(), e);
+ }
+ }
+ }
+ return result.toArray(new ISourceFolder[result.size()]);
+ }
+
+ public ISourceEntity getParent() {
+ return ModelFactory.getModelRoot();
+ }
+
+ public ISourceEntity getAncestor(Class ofType) {
+ if (ofType == ISourceProject.class) {
+ return this;
+ } else if (ofType == IWorkspaceModel.class) {
+ return ModelFactory.getModelRoot();
+ }
+ return null;
+ }
+
+ public ISourceEntity[] getChildren() {
+ final Set<ISourceEntity> result= new HashSet<ISourceEntity>();
+ Set<IResource> children= ResourceUtility.getImmediateChildren(fProject);
+
+ for(IResource child: children) {
+ try {
+ result.add(ModelFactory.open(child));
+ } catch (ModelException e) {
+ RuntimePlugin.getInstance().logException(e.getMessage(), e);
+ }
+ }
+ return result.toArray(new ISourceEntity[result.size()]);
+ }
+
+ // Presumably this will get called by the "New Project" wizard and the Project Properties pages
+ public void commit(IProgressMonitor monitor) {
+ saveMetaData(monitor);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof SourceProject))
+ return false;
+ SourceProject other= (SourceProject) obj;
+ return fProject.equals(other.fProject);
+ }
+
+ @Override
+ public int hashCode() {
+ int result= 6607;
+ result= result * 7451 + fProject.hashCode();
+ return result;
+ }
+
+ public String toString() {
+ return "<project: " + fProject.getName() + ">";
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/WorkspaceModel.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/WorkspaceModel.java
new file mode 100644
index 000000000..5d2d72d37
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/model/internal/WorkspaceModel.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.model.internal;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.imp.model.ISourceEntity;
+import org.eclipse.imp.model.ISourceProject;
+import org.eclipse.imp.model.IWorkspaceModel;
+import org.eclipse.imp.model.ModelFactory;
+import org.eclipse.imp.model.ModelFactory.ModelException;
+import org.eclipse.imp.runtime.RuntimePlugin;
+
+public class WorkspaceModel implements IWorkspaceModel {
+ private final IWorkspaceRoot fWSRoot;
+
+ public WorkspaceModel(IWorkspaceRoot wsRoot) {
+ fWSRoot= wsRoot;
+ }
+
+ public String getName() {
+ return "";
+ }
+
+ public ISourceEntity getParent() {
+ return null;
+ }
+
+ public ISourceEntity getAncestor(Class ofType) {
+ if (ofType == IWorkspaceModel.class) {
+ return this;
+ }
+ return null;
+ }
+
+ public ISourceEntity[] getChildren() {
+ return getProjects();
+ }
+
+ public ISourceProject[] getProjects() {
+ IProject[] projects= fWSRoot.getProjects();
+ ISourceProject[] srcProjects= new ISourceProject[projects.length];
+
+ for(int i= 0; i < projects.length; i++) {
+ IProject project= projects[i];
+
+ try {
+ ISourceProject srcProject= ModelFactory.open(project);
+ srcProjects[i]= srcProject;
+ } catch (ModelException e) {
+ RuntimePlugin.getInstance().logException(e.getMessage(), e);
+ }
+ }
+ return srcProjects;
+ }
+
+ public IResource getResource() {
+ return fWSRoot;
+ }
+
+ public void commit(IProgressMonitor monitor) {
+ // TODO Auto-generated method stub
+ }
+
+ public String toString() {
+ return "<workspace>";
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/ILexer.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/ILexer.java
new file mode 100644
index 000000000..83f69405c
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/ILexer.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.parser;
+
+import lpg.runtime.ILexStream;
+import lpg.runtime.IPrsStream;
+import lpg.runtime.Monitor;
+
+public interface ILexer {
+ public int[] getKeywordKinds();
+
+ public ILexStream getILexStream();
+
+ public void initialize(char[] contents, String filename);
+
+ public void lexer(Monitor monitor, IPrsStream prsStream);
+
+ public void reset(char[] contentsArray, String filePath);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IMessageHandler.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IMessageHandler.java
new file mode 100644
index 000000000..c0fa5808a
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IMessageHandler.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.parser;
+
+/**
+ * This interface describes something that can process messages emitted
+ * by a parser or other language processing front-end.
+ */
+public interface IMessageHandler {
+ /**
+ * Clear all previously-issued messages. Typically called at the
+ * beginning of a parsing "session".
+ */
+ void clearMessages();
+
+ /**
+ * Issue a single message with the given text and source position.
+ * @param msg the message text
+ * @param startOffset 0-based, inclusive
+ * @param endOffset 0-based, inclusive
+ * @param startCol 1-based, inclusive
+ * @param endCol 1-based, inclusive
+ * @param startLine 1-based, inclusive
+ * @param endLine 1-based, inclusive
+ */
+ void handleSimpleMessage(String msg, int startOffset, int endOffset,
+ int startCol, int endCol,
+ int startLine, int endLine);
+
+ /**
+ * Begins a group of related messages (e.g. the first describing an error
+ * relating multiple entities, identifying the position of the first entity,
+ * followed by individual messages, one per additional entity).
+ * @param groupName
+ */
+ void startMessageGroup(String groupName);
+
+ /**
+ * Ends a group of related messages
+ */
+ void endMessageGroup();
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IModelListener.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IModelListener.java
new file mode 100644
index 000000000..f44314f5c
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IModelListener.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.parser;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.imp.language.ILanguageService;
+
+/*
+ * Licensed Materials - Property of IBM,
+ * (c) Copyright IBM Corp. 2005 All Rights Reserved
+ */
+
+/**
+ * A language service that needs to be notified in order to update in response to source
+ * code changes.
+ * @author Claffra
+ * @author rfuhrer@watson.ibm.com
+ */
+public interface IModelListener extends ILanguageService {
+ // BROKEN!!!
+ // The following has no notion of the scope of analysis. E.g., providing a language
+ // service may require analysis within a much wider scope than a compilation unit
+ // (such as whole program analysis). Also, analyses don't really form a linear order.
+ public enum AnalysisRequired {
+ NONE(0),
+ LEXICAL_ANALYSIS(1),
+ SYNTACTIC_ANALYSIS(2),
+ NAME_ANALYSIS(3),
+ TYPE_ANALYSIS(4),
+ CALLGRAPH_ANALYSIS(5),
+ POINTER_ANALYSIS(6);
+
+ private final int fLevel;
+
+ private AnalysisRequired(int i) { fLevel= i; }
+
+ public int level() { return fLevel; }
+ };
+
+ public AnalysisRequired getAnalysisRequired();
+
+ /**
+ * Notify the listener that the document has been updated and a new AST has been computed
+ * @param parseController the parse controller that, among other things, provides the most recent AST
+ * @param monitor the progress monitor; listener should cancel when monitor.isCanceled() is true
+ */
+ public void update(IParseController parseController, IProgressMonitor monitor);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IParseController.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IParseController.java
new file mode 100644
index 000000000..c6114a9d9
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IParseController.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.parser;
+
+import java.util.Iterator;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.model.ISourceProject;
+import org.eclipse.imp.services.IAnnotationTypeInfo;
+import org.eclipse.imp.services.ILanguageSyntaxProperties;
+import org.eclipse.jface.text.IRegion;
+
+public interface IParseController extends ILanguageService {
+ Language getLanguage();
+
+ /**
+ * Initialize the parse controller to parse source text corresponding to
+ * a compilation unit in the given ISourceProject at the given path.
+ * @param filePath either a project-relative path, if project is non-null,
+ * or an absolute path
+ * @param project the source project to which the compilation unit is
+ * considered to belong
+ * @param handler the message handler to which error/warning/info messages
+ * should be directed
+ */
+ void initialize(IPath filePath, ISourceProject project, IMessageHandler handler);
+
+ /**
+ * @return the ISourceProject that contains the source text that this
+ * parse controller will process
+ */
+ ISourceProject getProject();
+
+ /**
+ * @return either a project-relative path, if getProject() is non-null, or an absolute path.
+ */
+ IPath getPath();
+
+ /**
+ * Parse the given source and return the resulting AST. If possible,
+ * and if parsing takes long, should check the {@link IProgressMonitor}
+ * for cancellation requests (e.g., if the user started editing again).
+ * The AST should typically be cached, so that immediately after a
+ * successful parse, getCurrentAst() returns the same AST as this method
+ * produced.
+ * @param input the source text to parse
+ * @param scanOnly deprecated; ignore
+ * @param monitor
+ * @return the AST, if any, resulting from the parse
+ */
+ Object parse(String input, IProgressMonitor monitor);
+
+ /**
+ * @return the AST corresponding to the most recently-parsed source text,
+ * if an AST was successfully produced. In general, there may be an AST
+ * even when parse errors were detected (e.g., if error recovery was
+ * performed).
+ */
+ Object getCurrentAst();
+
+ /**
+ * @return an Iterator that iterates over the tokens contained within
+ * the given region, including any tokens that are only partially
+ * contained
+ */
+ Iterator getTokenIterator(IRegion region);
+
+ /**
+ * @return an ISourcePositionLocator that can be used to correlate
+ * program entities (AST nodes, tokens, etc.) to source positions
+ */
+ ISourcePositionLocator getSourcePositionLocator();
+
+ /**
+ * @return an implementation of {@link ILanguageSyntaxProperties} that
+ * describes certain syntactic features of this language
+ */
+ ILanguageSyntaxProperties getSyntaxProperties();
+
+ /**
+ * @return an implementation of {@link IAnnotationTypeInfo} that
+ * describes the kinds of parser annotations that pertain to this
+ * language
+ */
+ IAnnotationTypeInfo getAnnotationTypeInfo();
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IParser.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IParser.java
new file mode 100644
index 000000000..7fbc5d679
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IParser.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.parser;
+
+import lpg.runtime.ILexStream;
+import lpg.runtime.IPrsStream;
+import lpg.runtime.Monitor;
+
+/*
+ * Licensed Materials - Property of IBM,
+ * (c) Copyright IBM Corp. 1998, 2004 All Rights Reserved
+ */
+
+
+/**
+ * @author rfuhrer, pcharles
+ */
+public interface IParser {
+ /**
+ * Run the parser to create a model.
+ * @param monitor stop scanning/parsing when monitor.isCanceled() is true.
+ * @return
+ */
+ public Object parser(Monitor monitor, int error_repair_count);
+
+ public IPrsStream getIPrsStream();
+
+ /**
+ * @return array of keywords in the order in which they are mapped to integers.
+ */
+ public String[] orderedTerminalSymbols();
+
+ /**
+ * @return array of keywords in the order in which they are mapped to integers.
+ */
+ public int numTokenKinds();
+
+ /**
+ * @return the token kind for the EOF token
+ */
+ public int getEOFTokenKind();
+
+ public void reset(ILexStream lexStream);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IRule.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IRule.java
new file mode 100644
index 000000000..d8c5b0242
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/IRule.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.parser;
+
+/*
+ * Licensed Materials - Property of IBM,
+ * (c) Copyright IBM Corp. 1998, 2004 All Rights Reserved
+ */
+
+/**
+ * @author Claffra
+ *
+ */
+public interface IRule {
+ public abstract String getLeftHandSide();
+
+ public abstract int getSize();
+
+ public abstract int getNumber();
+
+ public abstract String getRightHandSide(int n);
+
+ public abstract boolean isTerminal(int rhsNumber);
+} \ No newline at end of file
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/ISourcePositionLocator.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/ISourcePositionLocator.java
new file mode 100644
index 000000000..15478c403
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/ISourcePositionLocator.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+/**
+ *
+ */
+package org.eclipse.imp.parser;
+
+import org.eclipse.core.runtime.IPath;
+
+public interface ISourcePositionLocator
+{
+ /**
+ * @param ast the root of the AST
+ * @param offset the textual offset, in characters
+ * @return the innermost AST node whose textual extent contains the given text offset
+ */
+ Object findNode(Object astRoot, int offset);
+
+ /**
+ * @param ast the root of the AST
+ * @param startOffset the beginning of the textual extent, in characters
+ * @param endOffset the end of the textual extent, in characters
+ * @return the innermost AST node whose textual extent completely contains the given text extent
+ */
+ Object findNode(Object astRoot, int startOffset, int endOffset);
+
+ /**
+ * @param entity the program entity, e.g. AST node, token, or some
+ * kind of type system object
+ * @return the offset, in characters, of the beginning of the textual extent
+ * spanned by the given entity
+ */
+ int getStartOffset(Object entity);
+
+ /**
+ * @param entity the program entity, e.g. AST node, token, or some
+ * kind of type system object
+ * @return the offset, in characters, of the end of the textual extent spanned by the given entity
+ * It should be the character offset of the last character of the token,
+ * equivalent to <code>getStartOffset() + getLength() - 1</code>
+ *
+ *
+ */
+ int getEndOffset(Object entity);
+
+ /**
+ * @param entity the program entity, e.g. AST node, token, or some
+ * kind of type system object
+ * @return the length, in characters, of the textual extent spanned by the given AST node
+ */
+ int getLength(Object entity);
+
+ /**
+ * @return the workspace-relative or file-system absolute path to the compilation unit
+ * (source or compiled, if no source) that contains the given AST node or ISourceEntity.
+ * The path is in "portable" format, using the Eclipse convention '/' for the path
+ * component separator.
+ * @see org.eclipse.core.runtime.IPath#toPortableString()
+ */
+ IPath getPath(Object node);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/LPGSourcePositionLocator.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/LPGSourcePositionLocator.java
new file mode 100644
index 000000000..81ae3834c
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/LPGSourcePositionLocator.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.imp.parser;
+
+import lpg.runtime.IAst;
+import lpg.runtime.IToken;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.imp.editor.ModelTreeNode;
+import org.eclipse.imp.model.ICompilationUnit;
+
+/**
+ * Locator implementation that works for LPG-generated AST's using the base IAst
+ * interface.
+ *
+ * @author rfuhrer
+ */
+public class LPGSourcePositionLocator implements ISourcePositionLocator {
+ private final IParseController fParseController;
+
+ public LPGSourcePositionLocator(IParseController parseController) {
+ fParseController= parseController;
+ }
+
+ public Object findNode(Object root, int offset) {
+ return findNode(root, offset, offset);
+ }
+
+ public Object findNode(Object root, int startOffset, int endOffset) {
+ if (!(root instanceof IAst))
+ return root;
+
+ IAst astNode= (IAst) root;
+
+ if (astNode.getAllChildren() != null) {
+ for(int i= 0; i < astNode.getAllChildren().size(); i++) {
+ IAst maybe= (IAst) findNode(astNode.getAllChildren().get(i), startOffset, endOffset);
+ if (maybe != null)
+ return maybe;
+ }
+ }
+ if (startOffset >= astNode.getLeftIToken().getStartOffset()
+ && endOffset <= astNode.getRightIToken().getEndOffset())
+ return astNode;
+
+ return null;
+ }
+
+ public int getStartOffset(Object entity) {
+ if (entity instanceof IAst) {
+ IAst n= (IAst) entity;
+ return n.getLeftIToken().getStartOffset();
+ } else if (entity instanceof IToken) {
+ IToken tok= (IToken) entity;
+ return tok.getStartOffset();
+ } else if (entity instanceof ModelTreeNode) {
+ ModelTreeNode treeNode= (ModelTreeNode) entity;
+ return ((IAst) treeNode.getASTNode()).getLeftIToken().getStartOffset();
+ }
+ return 0;
+ }
+
+ public int getEndOffset(Object entity) {
+ if (entity instanceof IAst) {
+ IAst n= (IAst) entity;
+ return n.getRightIToken().getEndOffset();
+ } else if (entity instanceof IToken) {
+ IToken tok= (IToken) entity;
+ return tok.getEndOffset();
+ } else if (entity instanceof ModelTreeNode) {
+ ModelTreeNode treeNode= (ModelTreeNode) entity;
+ return ((IAst) treeNode.getASTNode()).getRightIToken().getEndOffset();
+ }
+ return 0;
+ }
+
+ public int getLength(Object node) {
+ return getEndOffset(node) - getStartOffset(node);
+ }
+
+ public IPath getPath(Object entity) {
+ if (entity instanceof IAst) {
+ IAst node= (IAst) entity;
+ return fParseController.getProject().getRawProject().getFile(node.getLeftIToken().getILexStream().getFileName()).getFullPath();
+ }
+ if (entity instanceof ICompilationUnit) {
+ ICompilationUnit cu= (ICompilationUnit) entity;
+ return cu.getPath();
+ }
+ return new Path("");
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/MessageHandlerAdapter.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/MessageHandlerAdapter.java
new file mode 100644
index 000000000..399df0e13
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/MessageHandlerAdapter.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.parser;
+
+import lpg.runtime.ParseErrorCodes;
+
+public class MessageHandlerAdapter implements lpg.runtime.IMessageHandler {
+ private final IMessageHandler fIMPHandler;
+
+ public MessageHandlerAdapter(IMessageHandler impHandler) {
+ fIMPHandler= impHandler;
+ }
+
+ public void handleMessage(int errorCode, int[] msgLocation, int[] errorLocation, String filename, String[] errorInfo) {
+ int startOffset= msgLocation[lpg.runtime.IMessageHandler.OFFSET_INDEX];
+ int length= msgLocation[lpg.runtime.IMessageHandler.LENGTH_INDEX];
+ int startLine= msgLocation[lpg.runtime.IMessageHandler.START_LINE_INDEX];
+ int endLine= msgLocation[lpg.runtime.IMessageHandler.END_LINE_INDEX];
+ int startCol= msgLocation[lpg.runtime.IMessageHandler.START_COLUMN_INDEX];
+ int endCol= msgLocation[lpg.runtime.IMessageHandler.END_COLUMN_INDEX];
+// String message = MessageFormat.format(ParseErrorCodes.errorMsgText[errorCode], (Object[]) errorInfo);
+ String message = ParseErrorCodes.errorMsgText[errorCode] + ":";
+
+ for (int i = 0; i < errorInfo.length; i++)
+ message += " " + errorInfo[i];
+
+ fIMPHandler.handleSimpleMessage(message, startOffset, startOffset + length - 1,
+ startCol, endCol, startLine, endLine);
+ }
+} \ No newline at end of file
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/ParseControllerBase.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/ParseControllerBase.java
new file mode 100644
index 000000000..63fb01185
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/ParseControllerBase.java
@@ -0,0 +1,73 @@
+package org.eclipse.imp.parser;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.language.LanguageRegistry;
+import org.eclipse.imp.model.ISourceProject;
+
+/**
+ * Base class for implementations of IParseController that takes care of maintaining the
+ * language, project, path, message handler, and the current AST. This implementation is
+ * entirely language- and parser-agnostic (i.e. it can be used with any type of parser).
+ * @author rfuhrer@watson.ibm.com
+ */
+public abstract class ParseControllerBase implements IParseController {
+ /**
+ * The language of the source being parsed by this IParseController.
+ */
+ protected Language fLanguage;
+
+ /**
+ * The project containing the source being parsed by this IParseController. May be null
+ * if the source isn't actually part of an Eclipse project (e.g., a random bit of source
+ * text living outside the workspace).
+ */
+ protected ISourceProject fProject;
+
+ /**
+ * The path to the file containing the source being parsed by this {@link IParseController}.
+ */
+ protected IPath fFilePath;
+
+ /**
+ * The {@link IMessageHandler} to which parser/compiler messages are directed.
+ */
+ protected IMessageHandler handler;
+
+ /**
+ * The current AST (if any) produced by the most recent successful parse.<br>
+ * N.B.: "Successful" may mean that there were syntax errors, but the parser managed
+ * to perform error recovery and still produce an AST.
+ */
+ protected Object fCurrentAst;
+
+ public ParseControllerBase(String languageID) {
+ fLanguage= LanguageRegistry.findLanguage(languageID);
+ }
+
+ public void initialize(IPath filePath, ISourceProject project, IMessageHandler handler) {
+ this.fProject= project;
+ this.fFilePath= filePath;
+ this.handler= handler;
+ }
+
+ public Language getLanguage() {
+ return fLanguage;
+ }
+
+ public ISourceProject getProject() {
+ return fProject;
+ }
+
+ public IPath getPath() {
+ return fFilePath;
+ }
+
+ public IMessageHandler getHandler() {
+ return handler;
+ }
+
+ public Object getCurrentAst() {
+ return fCurrentAst;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/SimpleAnnotationTypeInfo.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/SimpleAnnotationTypeInfo.java
new file mode 100644
index 000000000..b28d69e84
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/SimpleAnnotationTypeInfo.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.imp.services.IAnnotationTypeInfo;
+
+public class SimpleAnnotationTypeInfo implements IAnnotationTypeInfo {
+
+ /*
+ * For the management of associated problem-marker types
+ */
+
+ private static List<String> problemMarkerTypes= new ArrayList<String>();
+
+ public List<String> getProblemMarkerTypes() {
+ return problemMarkerTypes;
+ }
+
+ public void addProblemMarkerType(String problemMarkerType) {
+ problemMarkerTypes.add(problemMarkerType);
+ }
+
+ public void removeProblemMarkerType(String problemMarkerType) {
+ problemMarkerTypes.remove(problemMarkerType);
+ }
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/SimpleLPGParseController.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/SimpleLPGParseController.java
new file mode 100644
index 000000000..f72bc3680
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/SimpleLPGParseController.java
@@ -0,0 +1,285 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+ * Stan Sutton (suttons@us.ibm.com) - maintenance of iterator
+ *******************************************************************************/
+
+package org.eclipse.imp.parser;
+
+import java.util.Iterator;
+
+import lpg.runtime.IPrsStream;
+import lpg.runtime.IToken;
+import lpg.runtime.Monitor;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.imp.core.ErrorHandler;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.imp.services.IAnnotationTypeInfo;
+import org.eclipse.jface.text.IRegion;
+
+/**
+ * Base class for an IParseController implementation that encapsulates a simple
+ * LPG-based scanner and parser.
+ *
+ * @author rfuhrer@watson.ibm.com
+ * @author Stan Sutton (suttons@us.ibm.com): rewrote token iterator
+ */
+public abstract class SimpleLPGParseController extends ParseControllerBase {
+ private char fKeywords[][];
+
+ private boolean fIsKeyword[];
+
+ protected IParser fParser;
+
+ protected ILexer fLexer;
+
+ private ISourcePositionLocator fSourcePositionLocator;
+
+ private final SimpleAnnotationTypeInfo fSimpleAnnotationTypeInfo= new SimpleAnnotationTypeInfo();
+
+ /**
+ * An adapter from an Eclipse IProgressMonitor to an LPG Monitor
+ */
+ protected class PMMonitor implements Monitor {
+ private IProgressMonitor monitor;
+
+ private boolean wasCancelled= false;
+
+ public PMMonitor(IProgressMonitor monitor) {
+ this.monitor= monitor;
+ }
+
+ public boolean isCancelled() {
+ if (!wasCancelled)
+ wasCancelled= monitor.isCanceled();
+ return wasCancelled;
+ }
+
+ public void setMonitor(IProgressMonitor monitor) {
+ this.monitor= monitor;
+ }
+ }
+
+ public SimpleLPGParseController(String languageID) {
+ super(languageID);
+ }
+
+ public IParser getParser() {
+ return fParser;
+ }
+
+ public ILexer getLexer() {
+ return fLexer;
+ }
+
+ public ISourcePositionLocator getSourcePositionLocator() {
+ if (fSourcePositionLocator == null) {
+ fSourcePositionLocator= new LPGSourcePositionLocator(this);
+ }
+ return fSourcePositionLocator;
+ }
+
+ public Iterator<IToken> getTokenIterator(final IRegion region) {
+ final int regionOffset= region.getOffset();
+ final int regionLength= region.getLength();
+ final int regionEnd= regionOffset + regionLength - 1;
+
+ return new Iterator<IToken>() {
+ final IPrsStream stream= SimpleLPGParseController.this.getParser().getIPrsStream();
+ final int firstTokIdx= getTokenIndexAtCharacter(regionOffset);
+ final int lastTokIdx;
+ {
+ int endIdx= getTokenIndexAtCharacter(regionEnd);
+ char[] streamChars= stream.getInputChars();
+ int streamLen= streamChars.length;
+ try {
+ if (regionEnd >= 1 && regionEnd < streamLen
+ && streamChars[regionEnd] == IToken.EOF) {
+ // skip EOF token (assume LPG puts one at end of input
+ // character stream, since it does)
+ endIdx--;
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ ErrorHandler.logError("SimpleLPGParseController.getTokenIterator(IRegion): error initializing lastTokIdx",
+ e);
+ // System.err.println("getTokenIterator: new Iterator(..)<init>: ArrayIndexOutOfBoundsException");
+ // System.err.println(" regionEnd = " + regionEnd + ", endIdx = " + endIdx + ", streamLen = " + streamLen + ",
+ // inputChars.length = " + streamChars.length);
+ }
+ lastTokIdx= endIdx;
+ }
+ int curTokIdx= Math.max(1, firstTokIdx); // skip bogus initial token
+
+ private int getTokenIndexAtCharacter(int offset) {
+ int result= stream.getTokenIndexAtCharacter(offset);
+ // getTokenIndexAtCharacter() answers the negative of the index of the
+ // preceding token if the given offset is not actually within a token.
+ if (result < 0) {
+ result= -result + 1;
+ }
+
+ // The above may leave result set to a value that is one more than the
+ // last token index, so return the last token index if that's the case
+ // (This can happen if the end of the file contains some text that
+ // does not correspond to a token--e.g., if the text represents an adjunct
+ // or something unrecognized)
+ if (result >= stream.getTokens().size())
+ result= stream.getTokens().size() - 1;
+
+ return result;
+ }
+
+ // The following declarations cover the whole input stream, which
+ // may be a proper superset of the range of the given region.
+ // For now, that's a simple way to collect the information, and
+ // most often the given region corresponds to the whole input anyway.
+ // In any case, iteration is based on the range of the given region.
+
+ // The preceding adjuncts for each token
+ IToken[][] precedingAdjuncts= new IToken[lastTokIdx + 1][];
+ {
+ stream.setStreamLength();
+ for(int i= 0; i < precedingAdjuncts.length; i++) {
+ precedingAdjuncts[i]= stream.getPrecedingAdjuncts(i);
+ }
+ }
+
+ // The current indices for each array of preceding adjuncts
+ int[] nextPrecedingAdjunct= new int[lastTokIdx + 1];
+ {
+ for(int i= 0; i < nextPrecedingAdjunct.length; i++) {
+ if (precedingAdjuncts[i].length == 0)
+ nextPrecedingAdjunct[i]= -1;
+ else
+ nextPrecedingAdjunct[i]= 0;
+ }
+ }
+
+ // The following adjuncts (for the last token only)
+ IToken[] followingAdjuncts;
+ {
+ if (lastTokIdx <= 0)
+ followingAdjuncts= new IToken[0];
+ else
+ followingAdjuncts= stream.getFollowingAdjuncts(lastTokIdx);
+ }
+
+ // The current index for the array of following adjuncts
+ int nextFollowingAdjunct;
+ {
+ if (followingAdjuncts.length == 0)
+ nextFollowingAdjunct= -1;
+ else
+ nextFollowingAdjunct= 0;
+ }
+
+ // To support hasNext(); initial values may be reset if appropriate
+ private boolean finalTokenReturned= regionEnd < 1 || lastTokIdx <= 0;
+ private boolean finalAdjunctsReturned= !(followingAdjuncts.length > 0);
+
+ /**
+ * Tests whether the iterator has any unreturned tokens. These may
+ * include "regular" tokens and "adjunct" tokens (e.g., representing
+ * comments).
+ *
+ * @return True if there is another token available, false otherwise
+ */
+ public boolean hasNext() {
+ return !(finalTokenReturned && finalAdjunctsReturned);
+ }
+
+ /**
+ * Returns the next available token in the iterator (or null if
+ * there is none)
+ *
+ * Will return a valid token under conditions that would cause
+ * hasNext() to to return true; conversely, will return null under
+ * conditions that would cause hasNext() to return false.
+ *
+ * As a side effect, updates the flags that are used to compute the
+ * value returned by hasNext().
+ *
+ * The returned token may be a "regular" token (which will have a
+ * corresponding AST node) or an "adjunct" token (which will
+ * represent a comment). The tokens are returned in the order in
+ * which they occur in the text, regardless of their kind.
+ *
+ */
+ public IToken next() {
+ int next= -1; // for convenience
+
+ // If we're not all the way through the tokens
+ if (curTokIdx <= lastTokIdx) {
+
+ // First check for any remaining preceding adjuncts
+ // of the current token
+ next= nextPrecedingAdjunct[curTokIdx];
+ // If the current token has any unreturned preceding
+ // adjuncts
+ if (next >= 0 && next < precedingAdjuncts[curTokIdx].length) {
+ // Return the next preceding adjunct, incrementing the
+ // adjunct index afterwards
+ return precedingAdjuncts[curTokIdx][nextPrecedingAdjunct[curTokIdx]++];
+ }
+
+ // Flag whether the current token is the last one
+ finalTokenReturned= curTokIdx >= lastTokIdx;
+
+ // Return the current token, incrementing the token index
+ // afterwards
+ return stream.getIToken(curTokIdx++);
+ }
+
+ // If there are any adjuncts following the last token
+ if (nextFollowingAdjunct >= 0 && nextFollowingAdjunct < followingAdjuncts.length) {
+ // Flag whether the current adjunct is the last one
+ finalAdjunctsReturned= (nextFollowingAdjunct + 1) >= followingAdjuncts.length;
+
+ // Return the current adjunct, incrementing the adjunct
+ // index afterwards
+ return followingAdjuncts[nextFollowingAdjunct++];
+ }
+
+ return null;
+ }
+
+ public void remove() {
+ throw new IllegalArgumentException("Unimplemented");
+ }
+ };
+ }
+
+ public IAnnotationTypeInfo getAnnotationTypeInfo() {
+ return fSimpleAnnotationTypeInfo;
+ }
+
+ public boolean isKeyword(int kind) {
+ return kind < getParser().numTokenKinds() && fIsKeyword[kind];
+ }
+
+ protected void cacheKeywordsOnce() {
+ if (fKeywords == null) {
+ try {
+ IParser parser= getParser();
+ String tokenKindNames[]= parser.orderedTerminalSymbols();
+ this.fIsKeyword= new boolean[tokenKindNames.length];
+ this.fKeywords= new char[tokenKindNames.length][];
+ int[] keywordKinds= getLexer().getKeywordKinds();
+ for(int i= 1; i < keywordKinds.length; i++) {
+ int index= parser.getIPrsStream().mapKind(keywordKinds[i]);
+ fIsKeyword[index]= true;
+ fKeywords[index]= parser.orderedTerminalSymbols()[index].toCharArray();
+ }
+ } catch (NullPointerException e) {
+ RuntimePlugin.getInstance().writeErrorMsg("SimpleLPGParseController.cacheKeywordsOnce(): NullPointerException; trapped and discarded");
+ }
+ }
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/SymbolTable.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/SymbolTable.java
new file mode 100644
index 000000000..207c45c29
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/parser/SymbolTable.java
@@ -0,0 +1,57 @@
+package org.eclipse.imp.parser;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Trivial symbol table class mapping Strings to declarations (whatever kind
+ * the parser/resolver produces). Parent/child relationship is intended to
+ * represent lexical nesting of scopes.
+ */
+public class SymbolTable<T> extends HashMap<String,T> {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5447807516246616283L;
+ private final SymbolTable<T> parent;
+
+ public SymbolTable() { this(null); }
+ public SymbolTable(SymbolTable<T> parent) { this.parent = parent; }
+
+ public SymbolTable<T> getParent() { return parent; }
+
+ public T findDeclaration(String name) {
+ T decl = (T) get(name);
+ return decl != null ? decl : (parent != null ? parent.findDeclaration(name) : null);
+ }
+
+ public <T1> List<String> allSymbolsOfType(Class<T1> type) {
+ List<String> result= new ArrayList<String>();
+
+ for(String sym: keySet()) {
+ T def= get(sym);
+
+ if (type.isInstance(def))
+ result.add(sym);
+ }
+ return result;
+ }
+
+ public <T1> List<T1> allDefsOfType(Class<T1> type) {
+ List<T1> result = new ArrayList<T1>();
+
+ for(String sym: keySet()) {
+ T def= get(sym);
+
+ if (type.isInstance(def))
+ result.add((T1) def);
+ }
+ return result;
+ }
+
+ public Set<String> allSymbols() {
+ return keySet();
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/AlternativePreferencesPage.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/AlternativePreferencesPage.java
new file mode 100644
index 000000000..b27329d74
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/AlternativePreferencesPage.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences;
+
+
+import org.eclipse.jface.dialogs.Dialog;
+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.Label;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+
+/**
+ * A multi-tab preferences page for Imp-supported languages.
+ * The various tabs nominally represent the same sets of preferences
+ * as set on different levels (default, workspace configuration,
+ * workspace instance, and project).
+ *
+ * @author suttons@us.ibm.com
+ */
+public abstract class AlternativePreferencesPage extends PreferencePage implements IWorkbenchPreferencePage {
+
+ public AlternativePreferencesPage() {
+ this.noDefaultAndApplyButton();
+ }
+
+ protected Control createContents(Composite parent)
+ {
+ String message = getAlternativeMessage();
+ Label label = new Label(parent, SWT.WRAP);
+ label.setText(message);
+
+ // Set the font on the page
+ Dialog.applyDialogFont(parent);
+
+ return label;
+ }
+
+
+ protected abstract String getAlternativeMessage();
+
+
+ /*
+ * The following operations provide a page-level response to the pressing of
+ * buttons on the page. Note, though, that a preference page may not have all of
+ * these buttons--buttons not present on the page may instead be present on individual
+ * tabs on the page.
+ */
+
+
+
+ /**
+ * Respond to pressing of Cancel button by cancelling in-progress
+ * preference updates on each level.
+ *
+ * @see org.eclipse.jface.preference.IPreferencePage#performCancel()
+ */
+ public boolean performCancel()
+ {
+ return true;
+ }
+
+
+ /**
+ * Respond to pressing of the Save button by saving the prevailing preferences.
+ *
+ * Note: In a system of multiple preference levels with preference-value
+ * inheritance, this may only save values on the levels on which they
+ * are stored, i.e., not on levels where they apply through inheritance only.
+ *
+ * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
+ */
+ public boolean performOk()
+ {
+ return true;
+ }
+
+
+
+ /**
+ * For IWorkbenchPreferencePage
+ *
+ * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+ */
+ public void init(IWorkbench workbench) {
+ }
+
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/ConfigurationPreferencesTab.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/ConfigurationPreferencesTab.java
new file mode 100644
index 000000000..5b70f901f
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/ConfigurationPreferencesTab.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences;
+
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+
+
+public abstract class ConfigurationPreferencesTab extends PreferencesTab
+{
+
+ public ConfigurationPreferencesTab(IPreferencesService prefService, boolean noDetails) {
+ super(IPreferencesService.CONFIGURATION_LEVEL, noDetails);
+ this.fPrefService = prefService;
+ fPrefUtils = new PreferencesUtilities(prefService);
+ }
+
+ @Override
+ public Composite createTabContents(TabbedPreferencesPage page, final TabFolder tabFolder) {
+ fPrefPage = page;
+
+ int numColumns= getNoDetails() ? 1 : 2;
+
+ final Composite composite= new Composite(tabFolder, SWT.NONE);
+ composite.setFont(tabFolder.getFont());
+ final GridData gd= new GridData(SWT.FILL, SWT.CENTER, true, false);
+ gd.widthHint= 0;
+ gd.heightHint= SWT.DEFAULT;
+ gd.horizontalSpan= 1;
+ composite.setLayoutData(gd);
+
+ GridLayout gl = new GridLayout();
+ gl.numColumns = numColumns;
+ composite.setLayout(gl);
+
+ fTabItem = new TabItem(tabFolder, SWT.NONE);
+ fTabItem.setText("Configuration");
+ fTabItem.setControl(composite);
+ PreferencesTab.TabSelectionListener listener =
+ new PreferencesTab.TabSelectionListener(fPrefPage, fTabItem);
+ tabFolder.addSelectionListener(listener);
+
+
+ /*
+ * Add the elements relating to preferences fields and their associated "details" links.
+ */
+ //fields = createFields(composite);
+ fFields = createFields(page, composite);
+
+ PreferencesUtilities.fillGridPlace(composite, numColumns);
+
+ // Don't want newly created fields to be flagged as modified
+ clearModifiedMarksOnLabels();
+
+
+ // Put notes on bottom
+
+ final Composite bottom = new Composite(composite, SWT.BOTTOM | SWT.WRAP);
+ GridLayout layout = new GridLayout();
+ bottom.setLayout(layout);
+ bottom.setLayoutData(new GridData(SWT.BOTTOM));
+
+ Label bar = new Label(bottom, SWT.WRAP);
+ GridData data = new GridData();
+ data.verticalAlignment = SWT.WRAP;
+ bar.setLayoutData(data);
+ bar.setText("Preferences shown with a white (or neutral) background are set on this level.\n\n" +
+ "Preferences shown with a colored background are inherited from a\nhigher level.\n\n" +
+ Markings.MODIFIED_NOTE + "\n\n" +
+ Markings.TAB_ERROR_NOTE);
+
+ PreferencesUtilities.fillGridPlace(bottom, 1);
+
+
+ // Put buttons on bottom
+ fButtons = fPrefUtils.createDefaultAndApplyButtons(composite, this);
+
+ return composite;
+ }
+
+
+
+// public void performApply()
+// {
+// for (int i = 0; i < fields.length; i++) {
+// fields[i].store();
+// fields[i].clearModifyMarkOnLabel();
+// }
+// }
+
+
+
+ public void performDefaults() {
+ // Clear all preferences for this page at this level;
+ // "default" values will be set by inheritance from a higher level
+ //fPrefService.clearPreferencesAtLevel(IPreferencesService.DEFAULT_LEVEL);
+ PreferencesInitializer initializer = fPrefPage.getPreferenceInitializer();
+ initializer.clearPreferencesOnLevel(IPreferencesService.CONFIGURATION_LEVEL);
+
+ for (int i = 0; i < fFields.length; i++) {
+ fFields[i].loadWithInheritance();
+ }
+ }
+
+
+// public boolean performOk() {
+// // Example: Store each field
+// for (int i = 0; i < fields.length; i++) {
+// fields[i].store();
+// }
+// return true;
+// }
+
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/DefaultPreferencesTab.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/DefaultPreferencesTab.java
new file mode 100644
index 000000000..d7031199e
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/DefaultPreferencesTab.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+
+public abstract class DefaultPreferencesTab extends PreferencesTab
+{
+
+ public DefaultPreferencesTab(IPreferencesService prefService, boolean noDetails) {
+ super(IPreferencesService.DEFAULT_LEVEL, noDetails);
+ this.fPrefService = prefService;
+ fPrefUtils = new PreferencesUtilities(prefService);
+ }
+
+ @Override
+ public Composite createTabContents(TabbedPreferencesPage page, final TabFolder tabFolder) {
+
+ fPrefPage = page;
+
+ int numColumns= getNoDetails() ? 1 : 2;
+
+ final Composite composite = new Composite(tabFolder, SWT.NONE);
+ composite.setFont(tabFolder.getFont());
+ final GridData gd= new GridData(SWT.FILL, SWT.CENTER, true, false);
+ gd.widthHint= 0;
+ gd.heightHint= SWT.DEFAULT;
+ gd.horizontalSpan= 1;
+ composite.setLayoutData(gd);
+
+ GridLayout gl = new GridLayout();
+ gl.numColumns = numColumns;
+ composite.setLayout(gl);
+
+ fTabItem = new TabItem(tabFolder, SWT.NONE);
+ fTabItem.setText("Default");
+ fTabItem.setControl(composite);
+ PreferencesTab.TabSelectionListener listener =
+ new PreferencesTab.TabSelectionListener(fPrefPage, fTabItem);
+ tabFolder.addSelectionListener(listener);
+
+
+ // Don't want newly created fields to be flagged as modified
+ // page, this, prefService, "default",
+ fFields = createFields(page, composite);
+
+
+ // Being newly loaded, the fields may be displayed with some
+ // indication that they have been modified. This should reset
+ // that marking.
+ clearModifiedMarksOnLabels();
+
+ PreferencesUtilities.fillGridPlace(composite, numColumns);
+
+ // Put notes on bottom
+
+ final Composite bottom = new Composite(composite, SWT.BOTTOM | SWT.WRAP);
+ GridLayout layout = new GridLayout();
+ bottom.setLayout(layout);
+ bottom.setLayoutData(new GridData(SWT.BOTTOM));
+
+ Label bar = new Label(bottom, SWT.WRAP);
+ GridData data = new GridData();
+ data.verticalAlignment = SWT.WRAP;
+ bar.setLayoutData(data);
+ bar.setText("These preferences are set programmatically and are not stored\n" +
+ "persistently. Changes made here apply only to the current execution.\n\n" +
+ "Preferences on the default level cannot be removed.\n\n" +
+ Markings.MODIFIED_NOTE + "\n\n" +
+ Markings.TAB_ERROR_NOTE);
+
+ PreferencesUtilities.fillGridPlace(bottom, 1);
+
+ // Put buttons on the bottom
+ fButtons = fPrefUtils.createDefaultAndApplyButtons(composite, this);
+
+ return composite;
+ }
+
+
+
+ /**
+ * Should be overridden in language-specific default preferences tab
+ * to make use of language-specific preference initializer.
+ *
+ * @return The preference initializer to be used to initialize
+ * preferences in this tab
+ */
+// public AbstractPreferenceInitializer getPreferenceInitializer() {
+// // TODO: Override in subclass where the language-specific
+// // initializer should be known
+// System.out.println("DefaultPreferencesTab.getPreferenceInitializar(): unimplemented; should be overridden with language-specific implementation");
+// return null;
+// }
+
+
+
+// public void performApply()
+// {
+// for (int i = 0; i < fields.length; i++) {
+// fields[i].store();
+// fields[i].clearModifyMarkOnLabel();
+// }
+// }
+
+
+ public void performDefaults() {
+ // Clear all preferences for this page at this level and reload
+ // them into the preferences store
+ //fPrefService.clearPreferencesAtLevel(IPreferencesService.DEFAULT_LEVEL);
+ PreferencesInitializer initializer = fPrefPage.getPreferenceInitializer();
+ if (initializer != null) {
+ initializer.clearPreferencesOnLevel(IPreferencesService.DEFAULT_LEVEL);
+ initializer.initializeDefaultPreferences();
+ }
+ // Example: reload each preferences field
+ for (int i = 0; i < fFields.length; i++) {
+ fFields[i].load();
+ }
+ }
+
+// public boolean performOk() {
+// // Example: Store each field
+// for (int i = 0; i < fields.length; i++) {
+// fields[i].store();
+// }
+// return true;
+// }
+
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/IPreferencesService.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/IPreferencesService.java
new file mode 100644
index 000000000..4b8cc6b4c
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/IPreferencesService.java
@@ -0,0 +1,510 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
+import org.osgi.service.prefs.Preferences;
+
+
+/**
+ *
+ * Miscellaneous notes:
+ * - Assumes that there is a "current language" that is an implicit
+ * qualifier for all preferences
+ * - Assumes that there is a "current project" with respect to which
+ * project-level preferences are evaluated
+ * - Does not include various features of the Eclipse PreferencesService:
+ * - Call site default values
+ * - Call site specifications of priority contexts
+ * - Missing "untyped" get/set operations (which work on strings)
+ * If any of these come to seem useful they can be added
+ * - Implementations may restrict the levels at which some operations
+ * are effective
+ *
+ * @author sutton
+ *
+ */
+
+public interface IPreferencesService {
+
+ /*
+ * Levels at which preferences are supported
+ */
+ public final String PROJECT_LEVEL = "project";
+ public final String INSTANCE_LEVEL = "instance";
+ public final String CONFIGURATION_LEVEL = "configuration";
+ public final String DEFAULT_LEVEL = "default";
+
+ public final int PROJECT_INDEX = 0;
+ public final int INSTANCE_INDEX = 1;
+ public final int CONFIGURATION_INDEX = 2;
+ public final int DEFAULT_INDEX = 3;
+
+ public final static String[] levels = { PROJECT_LEVEL, INSTANCE_LEVEL, CONFIGURATION_LEVEL, DEFAULT_LEVEL };
+
+ public int indexForLevel(String levelName);
+
+ public boolean isaPreferencesLevel(String possibleLevel);
+
+ /*
+ * The service applies to a particular language in a
+ * particular project, both which can be set dynamically
+ */
+
+ public void setLanguageName(String languageName);
+ public String getLanguageName();
+
+ public void setProjectName(String projectName);
+ public String getProjectName();
+
+ public void setProject(IProject project);
+ public IProject getProject();
+
+
+ /*
+ * Get and set preferences by batch by level
+ */
+ public IEclipsePreferences getPreferences(String level);
+ public void setPreferences(String level, IEclipsePreferences preferences);
+
+
+ /*
+ * Get applicable preferences by type
+ *
+ * Requests are evaluated relative to an implicit "current project"
+ * and an implicit "current language."
+ *
+ * It is an error to request a preference when the current langauge is
+ * not defined, because all preferences are assumed to be defined relative
+ * to some language.
+ *
+ * It is not an error to request a preference when the current project
+ * is not set. That is because a preference may not be defined on the
+ * project level even when the project is set, and preferences are
+ * returned from the lowest level at which set in any case, so that a
+ * value can be returned from some higher level when the project is
+ * undefined.
+ *
+ * Preferences are returned from the lowest level at which set. If no
+ * preference is defined for a given key at all levels, then an apporpriate
+ * default value is returned. This is 0 for the numeric preferences,
+ * false for boolean preferences, the empty string for String preferences,
+ * and the empty array for byte[].
+ */
+ public boolean getBooleanPreference(String key);
+ public byte[] getByteArrayPreference(String key);
+ public double getDoublePreference(String key);
+ public float getFloatPreference(String key);
+ public int getIntPreference(String key);
+ public long getLongPreference(String key);
+ public String getStringPreference(String key);
+ public String getRawStringPreference(String key);
+
+
+ /*
+ * Get applicable preferences by project and type
+ *
+ * Requests are evaluated relative to an implicit "current language."
+ * It is an error to request a preference when the current langauge is
+ * not defined, because all preferences are assumed to be defined relative
+ * to some language.
+ *
+ * Requests are evaluated relative to a given project, regardless of
+ * whether there is a "current project" defined.
+ *
+ * Preferences are returned from the lowest level at which set. If no
+ * preference is defined for a given key at all levels, then an apporpriate
+ * default value is returned. This is 0 for the numeric preferences,
+ * false for boolean preferences, the empty string for String preferences,
+ * and the empty array for byte[].
+ */
+ public boolean getBooleanPreference(IProject project, String key);
+ public byte[] getByteArrayPreference(IProject project, String key);
+ public double getDoublePreference(IProject project, String key);
+ public float getFloatPreference(IProject project, String key);
+ public int getIntPreference(IProject project, String key);
+ public long getLongPreference(IProject project, String key);
+ public String getStringPreference(IProject project, String key);
+ public String getRawStringPreference(IProject project, String key);
+
+
+ /*
+ * Get preferences for a given level by type
+ *
+ * Requests are evaluated relative to an implicit "current language."
+ * It is an error to request a preference when the current langauge is
+ * not defined, because all preferences are assumed to be defined relative
+ * to some language.
+ *
+ * Requests are evaluated relative to the given level only.
+ * If a preference for the given key is defined at that level, then
+ * the associated value is returned. If no preferences is defined
+ * for the given key at that level, then a suitable default value
+ * is returned. This is 0 for the numeric preferences, false for
+ * boolean preferences, the empty string for String preferences,
+ * and the empty array for byte[].
+ *
+ * If the given level is the project level, then requests are
+ * evaluated relative to an implicit "current project." It is
+ * an error to request a preference from the project level when
+ * no current project is defined.
+ */
+ public boolean getBooleanPreference(String level, String key);
+ public byte[] getByteArrayPreference(String level, String key);
+ public double getDoublePreference(String level, String key);
+ public float getFloatPreference(String level, String key);
+ public int getIntPreference(String level, String key);
+ public long getLongPreference(String level, String key);
+ public String getStringPreference(String level, String key);
+ public String getRawStringPreference(String level, String key);
+
+
+ /*
+ * Get preferences for a given project by type
+ *
+ * Requests are evaluated relative to an implicit "current language."
+ * It is an error to request a preference when the current langauge is
+ * not defined, because all preferences are assumed to be defined relative
+ * to some language.
+ *
+ * Requests are evaluated relative to the given project only. If a
+ * preference for the given key is defined for that project, then the
+ * associated value is returned. If no preferences is defined
+ * for the given key in the given project, then a suitable default value
+ * is returned. This is 0 for the numeric preferences, false for boolean
+ * preferences, the empty string for String preferences, and the empty
+ * array for byte[].
+ */
+ public boolean getBooleanPreferenceForProject(IProject project, String key);
+ public byte[] getByteArrayPreferenceForProject(IProject project, String key);
+ public double getDoublePreferenceForProject(IProject project, String key);
+ public float getFloatPreferenceForProject(IProject project, String key);
+ public int getIntPreferenceForProject(IProject project, String key);
+ public long getLongPreferenceForProject(IProject project, String key);
+ public String getStringPreferenceForProject(IProject project, String key);
+ public String getRawStringPreferenceForProject(IProject project, String key);
+
+
+ /*
+ * Set preferences for a given level by type
+ */
+ public void setBooleanPreference(String level, String key, boolean value);
+ public void setByteArrayPreference(String level, String key, byte[] value);
+ public void setDoublePreference(String level, String key, double value);
+ public void setFloatPreference(String level, String key, float value);
+ public void setIntPreference(String level, String key, int value);
+ public void setLongPreference(String level, String key, long value);
+ public void setStringPreference(String level, String key, String value);
+
+
+ /*
+ * Get preferences for a given level, language, and project by type
+ */
+ public boolean getBooleanPreference(String languageName, String projectName, String level, String key, boolean def);
+ public byte[] getByteArrayPreference(String languageName, String projectName, String level, String key, byte[] def);
+ public double getDoublePreference(String languageName, String projectName, String level, String key, double def);
+ public float getFloatPreference(String languageName, String projectName, String level, String key, float def);
+ public int getIntPreference(String languageName, String projectName, String level, String key, int def);
+ public long getLongPreference(String languageName, String projectName, String level, String key, long def);
+ public String getStringPreference(String languageName, String projectName, String level, String key, String def);
+ public String getRawStringPreference(String languageName, String projectName, String level, String key, String def);
+
+ /*
+ * Set preferences for a given level, language, and project by type
+ */
+ public void setBooleanPreference(String languageName, String projectName, String level, String key, boolean value);
+ public void setByteArrayPreference(String languageName, String projectName, String level, String key, byte[] value);
+ public void setDoublePreference(String languageName, String projectName, String level, String key, double value);
+ public void setFloatPreference(String languageName, String projectName, String level, String key, float value);
+ public void setIntPreference(String languageName, String projectName, String level, String key, int value);
+ public void setLongPreference(String languageName, String projectName, String level, String key, long value);
+ public void setStringPreference(String languageName, String projectName, String level, String key, String value);
+
+ /**
+ * @return the result of performing all preference substitutions on the
+ * given value, which can include references of the form "${prefKey}" or
+ * "${pluginLoc:pluginID}". The values of any preference references are
+ * obtained in the context of the project associated with this
+ * {@link IPreferencesService}, if any.
+ */
+ public String performSubstitutions(String value);
+
+ /**
+ * @return the result of performing all preference substitutions on the
+ * given value, which can include references of the form "${prefKey}" or
+ * "${pluginLoc:pluginID}". Use the given project as the context for
+ * obtaining the values of referenced preferences.
+ */
+ public String performSubstitutions(String value, IProject project);
+
+ /*
+ * Clear preferences at a given level
+ *
+ * The first two methods operate relative to an implicit "current project."
+ * It is an error to invoke these methods for the project level when there is
+ * no currently defined project.
+ *
+ * The second two meethods operate relative to a given project, regardless of
+ * whether a current project is set. These are intended to address the clearing
+ * of preferences on the project level, but it is not an error (if nevertheless
+ * pointless) to use them to clear preferences on another level.
+ *
+ * The "clear preferences" methods clear all preferences on the given level.
+ * The "clear preference" methods clear the given preference on the given
+ * level; if the preference is not defined on that level then these methods
+ * should have no effect.
+ */
+ public IEclipsePreferences clearPreferencesAtLevel(String level);
+ public String clearPreferenceAtLevel(String level, String key);
+ public IEclipsePreferences clearPreferencesAtLevel(IProject project, String level);
+ public String clearPreferenceAtLevel(IProject project, String level, String key);
+
+
+
+ /*
+ * Regarding where and whether a preference is defined
+ *
+ * The first three methods operate relative to an implicit "current project."
+ * It is an error to invoke the first two of these methods for the project level
+ * when there is no currently defined project.
+ *
+ * The second three methods operate relative to a given project, regardless of
+ * whether a current project is set. For those methods that take a preferences
+ * level, it is not an error (if nevertheless pointless) to invoke these methods
+ * with a levels other than the project level.
+ *
+ * The getApplicableLevel(..) methods get the preferences level, at or above a
+ * given level, at which a preference is defined for a given key. They return
+ * null if no such level is found.
+ *
+ * The isDefault(..) methods indicate for a given key whether the value that
+ * applies at a given level is the default value (that is, the value associated
+ * with the given key on the default preference level).
+ *
+ * The isDefined(..) methods indicate for a given key whether a value is defined
+ * for that key at some level.
+ */
+ public String getApplicableLevel(String key, String level);
+ public boolean isDefault(String key, String level);
+ public boolean isDefined(String key);
+ public String getApplicableLevel(IProject project, String key, String level);
+ public boolean isDefault(IProject project, String key, String level);
+ public boolean isDefined(IProject project, String key);
+
+
+ /*
+ * Regarding contexts and nodes
+ */
+
+ /**
+ * Return the preferences root node (its children are
+ * the nodes for the various preferences levels)
+ */
+ public IEclipsePreferences getRootNode();
+
+ /**
+ * Return the preferences node for a given preferences level.
+ *
+ * @param level The String name of a preferences level
+ * @return The preferences node for that level
+ * @throws IllegalArgumentException if level is null of
+ * is not a recognized preferences level name;
+ * IllegalStateException if level designates the
+ * project level and the current project is not
+ * defined
+ */
+ public IEclipsePreferences getNodeForLevel(String level);
+
+
+ /**
+ * Return the preferences node for a given project, regardless
+ * of whether this is the curently defined project.
+ *
+ * @param project An IProject indicating the project for which
+ * preferences are sought
+ * @return The preferences node for the given project
+ * @throws IllegalArgumentException if the given project
+ * is null
+ */
+ public IEclipsePreferences getNodeForProject(IProject project);
+
+
+ /**
+ * Return an array of preferences nodes, one for each of the
+ * four (main) preferences levels: project, (workspace) instance,
+ * (workspace) configuration, and default. If there is no
+ * current project defined, then the project preferences node
+ * will be null.
+ *
+ * @return An array of preferences nodes, in order
+ * from lowest (project) to highest (default)
+ */
+ public IEclipsePreferences[] getNodesForLevels();
+
+
+ /**
+ * Return an array of preferences nodes, one for each of the
+ * four (main) preferences levels: project, (workspace) instance,
+ * (workspace) configuration, and default. Use a given project
+ *
+ * @param project
+ * @return
+ */
+ public IEclipsePreferences[] getNodesForLevels(IProject project);
+ public IScopeContext getScopeForLevel(String level);
+ public IScopeContext getScopeForProject(IProject project);
+ public int getIndexForLevel(String level);
+
+
+ public abstract class PreferenceServiceListener implements IPreferenceChangeListener {
+ private final String fKey;
+ private final IEclipsePreferences fConfigLevel;
+ private final IEclipsePreferences fWSLevel;
+ private final IEclipsePreferences fProjLevel;
+
+ PreferenceServiceListener(IPreferencesService service, String key) {
+ fKey= key;
+ fConfigLevel= service.getPreferences(IPreferencesService.CONFIGURATION_LEVEL);
+ fWSLevel= service.getPreferences(IPreferencesService.INSTANCE_LEVEL);
+ fProjLevel= service.getPreferences(IPreferencesService.PROJECT_LEVEL);
+
+ fConfigLevel.addPreferenceChangeListener(this);
+ fWSLevel.addPreferenceChangeListener(this);
+ fProjLevel.addPreferenceChangeListener(this);
+ }
+
+ public void preferenceChange(PreferenceChangeEvent event) {
+ if (!event.getKey().equals(fKey))
+ return;
+ handleChange(event.getOldValue(), event.getNewValue());
+ }
+
+ public void dispose() {
+ fConfigLevel.removePreferenceChangeListener(this);
+ fWSLevel.removePreferenceChangeListener(this);
+ fProjLevel.removePreferenceChangeListener(this);
+ }
+
+ protected abstract void handleChange(Object oldValue, Object newValue);
+ }
+
+ public abstract class StringPreferenceListener extends PreferenceServiceListener {
+ public StringPreferenceListener(IPreferencesService service, String key) {
+ super(service, key);
+ }
+ @Override
+ protected final void handleChange(Object oldValue, Object newValue) {
+ changed((String) oldValue, (String) newValue);
+ }
+ public abstract void changed(String oldValue, String newValue);
+ }
+
+ public abstract class BooleanPreferenceListener extends PreferenceServiceListener {
+ public BooleanPreferenceListener(IPreferencesService service, String key) {
+ super(service, key);
+ }
+ @Override
+ protected final void handleChange(Object oldValue, Object newValue) {
+ changed(Boolean.parseBoolean((String) oldValue), Boolean.parseBoolean((String) newValue));
+ }
+ public abstract void changed(boolean oldValue, boolean newValue);
+ }
+
+ public abstract class IntegerPreferenceListener extends PreferenceServiceListener {
+ public IntegerPreferenceListener(IPreferencesService service, String key) {
+ super(service, key);
+ }
+ protected final void handleChange(Object oldValue, Object newValue) {
+ changed(Integer.parseInt((String) oldValue), Integer.parseInt((String) newValue));
+ }
+ public abstract void changed(int oldValue, int newValue);
+ }
+
+
+ /*
+ * For monitoring changes in the selected project
+ */
+
+ public void addProjectSelectionListener(IProjectSelectionListener listener);
+ public void removeProjectSelectionListener(IProjectSelectionListener listener);
+
+
+ public final class ProjectSelectionEvent { //extends EventObject {
+ /**
+ * All serializable objects should have a stable serialVersionUID
+ */
+ private static final long serialVersionUID = 1L;
+
+ private Preferences previous;
+ private Preferences neww;
+
+ /**
+ * Constructor for a new node change event object.
+ *
+ * @param parent the parent node
+ * @param child the child node
+ */
+ public ProjectSelectionEvent(Preferences previous, Preferences neww) {
+ //super(neww);
+ this.previous = previous;
+ this.neww = neww;
+ }
+
+ /**
+ * Return the preferences node for the previously selected project.
+ * May be null if there was no previously selected project.
+ *
+ * @return the previous node
+ */
+ public Preferences getPrevious() {
+ return previous;
+ }
+
+ /**
+ * Return the preferences node for the newly selected project.
+ * May be null if somehow the selection is nullified.
+ * </p>
+ * @return the new node
+ */
+ public Preferences getNew() {
+ return neww;
+ }
+ }
+
+
+
+ /**
+ * A listener to be used to receive events that signal the selection
+ * of a project as the focus for project preferences.
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ *
+ * @since 3.0
+ */
+ public interface IProjectSelectionListener {
+
+ /**
+ * Notification that a project was selected
+ * The given event must not be <code>null</code>.
+ *
+ * @param event an event specifying the details about the new node
+ */
+ public void selection(ProjectSelectionEvent event);
+
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/InstancePreferencesTab.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/InstancePreferencesTab.java
new file mode 100644
index 000000000..3dc6e0a2b
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/InstancePreferencesTab.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences;
+
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+
+public abstract class InstancePreferencesTab extends PreferencesTab {
+
+ public InstancePreferencesTab(IPreferencesService prefService, boolean noDetails) {
+ super(IPreferencesService.INSTANCE_LEVEL, noDetails);
+ this.fPrefService = prefService;
+ fPrefUtils = new PreferencesUtilities(prefService);
+ }
+
+ @Override
+ public Composite createTabContents(TabbedPreferencesPage page, final TabFolder tabFolder) {
+
+ fPrefPage = page;
+
+ int numColumns= getNoDetails() ? 1 : 2;
+
+ final Composite composite= new Composite(tabFolder, SWT.NONE);
+ composite.setFont(tabFolder.getFont());
+ final GridData gd= new GridData(SWT.FILL, SWT.CENTER, true, false);
+ gd.widthHint= 0;
+ gd.heightHint= SWT.DEFAULT;
+ gd.horizontalSpan= 1;
+ composite.setLayoutData(gd);
+
+ GridLayout gl = new GridLayout();
+ gl.numColumns = numColumns;
+ composite.setLayout(gl);
+
+ fTabItem = new TabItem(tabFolder, SWT.NONE);
+ fTabItem.setText("Workspace");
+ fTabItem.setControl(composite);
+ PreferencesTab.TabSelectionListener listener =
+ new PreferencesTab.TabSelectionListener(fPrefPage, fTabItem);
+ tabFolder.addSelectionListener(listener);
+
+
+ /*
+ * Add the elements relating to preferences fields and their associated "details" links.
+ */
+ fFields = createFields(page, composite);
+
+ PreferencesUtilities.fillGridPlace(composite, numColumns);
+
+ // Don't want newly created fields to be flagged as modified
+ clearModifiedMarksOnLabels();
+
+ // Put notes on bottom
+
+ final Composite bottom = new Composite(composite, SWT.BOTTOM | SWT.WRAP);
+ GridLayout layout = new GridLayout();
+ bottom.setLayout(layout);
+ bottom.setLayoutData(new GridData(SWT.BOTTOM));
+
+ Label bar = new Label(bottom, SWT.WRAP);
+ GridData data = new GridData();
+ data.verticalAlignment = SWT.WRAP;
+ bar.setLayoutData(data);
+ bar.setText("Preferences shown with a white background are set on this level.\n\n" +
+ "Preferences shown with a colored background are inherited from a\nhigher level.\n\n" +
+ Markings.MODIFIED_NOTE + "\n\n" +
+ Markings.TAB_ERROR_NOTE);
+
+ PreferencesUtilities.fillGridPlace(bottom, 1);
+
+ // Put buttons on the bottom
+ fButtons = fPrefUtils.createDefaultAndApplyButtons(composite, this);
+
+ return composite;
+ }
+
+
+
+
+// public void performApply()
+// {
+// for (int i = 0; i < fields.length; i++) {
+// fields[i].store();
+// fields[i].clearModifyMarkOnLabel();
+// }
+// }
+
+
+
+ public void performDefaults() {
+ // Clear all preferences for this page at this level;
+ // "default" values will be set by inheritance from a higher level
+ PreferencesInitializer initializer = fPrefPage.getPreferenceInitializer();
+ initializer.clearPreferencesOnLevel(IPreferencesService.INSTANCE_LEVEL);
+
+ for (int i = 0; i < fFields.length; i++) {
+ fFields[i].loadWithInheritance();
+ }
+ }
+
+
+// public boolean performOk() {
+// // Example: Store each field
+// for (int i = 0; i < fields.length; i++) {
+// fields[i].store();
+// }
+// return true;
+// }
+
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/Markings.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/Markings.java
new file mode 100644
index 000000000..8ba2c859d
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/Markings.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences;
+
+public class Markings {
+
+ private Markings() {};
+
+ static public final String MODIFIED_NOTE = "Modified fields are marked in red.";
+
+ static public final String TAB_ERROR_MARK = "**";
+ static public final String TAB_ERROR_NOTE = "Tabs with erroneous fields are marked with \"" +
+ TAB_ERROR_MARK + "\"";
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceCache.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceCache.java
new file mode 100644
index 000000000..fa9796d6e
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceCache.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences;
+
+import org.eclipse.swt.graphics.Font;
+
+public class PreferenceCache {
+ public static boolean emitMessages= false;
+
+ public static int tabWidth= 8;
+
+ public static Font sourceFont;
+
+ public static boolean dumpTokens= false;
+
+ private PreferenceCache() { }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceConstants.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceConstants.java
new file mode 100644
index 000000000..68f1b113a
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceConstants.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences;
+
+public class PreferenceConstants {
+ public static final String P_EMIT_MESSAGES= "emitMessages";
+
+ public static final String P_TAB_WIDTH= "tabWidth";
+
+ public static final String P_SOURCE_FONT= "sourceFont";
+
+ public static final String P_DUMP_TOKENS= "dumpTokens";
+
+ /**
+ * A named preference that controls whether the project explorer's selection is linked to the active editor.
+ * <p>
+ * Value is of type <code>Boolean</code>.
+ * </p>
+ */
+ public static final String LINK_EXPLORER_TO_EDITOR= "org.eclipse.imp.ui.projects.linktoeditor"; //$NON-NLS-1$
+
+ /**
+ * A named preference that controls whether bracket matching highlighting is turned on or off.
+ * <p>
+ * Value is of type <code>Boolean</code>.
+ * </p>
+ */
+ public static final String EDITOR_MATCHING_BRACKETS= "matchingBrackets"; //$NON-NLS-1$
+
+ /**
+ * A named preference that holds the color used to highlight matching brackets.
+ * <p>
+ * Value is of type <code>String</code>. A RGB color value encoded as a string
+ * using class <code>PreferenceConverter</code>
+ * </p>
+ *
+ * @see org.eclipse.jface.resource.StringConverter
+ * @see org.eclipse.jface.preference.PreferenceConverter
+ */
+ public static final String EDITOR_MATCHING_BRACKETS_COLOR= "matchingBracketsColor"; //$NON-NLS-1$
+
+ /**
+ * A named preference that controls whether "fences" (e.g. parens or braces) are automatically closed.
+ * <p>
+ * Value is of type <code>Boolean</code>.
+ * </p>
+ */
+ public static final String EDITOR_CLOSE_FENCES= "closeFences"; //$NON-NLS-1$
+
+ /**
+ * A named preference that controls whether builders should emit diagnostics. Can be overridden
+ * by a language-specific builder preference of the same key.
+ * <p>
+ * Value is of type <code>Boolean</code>.
+ * </p>
+ */
+ public static final String P_EMIT_BUILDER_DIAGNOSTICS= "emitBuilderDiagnostics"; //$NON-NLS-1$
+
+ private PreferenceConstants() { }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceErrorUtilities.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceErrorUtilities.java
new file mode 100644
index 000000000..aa0b38e48
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceErrorUtilities.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences;
+
+
+
+
+public class PreferenceErrorUtilities {
+
+
+ public static void setErrorMessage(
+ PreferencePage page,
+ PreferencesTab tab,
+ String msg)
+ {
+
+
+
+
+ }
+
+
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceInitializer.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceInitializer.java
new file mode 100644
index 000000000..67f04de7a
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceInitializer.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.preferences;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.resource.ColorRegistry;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Initializes IMP framework-wide preferences to reasonable default values.
+ * @author rfuhrer@watson.ibm.com
+ */
+public class PreferenceInitializer extends AbstractPreferenceInitializer {
+ public void initializeDefaultPreferences() {
+ ColorRegistry registry= null;
+ if (PlatformUI.isWorkbenchRunning())
+ registry= PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().getColorRegistry();
+ IPreferenceStore store= RuntimePlugin.getInstance().getPreferenceStore();
+
+ store.setDefault(PreferenceConstants.P_EMIT_MESSAGES, false);
+ store.setDefault(PreferenceConstants.P_EMIT_BUILDER_DIAGNOSTICS, false);
+
+ // RMF 7/16/2008 - Somehow JFaceResources.getFont(symbolicName) and JFaceResources.getFontDescriptor()
+ // return different answers. Seems that getFontDescriptor() gives us a better answer, though.
+ FontData[] fontData= JFaceResources.getFontDescriptor("org.eclipse.jdt.ui.editors.textfont").getFontData();
+
+ if (fontData != null && fontData.length > 0)
+ PreferenceConverter.setDefault(store, PreferenceConstants.P_SOURCE_FONT, fontData);
+
+ store.setDefault(PreferenceConstants.P_TAB_WIDTH, 8);
+ store.setDefault(PreferenceConstants.P_DUMP_TOKENS, false);
+ store.setDefault(PreferenceConstants.EDITOR_MATCHING_BRACKETS, true);
+
+ PreferenceConverter.setDefault(store, PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR,
+ findRGB(registry, RuntimePlugin.IMP_RUNTIME + "." + PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR, new RGB(192, 192,192)));
+ }
+
+ /**
+ * Returns the RGB for the given key in the given color registry.
+ *
+ * @param registry the color registry
+ * @param key the key for the constant in the registry
+ * @param defaultRGB the default RGB if no entry is found
+ * @return RGB the RGB
+ * @since 3.3
+ */
+ private static RGB findRGB(ColorRegistry registry, String key, RGB defaultRGB) {
+ if (registry == null)
+ return defaultRGB;
+
+ RGB rgb= registry.getRGB(key);
+ if (rgb != null)
+ return rgb;
+
+ return defaultRGB;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencePage.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencePage.java
new file mode 100644
index 000000000..14e7a8bf6
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencePage.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences;
+
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.jface.preference.BooleanFieldEditor;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.jface.preference.FontFieldEditor;
+import org.eclipse.jface.preference.IntegerFieldEditor;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+public class PreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
+ public PreferencePage() {
+ super(GRID);
+ setPreferenceStore(RuntimePlugin.getInstance().getPreferenceStore());
+ setDescription("Preferences for the IMP framework");
+ }
+
+ public void createFieldEditors() {
+ final BooleanFieldEditor emitMessagesField= new BooleanFieldEditor(PreferenceConstants.P_EMIT_MESSAGES, "E&mit diagnostic messages from IMP UI",
+ getFieldEditorParent());
+ addField(emitMessagesField);
+
+ final BooleanFieldEditor dumpTokensField= new BooleanFieldEditor(PreferenceConstants.P_DUMP_TOKENS, "&Dump tokens after scanning",
+ getFieldEditorParent());
+ addField(dumpTokensField);
+
+ final BooleanFieldEditor emitBuilderDiagnosticsField= new BooleanFieldEditor(PreferenceConstants.P_EMIT_BUILDER_DIAGNOSTICS, "Emit diagnostic messages while building",
+ getFieldEditorParent());
+ addField(emitBuilderDiagnosticsField);
+
+ final IntegerFieldEditor tabWidthField= new IntegerFieldEditor(PreferenceConstants.P_TAB_WIDTH, "&Tab width:", getFieldEditorParent());
+ tabWidthField.setValidRange(1, 16);
+ tabWidthField.setTextLimit(2);
+ tabWidthField.setEmptyStringAllowed(false);
+ addField(tabWidthField);
+
+ final FontFieldEditor fontField= new FontFieldEditor(PreferenceConstants.P_SOURCE_FONT, "Source font:", getFieldEditorParent());
+ addField(fontField);
+
+ // Don't need a preference store listener here; the UniversalEditor already listens
+ // to the preference store, and takes the necessary actions. Moreover, some preference
+ // changes require some resource management that only it can do properly (e.g. it must
+ // only dispose of the old Font *after* telling the ITextViewer to use the new one).
+ }
+
+ public void init(IWorkbench workbench) {
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.g b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.g
new file mode 100644
index 000000000..1b290da75
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.g
@@ -0,0 +1,501 @@
+%options programming_language=java
+%options table
+%options la=1
+%options margin=4
+%options package=org.eclipse.imp.preferences
+%options prefix=Char_
+%options fp=PreferenceValueParser
+%options automatic_ast,ast_type=ASTNode,visitor=preorder,parent_saved
+%options action-block=("*.java", "/.", "./")
+%options ParseTable=lpg.runtime.ParseTable
+
+--
+-- This is a scannerless parser for preference values that contain 0 or more
+-- possibly-nested substitutions, e.g.:
+-- "foobar${pluginLoc:lpg.runtime}bletchbletch"
+-- "abcdef"
+-- "${pluginResource:lpg.runtime/lpgexe/lpg-${os}_${arch}}"
+--
+-- Because there are no templates suitable for scannerless parsers in the standard
+-- LPG distribution, we roll our own here by directly including the relevant bits
+-- of various standard template files.
+--
+
+%EOF
+ EOF
+%End
+
+%Globals
+ /.import org.eclipse.imp.parser.IParser;
+ import java.util.ArrayList;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.HashMap;
+ import java.util.Set;
+ import lpg.runtime.*;
+ ./
+%End
+
+%Define
+ $Header
+ /.
+ //
+ // Rule $rule_number: $rule_text
+ //./
+
+ $BeginAction
+ /. $Header
+ case $rule_number: {./
+
+ $EndAction
+ /. break;
+ }./
+
+ $BeginJava
+ /.$BeginAction
+ $symbol_declarations./
+
+ $EndJava /.$EndAction./
+
+ $NoAction
+ /. $Header
+ case $rule_number:
+ break;./
+
+ $NullAction
+ /. $Header
+ case $rule_number:
+ $setResult(null);
+ break;./
+
+ $BeginActions
+ /.
+ public void ruleAction(int ruleNumber)
+ {
+ switch (ruleNumber)
+ {./
+
+ $SplitActions
+ /.
+ default:
+ ruleAction$rule_number(ruleNumber);
+ break;
+ }
+ return;
+ }
+
+ public void ruleAction$rule_number(int ruleNumber)
+ {
+ switch (ruleNumber)
+ {./
+
+ $EndActions
+ /.
+ default:
+ break;
+ }
+ return;
+ }./
+%End
+
+%Terminals
+ a b c d e f g h i j k l m
+ n o p q r s t u v w x y z
+ _
+
+ A B C D E F G H I J K L M
+ N O P Q R S T U V W X Y Z
+
+ 0 1 2 3 4 5 6 7 8 9
+
+ DoubleQuote ::= '"'
+ SingleQuote ::= "'"
+ Percent ::= '%'
+ VerticalBar ::= '|'
+ Exclamation ::= '!'
+ AtSign ::= '@'
+ BackQuote ::= '`'
+ Tilde ::= '~'
+ Sharp ::= '#'
+ DollarSign ::= '$'
+ Ampersand ::= '&'
+ Caret ::= '^'
+ Colon ::= ':'
+ SemiColon ::= ';'
+ BackSlash ::= '\'
+ LeftBrace ::= '{'
+ RightBrace ::= '}'
+ LeftBracket ::= '['
+ RightBracket ::= ']'
+ QuestionMark ::= '?'
+ Comma ::= ','
+ Dot ::= '.'
+ LessThan ::= '<'
+ GreaterThan ::= '>'
+ Plus ::= '+'
+ Minus ::= '-'
+ Slash ::= '/'
+ Star ::= '*'
+ LeftParen ::= '('
+ RightParen ::= ')'
+ Equal ::= '='
+ Space ::= ' '
+ CtlCharNotWS
+ HT
+ LF
+ FF
+ CR
+ AfterASCII
+%End
+
+%Start
+ value
+%End
+
+%Notice
+/.
+////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2007 IBM Corporation.
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+//Author: Robert Fuhrer (rfuhrer@watson.ibm.com)
+////////////////////////////////////////////////////////////////////////////////
+./
+%End
+
+%Headers
+ /.
+ public class $action_type implements $sym_type, RuleAction {
+ static class MyLexStream extends LpgLexStream {
+ public void initialize(char [] content) {
+ super.initialize(content, "");
+ }
+
+ public final static int tokenKind[] = {
+ Char_CtlCharNotWS, // 000 0x00
+ Char_CtlCharNotWS, // 001 0x01
+ Char_CtlCharNotWS, // 002 0x02
+ Char_CtlCharNotWS, // 003 0x03
+ Char_CtlCharNotWS, // 004 0x04
+ Char_CtlCharNotWS, // 005 0x05
+ Char_CtlCharNotWS, // 006 0x06
+ Char_CtlCharNotWS, // 007 0x07
+ Char_CtlCharNotWS, // 008 0x08
+ Char_HT, // 009 0x09
+ Char_LF, // 010 0x0A
+ Char_CtlCharNotWS, // 011 0x0B
+ Char_FF, // 012 0x0C
+ Char_CR, // 013 0x0D
+ Char_CtlCharNotWS, // 014 0x0E
+ Char_CtlCharNotWS, // 015 0x0F
+ Char_CtlCharNotWS, // 016 0x10
+ Char_CtlCharNotWS, // 017 0x11
+ Char_CtlCharNotWS, // 018 0x12
+ Char_CtlCharNotWS, // 019 0x13
+ Char_CtlCharNotWS, // 020 0x14
+ Char_CtlCharNotWS, // 021 0x15
+ Char_CtlCharNotWS, // 022 0x16
+ Char_CtlCharNotWS, // 023 0x17
+ Char_CtlCharNotWS, // 024 0x18
+ Char_CtlCharNotWS, // 025 0x19
+ Char_CtlCharNotWS, // 026 0x1A
+ Char_CtlCharNotWS, // 027 0x1B
+ Char_CtlCharNotWS, // 028 0x1C
+ Char_CtlCharNotWS, // 029 0x1D
+ Char_CtlCharNotWS, // 030 0x1E
+ Char_CtlCharNotWS, // 031 0x1F
+ Char_Space, // 032 0x20
+ Char_Exclamation, // 033 0x21
+ Char_DoubleQuote, // 034 0x22
+ Char_Sharp, // 035 0x23
+ Char_DollarSign, // 036 0x24
+ Char_Percent, // 037 0x25
+ Char_Ampersand, // 038 0x26
+ Char_SingleQuote, // 039 0x27
+ Char_LeftParen, // 040 0x28
+ Char_RightParen, // 041 0x29
+ Char_Star, // 042 0x2A
+ Char_Plus, // 043 0x2B
+ Char_Comma, // 044 0x2C
+ Char_Minus, // 045 0x2D
+ Char_Dot, // 046 0x2E
+ Char_Slash, // 047 0x2F
+ Char_0, // 048 0x30
+ Char_1, // 049 0x31
+ Char_2, // 050 0x32
+ Char_3, // 051 0x33
+ Char_4, // 052 0x34
+ Char_5, // 053 0x35
+ Char_6, // 054 0x36
+ Char_7, // 055 0x37
+ Char_8, // 056 0x38
+ Char_9, // 057 0x39
+ Char_Colon, // 058 0x3A
+ Char_SemiColon, // 059 0x3B
+ Char_LessThan, // 060 0x3C
+ Char_Equal, // 061 0x3D
+ Char_GreaterThan, // 062 0x3E
+ Char_QuestionMark, // 063 0x3F
+ Char_AtSign, // 064 0x40
+ Char_A, // 065 0x41
+ Char_B, // 066 0x42
+ Char_C, // 067 0x43
+ Char_D, // 068 0x44
+ Char_E, // 069 0x45
+ Char_F, // 070 0x46
+ Char_G, // 071 0x47
+ Char_H, // 072 0x48
+ Char_I, // 073 0x49
+ Char_J, // 074 0x4A
+ Char_K, // 075 0x4B
+ Char_L, // 076 0x4C
+ Char_M, // 077 0x4D
+ Char_N, // 078 0x4E
+ Char_O, // 079 0x4F
+ Char_P, // 080 0x50
+ Char_Q, // 081 0x51
+ Char_R, // 082 0x52
+ Char_S, // 083 0x53
+ Char_T, // 084 0x54
+ Char_U, // 085 0x55
+ Char_V, // 086 0x56
+ Char_W, // 087 0x57
+ Char_X, // 088 0x58
+ Char_Y, // 089 0x59
+ Char_Z, // 090 0x5A
+ Char_LeftBracket, // 091 0x5B
+ Char_BackSlash, // 092 0x5C
+ Char_RightBracket, // 093 0x5D
+ Char_Caret, // 094 0x5E
+ Char__, // 095 0x5F
+ Char_BackQuote, // 096 0x60
+ Char_a, // 097 0x61
+ Char_b, // 098 0x62
+ Char_c, // 099 0x63
+ Char_d, // 100 0x64
+ Char_e, // 101 0x65
+ Char_f, // 102 0x66
+ Char_g, // 103 0x67
+ Char_h, // 104 0x68
+ Char_i, // 105 0x69
+ Char_j, // 106 0x6A
+ Char_k, // 107 0x6B
+ Char_l, // 108 0x6C
+ Char_m, // 109 0x6D
+ Char_n, // 110 0x6E
+ Char_o, // 111 0x6F
+ Char_p, // 112 0x70
+ Char_q, // 113 0x71
+ Char_r, // 114 0x72
+ Char_s, // 115 0x73
+ Char_t, // 116 0x74
+ Char_u, // 117 0x75
+ Char_v, // 118 0x76
+ Char_w, // 119 0x77
+ Char_x, // 120 0x78
+ Char_y, // 121 0x79
+ Char_z, // 122 0x7A
+ Char_LeftBrace, // 123 0x7B
+ Char_VerticalBar, // 124 0x7C
+ Char_RightBrace, // 125 0x7D
+ Char_Tilde, // 126 0x7E
+
+ Char_AfterASCII, // for all chars in range 128..65534
+ Char_EOF // for '\uffff' or 65535
+ };
+
+ public final int getKind(int i) { // Classify character at ith location
+ char c = (i >= getStreamLength() ? '\uffff' : getCharValue(i));
+ return (c < 128 // ASCII Character
+ ? tokenKind[c]
+ : c == '\uffff'
+ ? $sym_type.Char_EOF
+ : $sym_type.Char_AfterASCII);
+ }
+ public String[] orderedExportedSymbols() { return $sym_type.orderedTerminalSymbols; }
+ };
+
+ private MyLexStream lexStream = new MyLexStream();
+
+ private static ParseTable prs = new $prs_type();
+ private DeterministicParser dtParser;
+
+ private void setResult(Object object) { dtParser.setSym1(object); }
+ public DeterministicParser getParser() { return dtParser; }
+
+ public Object getRhsSym(int i) { return dtParser.getSym(i); }
+
+ public int getRhsTokenIndex(int i) { return dtParser.getToken(i); }
+ public int getRhsFirstTokenIndex(int i) { return dtParser.getFirstToken(i); }
+ public int getRhsLastTokenIndex(int i) { return dtParser.getLastToken(i); }
+
+ public IToken getLeftIToken() { return new MyToken(dtParser.getFirstToken(), lexStream); }
+ public IToken getRightIToken() { return new MyToken(dtParser.getLastToken(), lexStream); }
+
+ public IToken getRhsIToken(int idx) { return new MyToken(dtParser.getToken(idx), lexStream); }
+
+ public int getLeftSpan() { return dtParser.getFirstToken(); }
+ public int getRightSpan() { return dtParser.getLastToken(); }
+
+ public int getEOFTokenKind() { return $prs_type.EOFT_SYMBOL; }
+ public LpgLexStream getLexStream() { return lexStream; }
+
+ private String errorMsg= "";
+
+ public String getErrorMessage() { return errorMsg; }
+
+ public $ast_type parser(String input) {
+ try {
+ lexStream.initialize(input.toCharArray());
+ dtParser = new DeterministicParser(lexStream, prs, this);
+ } catch (NotDeterministicParseTableException e) {
+ System.out.println("****Error: Regenerate $prs_type.java with -NOBACKTRACK option");
+ return null;
+ } catch (BadParseSymFileException e) {
+ System.out.println("****Error: Bad Parser Symbol File -- $sym_type.java. Regenerate $prs_type.java");
+ return null;
+ }
+
+ try {
+ return ($ast_type) dtParser.parse();
+ } catch (BadParseException e) {
+ errorMsg= "unexpected";
+ if (e.error_token < lexStream.getStreamLength())
+ errorMsg += " character '" + lexStream.getCharValue(e.error_token) + "' at offset " + e.error_token;
+ else
+ errorMsg += " end of string";
+ }
+ return null;
+ }
+
+ private class MyToken implements IToken {
+ private int offset;
+ private LpgLexStream lexStream;
+ public MyToken(int offset, LpgLexStream ls) {
+ this.offset= offset;
+ this.lexStream= ls;
+ }
+ public int getKind() { return lexStream.getKind(lexStream.getInputChars()[offset]); }
+ public void setKind(int kind) { }
+
+ public int getStartOffset() { return offset; }
+ public void setStartOffset(int startOffset) { }
+
+ public int getEndOffset() { return offset; }
+ public void setEndOffset(int endOffset) { }
+
+ public int getTokenIndex() { return offset; }
+ public void setTokenIndex(int i) { }
+
+ public int getAdjunctIndex() { return -1; }
+ public void setAdjunctIndex(int i) { }
+
+ public IToken[] getPrecedingAdjuncts() { return null; }
+ public IToken[] getFollowingAdjuncts() { return null; }
+
+ public IPrsStream getPrsStream() { return null; }
+ public LpgLexStream getLexStream() { return lexStream; }
+ public IPrsStream getIPrsStream() { return null; }
+ public LpgLexStream getILexStream() { return lexStream; }
+
+ public int getLine() { return lexStream.getLine(offset); }
+ public int getColumn() { return lexStream.getColumn(offset); }
+ public int getEndLine() { return lexStream.getLine(offset); }
+ public int getEndColumn() { return lexStream.getColumn(offset); }
+
+ public String getValue(char[] inputChars) { return toString(); }
+
+ public String toString() {
+ return new String(new char[] { lexStream.getInputChars()[offset] });
+ }
+ }
+ ./
+%End
+
+%Rules
+ /.$BeginActions./
+
+ digit$ ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
+
+ aA$ ::= a | A
+ bB$ ::= b | B
+ cC$ ::= c | C
+ dD$ ::= d | D
+ eE$ ::= e | E
+ fF$ ::= f | F
+ gG$ ::= g | G
+ hH$ ::= h | H
+ iI$ ::= i | I
+ jJ$ ::= j | J
+ kK$ ::= k | K
+ lL$ ::= l | L
+ mM$ ::= m | M
+ nN$ ::= n | N
+ oO$ ::= o | O
+ pP$ ::= p | P
+ qQ$ ::= q | Q
+ rR$ ::= r | R
+ sS$ ::= s | S
+ tT$ ::= t | T
+ uU$ ::= u | U
+ vV$ ::= v | V
+ wW$ ::= w | W
+ xX$ ::= x | X
+ yY$ ::= y | Y
+ zZ$ ::= z | Z
+
+ letter$ ::= aA | bB | cC | dD | eE | fF | gG | hH | iI | jJ | kK | lL
+ | mM | nN | oO | pP | qQ | rR | sS | tT | uU | vV | wW | xX | yY | zZ
+
+ -- "foobar${pluginLoc:lpg.runtime}bletchbletch"
+ -- "abcdef"
+ -- "${pluginResource:lpg.runtime/lpgexe/lpg-${os}_${arch}}"
+
+ value ::= simpleStringPrefixed
+ | substPrefixed
+
+ simpleStringPrefixed$simpleStringPrefixed ::= valStringNoSubst | valStringNoSubst substPrefixed
+
+ valStringNoSubst$valStringNoSubst ::= valueStringNoSubst$
+
+ substPrefixed ::= substitutionList | substitutionList simpleStringPrefixed
+
+ substitutionList$$substitution ::= substitution | substitutionList substitution
+
+ valueStringNoSubst$ ::= nonSubstStart
+ | escapedChar
+ | valueStringNoSubst escapedChar
+ | valueStringNoSubst letter
+ | valueStringNoSubst digit
+ | valueStringNoSubst specialNoDollarRBrace
+
+ substitution ::= '$'$ '{'$ ident optParameter '}'$
+
+ optParameter ::= %empty | ':'$ value
+
+ ident$ident ::= identChars$
+ identChars$ ::= letter | identChars letter | identChars digit
+
+ nonSubstStart$ ::= letter | digit | specialNoDollarRBrace
+
+ escapedChar ::= '\'$ escapableChar
+ escapableChar ::= letter | digit | special
+
+ specialNoDollarRBrace ::= '+' | '-' | '(' | ')' | '"' | '!' | '@' | '`' | '~' | '.' | '/' |
+ '%' | '&' | '^' | ':' | ';' | "'" | '|' | '{' | ' ' |
+ '[' | ']' | '?' | ',' | '<' | '>' | '=' | '#' | '*' | '_'
+
+ special ::= '+' | '-' | '(' | ')' | '"' | '!' | '@' | '`' | '~' | '.' | '/' |
+ '%' | '&' | '^' | ':' | ';' | "'" | '\' | '|' | '{' | ' ' | '}' |
+ '[' | ']' | '?' | ',' | '<' | '>' | '=' | '#' | '*' | '_' | '$'
+%End
+
+%Trailers
+ /.
+ $EndActions
+ }
+ ./
+%End
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.java
new file mode 100644
index 000000000..c931a551f
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.java
@@ -0,0 +1,5250 @@
+
+////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2007 IBM Corporation.
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+//Author: Robert Fuhrer (rfuhrer@watson.ibm.com)
+////////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.imp.preferences;
+
+import org.eclipse.imp.parser.IParser;
+ import java.util.ArrayList;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.HashMap;
+ import java.util.Set;
+ import lpg.runtime.*;
+
+public class PreferenceValueParser implements PreferenceValueParsersym, RuleAction {
+ static class MyLexStream extends LpgLexStream {
+ public void initialize(char [] content) {
+ super.initialize(content, "");
+ }
+
+ public final static int tokenKind[] = {
+ Char_CtlCharNotWS, // 000 0x00
+ Char_CtlCharNotWS, // 001 0x01
+ Char_CtlCharNotWS, // 002 0x02
+ Char_CtlCharNotWS, // 003 0x03
+ Char_CtlCharNotWS, // 004 0x04
+ Char_CtlCharNotWS, // 005 0x05
+ Char_CtlCharNotWS, // 006 0x06
+ Char_CtlCharNotWS, // 007 0x07
+ Char_CtlCharNotWS, // 008 0x08
+ Char_HT, // 009 0x09
+ Char_LF, // 010 0x0A
+ Char_CtlCharNotWS, // 011 0x0B
+ Char_FF, // 012 0x0C
+ Char_CR, // 013 0x0D
+ Char_CtlCharNotWS, // 014 0x0E
+ Char_CtlCharNotWS, // 015 0x0F
+ Char_CtlCharNotWS, // 016 0x10
+ Char_CtlCharNotWS, // 017 0x11
+ Char_CtlCharNotWS, // 018 0x12
+ Char_CtlCharNotWS, // 019 0x13
+ Char_CtlCharNotWS, // 020 0x14
+ Char_CtlCharNotWS, // 021 0x15
+ Char_CtlCharNotWS, // 022 0x16
+ Char_CtlCharNotWS, // 023 0x17
+ Char_CtlCharNotWS, // 024 0x18
+ Char_CtlCharNotWS, // 025 0x19
+ Char_CtlCharNotWS, // 026 0x1A
+ Char_CtlCharNotWS, // 027 0x1B
+ Char_CtlCharNotWS, // 028 0x1C
+ Char_CtlCharNotWS, // 029 0x1D
+ Char_CtlCharNotWS, // 030 0x1E
+ Char_CtlCharNotWS, // 031 0x1F
+ Char_Space, // 032 0x20
+ Char_Exclamation, // 033 0x21
+ Char_DoubleQuote, // 034 0x22
+ Char_Sharp, // 035 0x23
+ Char_DollarSign, // 036 0x24
+ Char_Percent, // 037 0x25
+ Char_Ampersand, // 038 0x26
+ Char_SingleQuote, // 039 0x27
+ Char_LeftParen, // 040 0x28
+ Char_RightParen, // 041 0x29
+ Char_Star, // 042 0x2A
+ Char_Plus, // 043 0x2B
+ Char_Comma, // 044 0x2C
+ Char_Minus, // 045 0x2D
+ Char_Dot, // 046 0x2E
+ Char_Slash, // 047 0x2F
+ Char_0, // 048 0x30
+ Char_1, // 049 0x31
+ Char_2, // 050 0x32
+ Char_3, // 051 0x33
+ Char_4, // 052 0x34
+ Char_5, // 053 0x35
+ Char_6, // 054 0x36
+ Char_7, // 055 0x37
+ Char_8, // 056 0x38
+ Char_9, // 057 0x39
+ Char_Colon, // 058 0x3A
+ Char_SemiColon, // 059 0x3B
+ Char_LessThan, // 060 0x3C
+ Char_Equal, // 061 0x3D
+ Char_GreaterThan, // 062 0x3E
+ Char_QuestionMark, // 063 0x3F
+ Char_AtSign, // 064 0x40
+ Char_A, // 065 0x41
+ Char_B, // 066 0x42
+ Char_C, // 067 0x43
+ Char_D, // 068 0x44
+ Char_E, // 069 0x45
+ Char_F, // 070 0x46
+ Char_G, // 071 0x47
+ Char_H, // 072 0x48
+ Char_I, // 073 0x49
+ Char_J, // 074 0x4A
+ Char_K, // 075 0x4B
+ Char_L, // 076 0x4C
+ Char_M, // 077 0x4D
+ Char_N, // 078 0x4E
+ Char_O, // 079 0x4F
+ Char_P, // 080 0x50
+ Char_Q, // 081 0x51
+ Char_R, // 082 0x52
+ Char_S, // 083 0x53
+ Char_T, // 084 0x54
+ Char_U, // 085 0x55
+ Char_V, // 086 0x56
+ Char_W, // 087 0x57
+ Char_X, // 088 0x58
+ Char_Y, // 089 0x59
+ Char_Z, // 090 0x5A
+ Char_LeftBracket, // 091 0x5B
+ Char_BackSlash, // 092 0x5C
+ Char_RightBracket, // 093 0x5D
+ Char_Caret, // 094 0x5E
+ Char__, // 095 0x5F
+ Char_BackQuote, // 096 0x60
+ Char_a, // 097 0x61
+ Char_b, // 098 0x62
+ Char_c, // 099 0x63
+ Char_d, // 100 0x64
+ Char_e, // 101 0x65
+ Char_f, // 102 0x66
+ Char_g, // 103 0x67
+ Char_h, // 104 0x68
+ Char_i, // 105 0x69
+ Char_j, // 106 0x6A
+ Char_k, // 107 0x6B
+ Char_l, // 108 0x6C
+ Char_m, // 109 0x6D
+ Char_n, // 110 0x6E
+ Char_o, // 111 0x6F
+ Char_p, // 112 0x70
+ Char_q, // 113 0x71
+ Char_r, // 114 0x72
+ Char_s, // 115 0x73
+ Char_t, // 116 0x74
+ Char_u, // 117 0x75
+ Char_v, // 118 0x76
+ Char_w, // 119 0x77
+ Char_x, // 120 0x78
+ Char_y, // 121 0x79
+ Char_z, // 122 0x7A
+ Char_LeftBrace, // 123 0x7B
+ Char_VerticalBar, // 124 0x7C
+ Char_RightBrace, // 125 0x7D
+ Char_Tilde, // 126 0x7E
+
+ Char_AfterASCII, // for all chars in range 128..65534
+ Char_EOF // for '\uffff' or 65535
+ };
+
+ public final int getKind(int i) { // Classify character at ith location
+ char c = (i >= getStreamLength() ? '\uffff' : getCharValue(i));
+ return (c < 128 // ASCII Character
+ ? tokenKind[c]
+ : c == '\uffff'
+ ? PreferenceValueParsersym.Char_EOF
+ : PreferenceValueParsersym.Char_AfterASCII);
+ }
+ public String[] orderedExportedSymbols() { return PreferenceValueParsersym.orderedTerminalSymbols; }
+ };
+
+ private MyLexStream lexStream = new MyLexStream();
+
+ private static ParseTable prs = new PreferenceValueParserprs();
+ private DeterministicParser dtParser;
+
+ private void setResult(Object object) { dtParser.setSym1(object); }
+ public DeterministicParser getParser() { return dtParser; }
+
+ public Object getRhsSym(int i) { return dtParser.getSym(i); }
+
+ public int getRhsTokenIndex(int i) { return dtParser.getToken(i); }
+ public int getRhsFirstTokenIndex(int i) { return dtParser.getFirstToken(i); }
+ public int getRhsLastTokenIndex(int i) { return dtParser.getLastToken(i); }
+
+public IToken getLeftIToken() { return new MyToken(dtParser.getFirstToken(), lexStream); }
+public IToken getRightIToken() { return new MyToken(dtParser.getLastToken(), lexStream); }
+
+public IToken getRhsIToken(int idx) { return new MyToken(dtParser.getToken(idx), lexStream); }
+
+ public int getLeftSpan() { return dtParser.getFirstToken(); }
+ public int getRightSpan() { return dtParser.getLastToken(); }
+
+ public int getEOFTokenKind() { return PreferenceValueParserprs.EOFT_SYMBOL; }
+ public LpgLexStream getLexStream() { return lexStream; }
+
+ private String errorMsg= "";
+
+ public String getErrorMessage() { return errorMsg; }
+
+ public ASTNode parser(String input) {
+ try {
+ lexStream.initialize(input.toCharArray());
+ dtParser = new DeterministicParser(lexStream, prs, this);
+ } catch (NotDeterministicParseTableException e) {
+ System.out.println("****Error: Regenerate PreferenceValueParserprs.java with -NOBACKTRACK option");
+ return null;
+ } catch (BadParseSymFileException e) {
+ System.out.println("****Error: Bad Parser Symbol File -- PreferenceValueParsersym.java. Regenerate PreferenceValueParserprs.java");
+ return null;
+ }
+
+ try {
+ return (ASTNode) dtParser.parse();
+ } catch (BadParseException e) {
+ errorMsg= "unexpected";
+ if (e.error_token < lexStream.getStreamLength())
+ errorMsg += " character '" + lexStream.getCharValue(e.error_token) + "' at offset " + e.error_token;
+ else
+ errorMsg += " end of string";
+ }
+ return null;
+ }
+
+private class MyToken implements IToken {
+ private int offset;
+ private LpgLexStream lexStream;
+ public MyToken(int offset, LpgLexStream ls) {
+ this.offset= offset;
+ this.lexStream= ls;
+ }
+ public int getKind() { return lexStream.getKind(lexStream.getInputChars()[offset]); }
+ public void setKind(int kind) { }
+
+ public int getStartOffset() { return offset; }
+ public void setStartOffset(int startOffset) { }
+
+ public int getEndOffset() { return offset; }
+ public void setEndOffset(int endOffset) { }
+
+ public int getTokenIndex() { return offset; }
+ public void setTokenIndex(int i) { }
+
+ public int getAdjunctIndex() { return -1; }
+ public void setAdjunctIndex(int i) { }
+
+ public IToken[] getPrecedingAdjuncts() { return null; }
+ public IToken[] getFollowingAdjuncts() { return null; }
+
+ public IPrsStream getIPrsStream() { return null; }
+ public LpgLexStream getILexStream() { return lexStream; }
+ public IPrsStream getPrsStream() { return null; }
+ public LpgLexStream getLexStream() { return lexStream; }
+
+ public int getLine() { return lexStream.getLine(offset); }
+ public int getColumn() { return lexStream.getColumn(offset); }
+ public int getEndLine() { return lexStream.getLine(offset); }
+ public int getEndColumn() { return lexStream.getColumn(offset); }
+
+ public String getValue(char[] inputChars) { return toString(); }
+
+ public String toString() {
+ return new String(new char[] { lexStream.getInputChars()[offset] });
+ }
+}
+ static public abstract class ASTNode implements IAst
+ {
+ public IAst getNextAst() { return null; }
+ protected IToken leftIToken,
+ rightIToken;
+ protected IAst parent = null;
+ protected void setParent(IAst parent) { this.parent = parent; }
+ public IAst getParent() { return parent; }
+
+ public IToken getLeftIToken() { return leftIToken; }
+ public IToken getRightIToken() { return rightIToken; }
+ public IToken[] getPrecedingAdjuncts() { return leftIToken.getPrecedingAdjuncts(); }
+ public IToken[] getFollowingAdjuncts() { return rightIToken.getFollowingAdjuncts(); }
+
+ public String toString()
+ {
+ return leftIToken.getLexStream().toString(leftIToken.getStartOffset(), rightIToken.getEndOffset());
+ }
+
+ public ASTNode(IToken token) { this.leftIToken = this.rightIToken = token; }
+ public ASTNode(IToken leftIToken, IToken rightIToken)
+ {
+ this.leftIToken = leftIToken;
+ this.rightIToken = rightIToken;
+ }
+
+ void initialize() {}
+
+ /**
+ * A list of all children of this node, excluding the null ones.
+ */
+ public java.util.ArrayList getChildren()
+ {
+ java.util.ArrayList list = getAllChildren();
+ int k = -1;
+ for (int i = 0; i < list.size(); i++)
+ {
+ Object element = list.get(i);
+ if (element != null)
+ {
+ if (++k != i)
+ list.set(k, element);
+ }
+ }
+ for (int i = list.size() - 1; i > k; i--) // remove extraneous elements
+ list.remove(i);
+ return list;
+ }
+
+ /**
+ * A list of all children of this node, including the null ones.
+ */
+ public abstract java.util.ArrayList getAllChildren();
+
+ public boolean equals(Object o)
+ {
+ if (o == this) return true;
+ if (! (o instanceof ASTNode)) return false;
+ ASTNode other = (ASTNode) o;
+ return getLeftIToken().getLexStream() == other.getLeftIToken().getLexStream() &&
+ getLeftIToken().getTokenIndex() == other.getLeftIToken().getTokenIndex() &&
+ getRightIToken().getLexStream() == other.getRightIToken().getLexStream() &&
+ getRightIToken().getTokenIndex() == other.getRightIToken().getTokenIndex();
+ }
+
+ public int hashCode()
+ {
+ int hash = 7;
+ if (getLeftIToken().getLexStream() != null) hash = hash * 31 + getLeftIToken().getLexStream().hashCode();
+ hash = hash * 31 + getLeftIToken().getTokenIndex();
+ if (getRightIToken().getLexStream() != null) hash = hash * 31 + getRightIToken().getLexStream().hashCode();
+ hash = hash * 31 + getRightIToken().getTokenIndex();
+ return hash;
+ }
+ public abstract void accept(IAstVisitor v);
+ }
+
+ static public abstract class AbstractASTNodeList extends ASTNode
+ {
+ private boolean leftRecursive;
+ private java.util.ArrayList list;
+ public int size() { return list.size(); }
+ public ASTNode getElementAt(int i) { return (ASTNode) list.get(leftRecursive ? i : list.size() - 1 - i); }
+ public java.util.ArrayList getArrayList()
+ {
+ if (! leftRecursive) // reverse the list
+ {
+ for (int i = 0, n = list.size() - 1; i < n; i++, n--)
+ {
+ Object ith = list.get(i),
+ nth = list.get(n);
+ list.set(i, nth);
+ list.set(n, ith);
+ }
+ leftRecursive = true;
+ }
+ return list;
+ }
+ public void add(ASTNode element)
+ {
+ list.add(element);
+ if (leftRecursive)
+ rightIToken = element.getRightIToken();
+ else leftIToken = element.getLeftIToken();
+ }
+
+ public AbstractASTNodeList(IToken leftIToken, IToken rightIToken, boolean leftRecursive)
+ {
+ super(leftIToken, rightIToken);
+ this.leftRecursive = leftRecursive;
+ list = new java.util.ArrayList();
+ }
+
+ public AbstractASTNodeList(ASTNode element, boolean leftRecursive)
+ {
+ this(element.getLeftIToken(), element.getRightIToken(), leftRecursive);
+ list.add(element);
+ }
+
+ /**
+ * Make a copy of the list and return it. Note that we obtain the local list by
+ * invoking getArrayList so as to make sure that the list we return is in proper order.
+ */
+ public java.util.ArrayList getAllChildren()
+ {
+ return (java.util.ArrayList) getArrayList().clone();
+ }
+
+ }
+
+ static public class ASTNodeToken extends ASTNode implements IASTNodeToken
+ {
+ public ASTNodeToken(IToken token) { super(token); }
+ public IToken getIToken() { return leftIToken; }
+ public String toString() { return leftIToken.toString(); }
+
+ /**
+ * A token class has no children. So, we return the empty list.
+ */
+ public java.util.ArrayList getAllChildren() { return new java.util.ArrayList(); }
+
+ public boolean equals(Object o)
+ {
+ if (o == this) return true;
+ if (! (o instanceof ASTNodeToken)) return false;
+ ASTNodeToken other = (ASTNodeToken) o;
+ return getIToken().getLexStream() == other.getIToken().getLexStream() &&
+ getIToken().getTokenIndex() == other.getIToken().getTokenIndex();
+ }
+
+ public int hashCode()
+ {
+ int hash = 7;
+ if (getIToken().getLexStream() != null) hash = hash * 31 + getIToken().getLexStream().hashCode();
+ hash = hash * 31 + getIToken().getTokenIndex();
+ return hash;
+ }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *<li>specialNoDollarRBrace0
+ *<li>specialNoDollarRBrace1
+ *<li>specialNoDollarRBrace2
+ *<li>specialNoDollarRBrace3
+ *<li>specialNoDollarRBrace4
+ *<li>specialNoDollarRBrace5
+ *<li>specialNoDollarRBrace6
+ *<li>specialNoDollarRBrace7
+ *<li>specialNoDollarRBrace8
+ *<li>specialNoDollarRBrace9
+ *<li>specialNoDollarRBrace10
+ *<li>specialNoDollarRBrace11
+ *<li>specialNoDollarRBrace12
+ *<li>specialNoDollarRBrace13
+ *<li>specialNoDollarRBrace14
+ *<li>specialNoDollarRBrace15
+ *<li>specialNoDollarRBrace16
+ *<li>specialNoDollarRBrace17
+ *<li>specialNoDollarRBrace18
+ *<li>specialNoDollarRBrace19
+ *<li>specialNoDollarRBrace20
+ *<li>specialNoDollarRBrace21
+ *<li>specialNoDollarRBrace22
+ *<li>specialNoDollarRBrace23
+ *<li>specialNoDollarRBrace24
+ *<li>specialNoDollarRBrace25
+ *<li>specialNoDollarRBrace26
+ *<li>specialNoDollarRBrace27
+ *<li>specialNoDollarRBrace28
+ *<li>specialNoDollarRBrace29
+ *<li>special0
+ *<li>special1
+ *<li>special2
+ *<li>special3
+ *<li>special4
+ *<li>special5
+ *<li>special6
+ *<li>special7
+ *<li>special8
+ *<li>special9
+ *<li>special10
+ *<li>special11
+ *<li>special12
+ *<li>special13
+ *<li>special14
+ *<li>special15
+ *<li>special16
+ *<li>special17
+ *<li>special18
+ *<li>special19
+ *<li>special20
+ *<li>special21
+ *<li>special22
+ *<li>special23
+ *<li>special24
+ *<li>special25
+ *<li>special26
+ *<li>special27
+ *<li>special28
+ *<li>special29
+ *<li>special30
+ *<li>special31
+ *<li>special32
+ *</ul>
+ *</b>
+ */
+ public interface IASTNodeToken
+ {
+ public IToken getLeftIToken();
+ public IToken getRightIToken();
+
+ void accept(IAstVisitor v);
+ }
+
+ /**
+ * is implemented by:
+ *<b>
+ *<ul>
+ *<li>simpleStringPrefixed
+ *<li>valStringNoSubst
+ *<li>substPrefixed
+ *<li>substitutionList
+ *<li>escapedChar
+ *<li>specialNoDollarRBrace0
+ *<li>specialNoDollarRBrace1
+ *<li>specialNoDollarRBrace2
+ *<li>specialNoDollarRBrace3
+ *<li>specialNoDollarRBrace4
+ *<li>specialNoDollarRBrace5
+ *<li>specialNoDollarRBrace6
+ *<li>specialNoDollarRBrace7
+ *<li>specialNoDollarRBrace8
+ *<li>specialNoDollarRBrace9
+ *<li>specialNoDollarRBrace10
+ *<li>specialNoDollarRBrace11
+ *<li>specialNoDollarRBrace12
+ *<li>specialNoDollarRBrace13
+ *<li>specialNoDollarRBrace14
+ *<li>specialNoDollarRBrace15
+ *<li>specialNoDollarRBrace16
+ *<li>specialNoDollarRBrace17
+ *<li>specialNoDollarRBrace18
+ *<li>specialNoDollarRBrace19
+ *<li>specialNoDollarRBrace20
+ *<li>specialNoDollarRBrace21
+ *<li>specialNoDollarRBrace22
+ *<li>specialNoDollarRBrace23
+ *<li>specialNoDollarRBrace24
+ *<li>specialNoDollarRBrace25
+ *<li>specialNoDollarRBrace26
+ *<li>specialNoDollarRBrace27
+ *<li>specialNoDollarRBrace28
+ *<li>specialNoDollarRBrace29
+ *</ul>
+ *</b>
+ */
+ public interface Ivalue
+ {
+ public IToken getLeftIToken();
+ public IToken getRightIToken();
+
+ void accept(IAstVisitor v);
+ }
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface Idigit extends IASTNodeToken, InonSubstStart, IescapableChar {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IaA extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IbB extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IcC extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IdD extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IeE extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IfF extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IgG extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IhH extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IiI extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IjJ extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IkK extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IlL extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface ImM extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface InN extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IoO extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IpP extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IqQ extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IrR extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IsS extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface ItT extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IuU extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IvV extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IwW extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IxX extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IyY extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IzZ extends IASTNodeToken, Iletter {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface Iletter extends IidentChars, InonSubstStart, IescapableChar {}
+
+ /**
+ * is implemented by:
+ *<b>
+ *<ul>
+ *<li>simpleStringPrefixed
+ *<li>valStringNoSubst
+ *<li>escapedChar
+ *<li>specialNoDollarRBrace0
+ *<li>specialNoDollarRBrace1
+ *<li>specialNoDollarRBrace2
+ *<li>specialNoDollarRBrace3
+ *<li>specialNoDollarRBrace4
+ *<li>specialNoDollarRBrace5
+ *<li>specialNoDollarRBrace6
+ *<li>specialNoDollarRBrace7
+ *<li>specialNoDollarRBrace8
+ *<li>specialNoDollarRBrace9
+ *<li>specialNoDollarRBrace10
+ *<li>specialNoDollarRBrace11
+ *<li>specialNoDollarRBrace12
+ *<li>specialNoDollarRBrace13
+ *<li>specialNoDollarRBrace14
+ *<li>specialNoDollarRBrace15
+ *<li>specialNoDollarRBrace16
+ *<li>specialNoDollarRBrace17
+ *<li>specialNoDollarRBrace18
+ *<li>specialNoDollarRBrace19
+ *<li>specialNoDollarRBrace20
+ *<li>specialNoDollarRBrace21
+ *<li>specialNoDollarRBrace22
+ *<li>specialNoDollarRBrace23
+ *<li>specialNoDollarRBrace24
+ *<li>specialNoDollarRBrace25
+ *<li>specialNoDollarRBrace26
+ *<li>specialNoDollarRBrace27
+ *<li>specialNoDollarRBrace28
+ *<li>specialNoDollarRBrace29
+ *</ul>
+ *</b>
+ */
+ public interface IsimpleStringPrefixed extends Ivalue {}
+
+ /**
+ * is implemented by:
+ *<b>
+ *<ul>
+ *<li>substPrefixed
+ *<li>substitutionList
+ *</ul>
+ *</b>
+ */
+ public interface IsubstPrefixed extends Ivalue {}
+
+ /**
+ * is implemented by:
+ *<b>
+ *<ul>
+ *<li>valStringNoSubst
+ *<li>escapedChar
+ *<li>specialNoDollarRBrace0
+ *<li>specialNoDollarRBrace1
+ *<li>specialNoDollarRBrace2
+ *<li>specialNoDollarRBrace3
+ *<li>specialNoDollarRBrace4
+ *<li>specialNoDollarRBrace5
+ *<li>specialNoDollarRBrace6
+ *<li>specialNoDollarRBrace7
+ *<li>specialNoDollarRBrace8
+ *<li>specialNoDollarRBrace9
+ *<li>specialNoDollarRBrace10
+ *<li>specialNoDollarRBrace11
+ *<li>specialNoDollarRBrace12
+ *<li>specialNoDollarRBrace13
+ *<li>specialNoDollarRBrace14
+ *<li>specialNoDollarRBrace15
+ *<li>specialNoDollarRBrace16
+ *<li>specialNoDollarRBrace17
+ *<li>specialNoDollarRBrace18
+ *<li>specialNoDollarRBrace19
+ *<li>specialNoDollarRBrace20
+ *<li>specialNoDollarRBrace21
+ *<li>specialNoDollarRBrace22
+ *<li>specialNoDollarRBrace23
+ *<li>specialNoDollarRBrace24
+ *<li>specialNoDollarRBrace25
+ *<li>specialNoDollarRBrace26
+ *<li>specialNoDollarRBrace27
+ *<li>specialNoDollarRBrace28
+ *<li>specialNoDollarRBrace29
+ *</ul>
+ *</b>
+ */
+ public interface IvalStringNoSubst extends IsimpleStringPrefixed {}
+
+ /**
+ * is implemented by:
+ *<b>
+ *<ul>
+ *<li>escapedChar
+ *<li>specialNoDollarRBrace0
+ *<li>specialNoDollarRBrace1
+ *<li>specialNoDollarRBrace2
+ *<li>specialNoDollarRBrace3
+ *<li>specialNoDollarRBrace4
+ *<li>specialNoDollarRBrace5
+ *<li>specialNoDollarRBrace6
+ *<li>specialNoDollarRBrace7
+ *<li>specialNoDollarRBrace8
+ *<li>specialNoDollarRBrace9
+ *<li>specialNoDollarRBrace10
+ *<li>specialNoDollarRBrace11
+ *<li>specialNoDollarRBrace12
+ *<li>specialNoDollarRBrace13
+ *<li>specialNoDollarRBrace14
+ *<li>specialNoDollarRBrace15
+ *<li>specialNoDollarRBrace16
+ *<li>specialNoDollarRBrace17
+ *<li>specialNoDollarRBrace18
+ *<li>specialNoDollarRBrace19
+ *<li>specialNoDollarRBrace20
+ *<li>specialNoDollarRBrace21
+ *<li>specialNoDollarRBrace22
+ *<li>specialNoDollarRBrace23
+ *<li>specialNoDollarRBrace24
+ *<li>specialNoDollarRBrace25
+ *<li>specialNoDollarRBrace26
+ *<li>specialNoDollarRBrace27
+ *<li>specialNoDollarRBrace28
+ *<li>specialNoDollarRBrace29
+ *</ul>
+ *</b>
+ */
+ public interface IvalueStringNoSubst extends IvalStringNoSubst {}
+
+ /**
+ * is implemented by <b>substitutionList</b>
+ */
+ public interface IsubstitutionList extends IsubstPrefixed {}
+
+ /**
+ * is implemented by <b>substitution</b>
+ */
+ public interface Isubstitution
+ {
+ public IToken getLeftIToken();
+ public IToken getRightIToken();
+
+ void accept(IAstVisitor v);
+ }
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *<li>specialNoDollarRBrace0
+ *<li>specialNoDollarRBrace1
+ *<li>specialNoDollarRBrace2
+ *<li>specialNoDollarRBrace3
+ *<li>specialNoDollarRBrace4
+ *<li>specialNoDollarRBrace5
+ *<li>specialNoDollarRBrace6
+ *<li>specialNoDollarRBrace7
+ *<li>specialNoDollarRBrace8
+ *<li>specialNoDollarRBrace9
+ *<li>specialNoDollarRBrace10
+ *<li>specialNoDollarRBrace11
+ *<li>specialNoDollarRBrace12
+ *<li>specialNoDollarRBrace13
+ *<li>specialNoDollarRBrace14
+ *<li>specialNoDollarRBrace15
+ *<li>specialNoDollarRBrace16
+ *<li>specialNoDollarRBrace17
+ *<li>specialNoDollarRBrace18
+ *<li>specialNoDollarRBrace19
+ *<li>specialNoDollarRBrace20
+ *<li>specialNoDollarRBrace21
+ *<li>specialNoDollarRBrace22
+ *<li>specialNoDollarRBrace23
+ *<li>specialNoDollarRBrace24
+ *<li>specialNoDollarRBrace25
+ *<li>specialNoDollarRBrace26
+ *<li>specialNoDollarRBrace27
+ *<li>specialNoDollarRBrace28
+ *<li>specialNoDollarRBrace29
+ *</ul>
+ *</b>
+ */
+ public interface InonSubstStart extends IvalueStringNoSubst {}
+
+ /**
+ * is implemented by <b>escapedChar</b>
+ */
+ public interface IescapedChar extends IvalueStringNoSubst {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *<li>specialNoDollarRBrace0
+ *<li>specialNoDollarRBrace1
+ *<li>specialNoDollarRBrace2
+ *<li>specialNoDollarRBrace3
+ *<li>specialNoDollarRBrace4
+ *<li>specialNoDollarRBrace5
+ *<li>specialNoDollarRBrace6
+ *<li>specialNoDollarRBrace7
+ *<li>specialNoDollarRBrace8
+ *<li>specialNoDollarRBrace9
+ *<li>specialNoDollarRBrace10
+ *<li>specialNoDollarRBrace11
+ *<li>specialNoDollarRBrace12
+ *<li>specialNoDollarRBrace13
+ *<li>specialNoDollarRBrace14
+ *<li>specialNoDollarRBrace15
+ *<li>specialNoDollarRBrace16
+ *<li>specialNoDollarRBrace17
+ *<li>specialNoDollarRBrace18
+ *<li>specialNoDollarRBrace19
+ *<li>specialNoDollarRBrace20
+ *<li>specialNoDollarRBrace21
+ *<li>specialNoDollarRBrace22
+ *<li>specialNoDollarRBrace23
+ *<li>specialNoDollarRBrace24
+ *<li>specialNoDollarRBrace25
+ *<li>specialNoDollarRBrace26
+ *<li>specialNoDollarRBrace27
+ *<li>specialNoDollarRBrace28
+ *<li>specialNoDollarRBrace29
+ *</ul>
+ *</b>
+ */
+ public interface IspecialNoDollarRBrace extends InonSubstStart, IASTNodeToken {}
+
+ /**
+ * is implemented by <b>ident</b>
+ */
+ public interface Iident
+ {
+ public IToken getLeftIToken();
+ public IToken getRightIToken();
+
+ void accept(IAstVisitor v);
+ }
+
+ /**
+ * is implemented by <b>optParameter</b>
+ */
+ public interface IoptParameter
+ {
+ public IToken getLeftIToken();
+ public IToken getRightIToken();
+
+ void accept(IAstVisitor v);
+ }
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *</ul>
+ *</b>
+ */
+ public interface IidentChars extends Iident {}
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *<li>special0
+ *<li>special1
+ *<li>special2
+ *<li>special3
+ *<li>special4
+ *<li>special5
+ *<li>special6
+ *<li>special7
+ *<li>special8
+ *<li>special9
+ *<li>special10
+ *<li>special11
+ *<li>special12
+ *<li>special13
+ *<li>special14
+ *<li>special15
+ *<li>special16
+ *<li>special17
+ *<li>special18
+ *<li>special19
+ *<li>special20
+ *<li>special21
+ *<li>special22
+ *<li>special23
+ *<li>special24
+ *<li>special25
+ *<li>special26
+ *<li>special27
+ *<li>special28
+ *<li>special29
+ *<li>special30
+ *<li>special31
+ *<li>special32
+ *</ul>
+ *</b>
+ */
+ public interface IescapableChar
+ {
+ public IToken getLeftIToken();
+ public IToken getRightIToken();
+
+ void accept(IAstVisitor v);
+ }
+
+ /**
+ * is always implemented by <b>ASTNodeToken</b>. It is also implemented by:
+ *<b>
+ *<ul>
+ *<li>special0
+ *<li>special1
+ *<li>special2
+ *<li>special3
+ *<li>special4
+ *<li>special5
+ *<li>special6
+ *<li>special7
+ *<li>special8
+ *<li>special9
+ *<li>special10
+ *<li>special11
+ *<li>special12
+ *<li>special13
+ *<li>special14
+ *<li>special15
+ *<li>special16
+ *<li>special17
+ *<li>special18
+ *<li>special19
+ *<li>special20
+ *<li>special21
+ *<li>special22
+ *<li>special23
+ *<li>special24
+ *<li>special25
+ *<li>special26
+ *<li>special27
+ *<li>special28
+ *<li>special29
+ *<li>special30
+ *<li>special31
+ *<li>special32
+ *</ul>
+ *</b>
+ */
+ public interface Ispecial extends IescapableChar, IASTNodeToken {}
+
+ /**
+ *<b>
+ *<li>Rule 91: simpleStringPrefixed ::= valStringNoSubst
+ *<li>Rule 92: simpleStringPrefixed ::= valStringNoSubst substPrefixed
+ *</b>
+ */
+ static public class simpleStringPrefixed extends ASTNode implements IsimpleStringPrefixed
+ {
+ private IvalStringNoSubst _valStringNoSubst;
+ private IsubstPrefixed _substPrefixed;
+
+ /**
+ * The value returned by <b>getvalStringNoSubst</b> may be <b>null</b>
+ */
+ public IvalStringNoSubst getvalStringNoSubst() { return _valStringNoSubst; }
+ /**
+ * The value returned by <b>getsubstPrefixed</b> may be <b>null</b>
+ */
+ public IsubstPrefixed getsubstPrefixed() { return _substPrefixed; }
+
+ public simpleStringPrefixed(IToken leftIToken, IToken rightIToken,
+ IvalStringNoSubst _valStringNoSubst,
+ IsubstPrefixed _substPrefixed)
+ {
+ super(leftIToken, rightIToken);
+
+ this._valStringNoSubst = _valStringNoSubst;
+ if (_valStringNoSubst != null) ((ASTNode) _valStringNoSubst).setParent(this);
+ this._substPrefixed = _substPrefixed;
+ if (_substPrefixed != null) ((ASTNode) _substPrefixed).setParent(this);
+ initialize();
+ }
+
+ /**
+ * A list of all children of this node, including the null ones.
+ */
+ public java.util.ArrayList getAllChildren()
+ {
+ java.util.ArrayList list = new java.util.ArrayList();
+ list.add(_valStringNoSubst);
+ list.add(_substPrefixed);
+ return list;
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o == this) return true;
+ if (! (o instanceof simpleStringPrefixed)) return false;
+ if (! super.equals(o)) return false;
+ simpleStringPrefixed other = (simpleStringPrefixed) o;
+ if (_valStringNoSubst == null)
+ if (other._valStringNoSubst != null) return false;
+ else; // continue
+ else if (! _valStringNoSubst.equals(other._valStringNoSubst)) return false;
+ if (_substPrefixed == null)
+ if (other._substPrefixed != null) return false;
+ else; // continue
+ else if (! _substPrefixed.equals(other._substPrefixed)) return false;
+ return true;
+ }
+
+ public int hashCode()
+ {
+ int hash = super.hashCode();
+ hash = hash * 31 + (_valStringNoSubst == null ? 0 : _valStringNoSubst.hashCode());
+ hash = hash * 31 + (_substPrefixed == null ? 0 : _substPrefixed.hashCode());
+ return hash;
+ }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ boolean checkChildren = v.visit(this);
+ if (checkChildren)
+ {
+ if (_valStringNoSubst != null) _valStringNoSubst.accept(v);
+ if (_substPrefixed != null) _substPrefixed.accept(v);
+ }
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 93: valStringNoSubst ::= valueStringNoSubst$
+ *</b>
+ */
+ static public class valStringNoSubst extends ASTNode implements IvalStringNoSubst
+ {
+ public valStringNoSubst(IToken leftIToken, IToken rightIToken)
+ {
+ super(leftIToken, rightIToken);
+
+ initialize();
+ }
+
+ /**
+ * A list of all children of this node, including the null ones.
+ */
+ public java.util.ArrayList getAllChildren()
+ {
+ java.util.ArrayList list = new java.util.ArrayList();
+ return list;
+ }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<em>
+ *<li>Rule 94: substPrefixed ::= substitutionList
+ *</em>
+ *<p>
+ *<b>
+ *<li>Rule 95: substPrefixed ::= substitutionList simpleStringPrefixed
+ *</b>
+ */
+ static public class substPrefixed extends ASTNode implements IsubstPrefixed
+ {
+ private substitutionList _substitutionList;
+ private IsimpleStringPrefixed _simpleStringPrefixed;
+
+ public substitutionList getsubstitutionList() { return _substitutionList; }
+ /**
+ * The value returned by <b>getsimpleStringPrefixed</b> may be <b>null</b>
+ */
+ public IsimpleStringPrefixed getsimpleStringPrefixed() { return _simpleStringPrefixed; }
+
+ public substPrefixed(IToken leftIToken, IToken rightIToken,
+ substitutionList _substitutionList,
+ IsimpleStringPrefixed _simpleStringPrefixed)
+ {
+ super(leftIToken, rightIToken);
+
+ this._substitutionList = _substitutionList;
+ ((ASTNode) _substitutionList).setParent(this);
+ this._simpleStringPrefixed = _simpleStringPrefixed;
+ if (_simpleStringPrefixed != null) ((ASTNode) _simpleStringPrefixed).setParent(this);
+ initialize();
+ }
+
+ /**
+ * A list of all children of this node, including the null ones.
+ */
+ public java.util.ArrayList getAllChildren()
+ {
+ java.util.ArrayList list = new java.util.ArrayList();
+ list.add(_substitutionList);
+ list.add(_simpleStringPrefixed);
+ return list;
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o == this) return true;
+ if (! (o instanceof substPrefixed)) return false;
+ if (! super.equals(o)) return false;
+ substPrefixed other = (substPrefixed) o;
+ if (! _substitutionList.equals(other._substitutionList)) return false;
+ if (_simpleStringPrefixed == null)
+ if (other._simpleStringPrefixed != null) return false;
+ else; // continue
+ else if (! _simpleStringPrefixed.equals(other._simpleStringPrefixed)) return false;
+ return true;
+ }
+
+ public int hashCode()
+ {
+ int hash = super.hashCode();
+ hash = hash * 31 + (_substitutionList.hashCode());
+ hash = hash * 31 + (_simpleStringPrefixed == null ? 0 : _simpleStringPrefixed.hashCode());
+ return hash;
+ }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ boolean checkChildren = v.visit(this);
+ if (checkChildren)
+ {
+ _substitutionList.accept(v);
+ if (_simpleStringPrefixed != null) _simpleStringPrefixed.accept(v);
+ }
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 96: substitutionList ::= substitution
+ *<li>Rule 97: substitutionList ::= substitutionList substitution
+ *</b>
+ */
+ static public class substitutionList extends AbstractASTNodeList implements IsubstitutionList
+ {
+ public substitution getsubstitutionAt(int i) { return (substitution) getElementAt(i); }
+
+ public substitutionList(IToken leftIToken, IToken rightIToken, boolean leftRecursive)
+ {
+ super(leftIToken, rightIToken, leftRecursive);
+ }
+
+ public substitutionList(substitution _substitution, boolean leftRecursive)
+ {
+ super((ASTNode) _substitution, leftRecursive);
+ ((ASTNode) _substitution).setParent(this);
+ }
+
+ public void add(substitution _substitution)
+ {
+ super.add((ASTNode) _substitution);
+ ((ASTNode) _substitution).setParent(this);
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o == this) return true;
+ if (! (o instanceof substitutionList)) return false;
+ if (! super.equals(o)) return false;
+ substitutionList other = (substitutionList ) o;
+ if (size() != other.size()) return false;
+ for (int i = 0; i < size(); i++)
+ {
+ substitution element = getsubstitutionAt(i);
+ if (! element.equals(other.getsubstitutionAt(i))) return false;
+ }
+ return true;
+ }
+
+ public int hashCode()
+ {
+ int hash = super.hashCode();
+ for (int i = 0; i < size(); i++)
+ hash = hash * 31 + (getsubstitutionAt(i).hashCode());
+ return hash;
+ }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+ public void enter(Visitor v)
+ {
+ boolean checkChildren = v.visit(this);
+ if (checkChildren)
+ {
+ for (int i = 0; i < size(); i++)
+ {
+ substitution element = getsubstitutionAt(i);
+ if (! v.preVisit(element)) continue;
+ element.enter(v);
+ v.postVisit(element);
+ }
+ }
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 104: substitution ::= $$ {$ ident optParameter }$
+ *</b>
+ */
+ static public class substitution extends ASTNode implements Isubstitution
+ {
+ private ident _ident;
+ private optParameter _optParameter;
+
+ /**
+ * The value returned by <b>getident</b> may be <b>null</b>
+ */
+ public ident getident() { return _ident; }
+ /**
+ * The value returned by <b>getoptParameter</b> may be <b>null</b>
+ */
+ public optParameter getoptParameter() { return _optParameter; }
+
+ public substitution(IToken leftIToken, IToken rightIToken,
+ ident _ident,
+ optParameter _optParameter)
+ {
+ super(leftIToken, rightIToken);
+
+ this._ident = _ident;
+ if (_ident != null) ((ASTNode) _ident).setParent(this);
+ this._optParameter = _optParameter;
+ if (_optParameter != null) ((ASTNode) _optParameter).setParent(this);
+ initialize();
+ }
+
+ /**
+ * A list of all children of this node, including the null ones.
+ */
+ public java.util.ArrayList getAllChildren()
+ {
+ java.util.ArrayList list = new java.util.ArrayList();
+ list.add(_ident);
+ list.add(_optParameter);
+ return list;
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o == this) return true;
+ if (! (o instanceof substitution)) return false;
+ if (! super.equals(o)) return false;
+ substitution other = (substitution) o;
+ if (_ident == null)
+ if (other._ident != null) return false;
+ else; // continue
+ else if (! _ident.equals(other._ident)) return false;
+ if (_optParameter == null)
+ if (other._optParameter != null) return false;
+ else; // continue
+ else if (! _optParameter.equals(other._optParameter)) return false;
+ return true;
+ }
+
+ public int hashCode()
+ {
+ int hash = super.hashCode();
+ hash = hash * 31 + (_ident == null ? 0 : _ident.hashCode());
+ hash = hash * 31 + (_optParameter == null ? 0 : _optParameter.hashCode());
+ return hash;
+ }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ boolean checkChildren = v.visit(this);
+ if (checkChildren)
+ {
+ if (_ident != null) _ident.accept(v);
+ if (_optParameter != null) _optParameter.accept(v);
+ }
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<em>
+ *<li>Rule 105: optParameter ::= $Empty
+ *</em>
+ *<p>
+ *<b>
+ *<li>Rule 106: optParameter ::= :$ value
+ *</b>
+ */
+ static public class optParameter extends ASTNode implements IoptParameter
+ {
+ private Ivalue _value;
+
+ /**
+ * The value returned by <b>getvalue</b> may be <b>null</b>
+ */
+ public Ivalue getvalue() { return _value; }
+
+ public optParameter(IToken leftIToken, IToken rightIToken,
+ Ivalue _value)
+ {
+ super(leftIToken, rightIToken);
+
+ this._value = _value;
+ if (_value != null) ((ASTNode) _value).setParent(this);
+ initialize();
+ }
+
+ /**
+ * A list of all children of this node, including the null ones.
+ */
+ public java.util.ArrayList getAllChildren()
+ {
+ java.util.ArrayList list = new java.util.ArrayList();
+ list.add(_value);
+ return list;
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o == this) return true;
+ if (! (o instanceof optParameter)) return false;
+ if (! super.equals(o)) return false;
+ optParameter other = (optParameter) o;
+ if (_value == null)
+ if (other._value != null) return false;
+ else; // continue
+ else if (! _value.equals(other._value)) return false;
+ return true;
+ }
+
+ public int hashCode()
+ {
+ int hash = super.hashCode();
+ hash = hash * 31 + (_value == null ? 0 : _value.hashCode());
+ return hash;
+ }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ boolean checkChildren = v.visit(this);
+ if (checkChildren)
+ if (_value != null) _value.accept(v);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 107: ident ::= identChars$
+ *</b>
+ */
+ static public class ident extends ASTNode implements Iident
+ {
+ public ident(IToken leftIToken, IToken rightIToken)
+ {
+ super(leftIToken, rightIToken);
+
+ initialize();
+ }
+
+ /**
+ * A list of all children of this node, including the null ones.
+ */
+ public java.util.ArrayList getAllChildren()
+ {
+ java.util.ArrayList list = new java.util.ArrayList();
+ return list;
+ }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 114: escapedChar ::= \$ escapableChar
+ *</b>
+ */
+ static public class escapedChar extends ASTNode implements IescapedChar
+ {
+ private IescapableChar _escapableChar;
+
+ /**
+ * The value returned by <b>getescapableChar</b> may be <b>null</b>
+ */
+ public IescapableChar getescapableChar() { return _escapableChar; }
+
+ public escapedChar(IToken leftIToken, IToken rightIToken,
+ IescapableChar _escapableChar)
+ {
+ super(leftIToken, rightIToken);
+
+ this._escapableChar = _escapableChar;
+ if (_escapableChar != null) ((ASTNode) _escapableChar).setParent(this);
+ initialize();
+ }
+
+ /**
+ * A list of all children of this node, including the null ones.
+ */
+ public java.util.ArrayList getAllChildren()
+ {
+ java.util.ArrayList list = new java.util.ArrayList();
+ list.add(_escapableChar);
+ return list;
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o == this) return true;
+ if (! (o instanceof escapedChar)) return false;
+ if (! super.equals(o)) return false;
+ escapedChar other = (escapedChar) o;
+ if (_escapableChar == null)
+ if (other._escapableChar != null) return false;
+ else; // continue
+ else if (! _escapableChar.equals(other._escapableChar)) return false;
+ return true;
+ }
+
+ public int hashCode()
+ {
+ int hash = super.hashCode();
+ hash = hash * 31 + (_escapableChar == null ? 0 : _escapableChar.hashCode());
+ return hash;
+ }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ boolean checkChildren = v.visit(this);
+ if (checkChildren)
+ if (_escapableChar != null) _escapableChar.accept(v);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 118: specialNoDollarRBrace ::= +
+ *</b>
+ */
+ static public class specialNoDollarRBrace0 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getPlus() { return leftIToken; }
+
+ public specialNoDollarRBrace0(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 119: specialNoDollarRBrace ::= -
+ *</b>
+ */
+ static public class specialNoDollarRBrace1 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getMinus() { return leftIToken; }
+
+ public specialNoDollarRBrace1(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 120: specialNoDollarRBrace ::= (
+ *</b>
+ */
+ static public class specialNoDollarRBrace2 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getLeftParen() { return leftIToken; }
+
+ public specialNoDollarRBrace2(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 121: specialNoDollarRBrace ::= )
+ *</b>
+ */
+ static public class specialNoDollarRBrace3 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getRightParen() { return leftIToken; }
+
+ public specialNoDollarRBrace3(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 122: specialNoDollarRBrace ::= "
+ *</b>
+ */
+ static public class specialNoDollarRBrace4 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getDoubleQuote() { return leftIToken; }
+
+ public specialNoDollarRBrace4(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 123: specialNoDollarRBrace ::= !
+ *</b>
+ */
+ static public class specialNoDollarRBrace5 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getExclamation() { return leftIToken; }
+
+ public specialNoDollarRBrace5(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 124: specialNoDollarRBrace ::= @
+ *</b>
+ */
+ static public class specialNoDollarRBrace6 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getAtSign() { return leftIToken; }
+
+ public specialNoDollarRBrace6(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 125: specialNoDollarRBrace ::= `
+ *</b>
+ */
+ static public class specialNoDollarRBrace7 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getBackQuote() { return leftIToken; }
+
+ public specialNoDollarRBrace7(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 126: specialNoDollarRBrace ::= ~
+ *</b>
+ */
+ static public class specialNoDollarRBrace8 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getTilde() { return leftIToken; }
+
+ public specialNoDollarRBrace8(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 127: specialNoDollarRBrace ::= .
+ *</b>
+ */
+ static public class specialNoDollarRBrace9 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getDot() { return leftIToken; }
+
+ public specialNoDollarRBrace9(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 128: specialNoDollarRBrace ::= /
+ *</b>
+ */
+ static public class specialNoDollarRBrace10 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getSlash() { return leftIToken; }
+
+ public specialNoDollarRBrace10(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 129: specialNoDollarRBrace ::= %
+ *</b>
+ */
+ static public class specialNoDollarRBrace11 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getPercent() { return leftIToken; }
+
+ public specialNoDollarRBrace11(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 130: specialNoDollarRBrace ::= &
+ *</b>
+ */
+ static public class specialNoDollarRBrace12 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getAmpersand() { return leftIToken; }
+
+ public specialNoDollarRBrace12(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 131: specialNoDollarRBrace ::= ^
+ *</b>
+ */
+ static public class specialNoDollarRBrace13 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getCaret() { return leftIToken; }
+
+ public specialNoDollarRBrace13(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 132: specialNoDollarRBrace ::= :
+ *</b>
+ */
+ static public class specialNoDollarRBrace14 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getColon() { return leftIToken; }
+
+ public specialNoDollarRBrace14(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 133: specialNoDollarRBrace ::= ;
+ *</b>
+ */
+ static public class specialNoDollarRBrace15 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getSemiColon() { return leftIToken; }
+
+ public specialNoDollarRBrace15(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 134: specialNoDollarRBrace ::= '
+ *</b>
+ */
+ static public class specialNoDollarRBrace16 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getSingleQuote() { return leftIToken; }
+
+ public specialNoDollarRBrace16(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 135: specialNoDollarRBrace ::= |
+ *</b>
+ */
+ static public class specialNoDollarRBrace17 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getVerticalBar() { return leftIToken; }
+
+ public specialNoDollarRBrace17(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 136: specialNoDollarRBrace ::= {
+ *</b>
+ */
+ static public class specialNoDollarRBrace18 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getLeftBrace() { return leftIToken; }
+
+ public specialNoDollarRBrace18(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 137: specialNoDollarRBrace ::=
+ *</b>
+ */
+ static public class specialNoDollarRBrace19 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getSpace() { return leftIToken; }
+
+ public specialNoDollarRBrace19(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 138: specialNoDollarRBrace ::= [
+ *</b>
+ */
+ static public class specialNoDollarRBrace20 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getLeftBracket() { return leftIToken; }
+
+ public specialNoDollarRBrace20(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 139: specialNoDollarRBrace ::= ]
+ *</b>
+ */
+ static public class specialNoDollarRBrace21 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getRightBracket() { return leftIToken; }
+
+ public specialNoDollarRBrace21(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 140: specialNoDollarRBrace ::= ?
+ *</b>
+ */
+ static public class specialNoDollarRBrace22 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getQuestionMark() { return leftIToken; }
+
+ public specialNoDollarRBrace22(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 141: specialNoDollarRBrace ::= ,
+ *</b>
+ */
+ static public class specialNoDollarRBrace23 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getComma() { return leftIToken; }
+
+ public specialNoDollarRBrace23(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 142: specialNoDollarRBrace ::= <
+ *</b>
+ */
+ static public class specialNoDollarRBrace24 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getLessThan() { return leftIToken; }
+
+ public specialNoDollarRBrace24(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 143: specialNoDollarRBrace ::= >
+ *</b>
+ */
+ static public class specialNoDollarRBrace25 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getGreaterThan() { return leftIToken; }
+
+ public specialNoDollarRBrace25(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 144: specialNoDollarRBrace ::= =
+ *</b>
+ */
+ static public class specialNoDollarRBrace26 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getEqual() { return leftIToken; }
+
+ public specialNoDollarRBrace26(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 145: specialNoDollarRBrace ::= #
+ *</b>
+ */
+ static public class specialNoDollarRBrace27 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getSharp() { return leftIToken; }
+
+ public specialNoDollarRBrace27(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 146: specialNoDollarRBrace ::= *
+ *</b>
+ */
+ static public class specialNoDollarRBrace28 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken getStar() { return leftIToken; }
+
+ public specialNoDollarRBrace28(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 147: specialNoDollarRBrace ::= _
+ *</b>
+ */
+ static public class specialNoDollarRBrace29 extends ASTNodeToken implements IspecialNoDollarRBrace
+ {
+ public IToken get_() { return leftIToken; }
+
+ public specialNoDollarRBrace29(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 148: special ::= +
+ *</b>
+ */
+ static public class special0 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getPlus() { return leftIToken; }
+
+ public special0(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 149: special ::= -
+ *</b>
+ */
+ static public class special1 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getMinus() { return leftIToken; }
+
+ public special1(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 150: special ::= (
+ *</b>
+ */
+ static public class special2 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getLeftParen() { return leftIToken; }
+
+ public special2(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 151: special ::= )
+ *</b>
+ */
+ static public class special3 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getRightParen() { return leftIToken; }
+
+ public special3(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 152: special ::= "
+ *</b>
+ */
+ static public class special4 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getDoubleQuote() { return leftIToken; }
+
+ public special4(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 153: special ::= !
+ *</b>
+ */
+ static public class special5 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getExclamation() { return leftIToken; }
+
+ public special5(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 154: special ::= @
+ *</b>
+ */
+ static public class special6 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getAtSign() { return leftIToken; }
+
+ public special6(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 155: special ::= `
+ *</b>
+ */
+ static public class special7 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getBackQuote() { return leftIToken; }
+
+ public special7(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 156: special ::= ~
+ *</b>
+ */
+ static public class special8 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getTilde() { return leftIToken; }
+
+ public special8(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 157: special ::= .
+ *</b>
+ */
+ static public class special9 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getDot() { return leftIToken; }
+
+ public special9(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 158: special ::= /
+ *</b>
+ */
+ static public class special10 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getSlash() { return leftIToken; }
+
+ public special10(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 159: special ::= %
+ *</b>
+ */
+ static public class special11 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getPercent() { return leftIToken; }
+
+ public special11(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 160: special ::= &
+ *</b>
+ */
+ static public class special12 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getAmpersand() { return leftIToken; }
+
+ public special12(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 161: special ::= ^
+ *</b>
+ */
+ static public class special13 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getCaret() { return leftIToken; }
+
+ public special13(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 162: special ::= :
+ *</b>
+ */
+ static public class special14 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getColon() { return leftIToken; }
+
+ public special14(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 163: special ::= ;
+ *</b>
+ */
+ static public class special15 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getSemiColon() { return leftIToken; }
+
+ public special15(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 164: special ::= '
+ *</b>
+ */
+ static public class special16 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getSingleQuote() { return leftIToken; }
+
+ public special16(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 165: special ::= \
+ *</b>
+ */
+ static public class special17 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getBackSlash() { return leftIToken; }
+
+ public special17(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 166: special ::= |
+ *</b>
+ */
+ static public class special18 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getVerticalBar() { return leftIToken; }
+
+ public special18(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 167: special ::= {
+ *</b>
+ */
+ static public class special19 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getLeftBrace() { return leftIToken; }
+
+ public special19(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 168: special ::=
+ *</b>
+ */
+ static public class special20 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getSpace() { return leftIToken; }
+
+ public special20(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 169: special ::= }
+ *</b>
+ */
+ static public class special21 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getRightBrace() { return leftIToken; }
+
+ public special21(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 170: special ::= [
+ *</b>
+ */
+ static public class special22 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getLeftBracket() { return leftIToken; }
+
+ public special22(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 171: special ::= ]
+ *</b>
+ */
+ static public class special23 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getRightBracket() { return leftIToken; }
+
+ public special23(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 172: special ::= ?
+ *</b>
+ */
+ static public class special24 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getQuestionMark() { return leftIToken; }
+
+ public special24(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 173: special ::= ,
+ *</b>
+ */
+ static public class special25 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getComma() { return leftIToken; }
+
+ public special25(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 174: special ::= <
+ *</b>
+ */
+ static public class special26 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getLessThan() { return leftIToken; }
+
+ public special26(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 175: special ::= >
+ *</b>
+ */
+ static public class special27 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getGreaterThan() { return leftIToken; }
+
+ public special27(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 176: special ::= =
+ *</b>
+ */
+ static public class special28 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getEqual() { return leftIToken; }
+
+ public special28(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 177: special ::= #
+ *</b>
+ */
+ static public class special29 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getSharp() { return leftIToken; }
+
+ public special29(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 178: special ::= *
+ *</b>
+ */
+ static public class special30 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getStar() { return leftIToken; }
+
+ public special30(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 179: special ::= _
+ *</b>
+ */
+ static public class special31 extends ASTNodeToken implements Ispecial
+ {
+ public IToken get_() { return leftIToken; }
+
+ public special31(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ /**
+ *<b>
+ *<li>Rule 180: special ::= $
+ *</b>
+ */
+ static public class special32 extends ASTNodeToken implements Ispecial
+ {
+ public IToken getDollarSign() { return leftIToken; }
+
+ public special32(IToken token) { super(token); initialize(); }
+
+ public void accept(IAstVisitor v)
+ {
+ if (! v.preVisit(this)) return;
+ enter((Visitor) v);
+ v.postVisit(this);
+ }
+
+ public void enter(Visitor v)
+ {
+ v.visit(this);
+ v.endVisit(this);
+ }
+ }
+
+ public interface Visitor extends IAstVisitor
+ {
+ boolean visit(ASTNode n);
+ void endVisit(ASTNode n);
+
+ boolean visit(ASTNodeToken n);
+ void endVisit(ASTNodeToken n);
+
+ boolean visit(simpleStringPrefixed n);
+ void endVisit(simpleStringPrefixed n);
+
+ boolean visit(valStringNoSubst n);
+ void endVisit(valStringNoSubst n);
+
+ boolean visit(substPrefixed n);
+ void endVisit(substPrefixed n);
+
+ boolean visit(substitutionList n);
+ void endVisit(substitutionList n);
+
+ boolean visit(substitution n);
+ void endVisit(substitution n);
+
+ boolean visit(optParameter n);
+ void endVisit(optParameter n);
+
+ boolean visit(ident n);
+ void endVisit(ident n);
+
+ boolean visit(escapedChar n);
+ void endVisit(escapedChar n);
+
+ boolean visit(specialNoDollarRBrace0 n);
+ void endVisit(specialNoDollarRBrace0 n);
+
+ boolean visit(specialNoDollarRBrace1 n);
+ void endVisit(specialNoDollarRBrace1 n);
+
+ boolean visit(specialNoDollarRBrace2 n);
+ void endVisit(specialNoDollarRBrace2 n);
+
+ boolean visit(specialNoDollarRBrace3 n);
+ void endVisit(specialNoDollarRBrace3 n);
+
+ boolean visit(specialNoDollarRBrace4 n);
+ void endVisit(specialNoDollarRBrace4 n);
+
+ boolean visit(specialNoDollarRBrace5 n);
+ void endVisit(specialNoDollarRBrace5 n);
+
+ boolean visit(specialNoDollarRBrace6 n);
+ void endVisit(specialNoDollarRBrace6 n);
+
+ boolean visit(specialNoDollarRBrace7 n);
+ void endVisit(specialNoDollarRBrace7 n);
+
+ boolean visit(specialNoDollarRBrace8 n);
+ void endVisit(specialNoDollarRBrace8 n);
+
+ boolean visit(specialNoDollarRBrace9 n);
+ void endVisit(specialNoDollarRBrace9 n);
+
+ boolean visit(specialNoDollarRBrace10 n);
+ void endVisit(specialNoDollarRBrace10 n);
+
+ boolean visit(specialNoDollarRBrace11 n);
+ void endVisit(specialNoDollarRBrace11 n);
+
+ boolean visit(specialNoDollarRBrace12 n);
+ void endVisit(specialNoDollarRBrace12 n);
+
+ boolean visit(specialNoDollarRBrace13 n);
+ void endVisit(specialNoDollarRBrace13 n);
+
+ boolean visit(specialNoDollarRBrace14 n);
+ void endVisit(specialNoDollarRBrace14 n);
+
+ boolean visit(specialNoDollarRBrace15 n);
+ void endVisit(specialNoDollarRBrace15 n);
+
+ boolean visit(specialNoDollarRBrace16 n);
+ void endVisit(specialNoDollarRBrace16 n);
+
+ boolean visit(specialNoDollarRBrace17 n);
+ void endVisit(specialNoDollarRBrace17 n);
+
+ boolean visit(specialNoDollarRBrace18 n);
+ void endVisit(specialNoDollarRBrace18 n);
+
+ boolean visit(specialNoDollarRBrace19 n);
+ void endVisit(specialNoDollarRBrace19 n);
+
+ boolean visit(specialNoDollarRBrace20 n);
+ void endVisit(specialNoDollarRBrace20 n);
+
+ boolean visit(specialNoDollarRBrace21 n);
+ void endVisit(specialNoDollarRBrace21 n);
+
+ boolean visit(specialNoDollarRBrace22 n);
+ void endVisit(specialNoDollarRBrace22 n);
+
+ boolean visit(specialNoDollarRBrace23 n);
+ void endVisit(specialNoDollarRBrace23 n);
+
+ boolean visit(specialNoDollarRBrace24 n);
+ void endVisit(specialNoDollarRBrace24 n);
+
+ boolean visit(specialNoDollarRBrace25 n);
+ void endVisit(specialNoDollarRBrace25 n);
+
+ boolean visit(specialNoDollarRBrace26 n);
+ void endVisit(specialNoDollarRBrace26 n);
+
+ boolean visit(specialNoDollarRBrace27 n);
+ void endVisit(specialNoDollarRBrace27 n);
+
+ boolean visit(specialNoDollarRBrace28 n);
+ void endVisit(specialNoDollarRBrace28 n);
+
+ boolean visit(specialNoDollarRBrace29 n);
+ void endVisit(specialNoDollarRBrace29 n);
+
+ boolean visit(special0 n);
+ void endVisit(special0 n);
+
+ boolean visit(special1 n);
+ void endVisit(special1 n);
+
+ boolean visit(special2 n);
+ void endVisit(special2 n);
+
+ boolean visit(special3 n);
+ void endVisit(special3 n);
+
+ boolean visit(special4 n);
+ void endVisit(special4 n);
+
+ boolean visit(special5 n);
+ void endVisit(special5 n);
+
+ boolean visit(special6 n);
+ void endVisit(special6 n);
+
+ boolean visit(special7 n);
+ void endVisit(special7 n);
+
+ boolean visit(special8 n);
+ void endVisit(special8 n);
+
+ boolean visit(special9 n);
+ void endVisit(special9 n);
+
+ boolean visit(special10 n);
+ void endVisit(special10 n);
+
+ boolean visit(special11 n);
+ void endVisit(special11 n);
+
+ boolean visit(special12 n);
+ void endVisit(special12 n);
+
+ boolean visit(special13 n);
+ void endVisit(special13 n);
+
+ boolean visit(special14 n);
+ void endVisit(special14 n);
+
+ boolean visit(special15 n);
+ void endVisit(special15 n);
+
+ boolean visit(special16 n);
+ void endVisit(special16 n);
+
+ boolean visit(special17 n);
+ void endVisit(special17 n);
+
+ boolean visit(special18 n);
+ void endVisit(special18 n);
+
+ boolean visit(special19 n);
+ void endVisit(special19 n);
+
+ boolean visit(special20 n);
+ void endVisit(special20 n);
+
+ boolean visit(special21 n);
+ void endVisit(special21 n);
+
+ boolean visit(special22 n);
+ void endVisit(special22 n);
+
+ boolean visit(special23 n);
+ void endVisit(special23 n);
+
+ boolean visit(special24 n);
+ void endVisit(special24 n);
+
+ boolean visit(special25 n);
+ void endVisit(special25 n);
+
+ boolean visit(special26 n);
+ void endVisit(special26 n);
+
+ boolean visit(special27 n);
+ void endVisit(special27 n);
+
+ boolean visit(special28 n);
+ void endVisit(special28 n);
+
+ boolean visit(special29 n);
+ void endVisit(special29 n);
+
+ boolean visit(special30 n);
+ void endVisit(special30 n);
+
+ boolean visit(special31 n);
+ void endVisit(special31 n);
+
+ boolean visit(special32 n);
+ void endVisit(special32 n);
+
+ }
+
+ static public abstract class AbstractVisitor implements Visitor
+ {
+ public abstract void unimplementedVisitor(String s);
+
+ public boolean preVisit(IAst element) { return true; }
+
+ public void postVisit(IAst element) {}
+
+ public boolean visit(ASTNodeToken n) { unimplementedVisitor("visit(ASTNodeToken)"); return true; }
+ public void endVisit(ASTNodeToken n) { unimplementedVisitor("endVisit(ASTNodeToken)"); }
+
+ public boolean visit(simpleStringPrefixed n) { unimplementedVisitor("visit(simpleStringPrefixed)"); return true; }
+ public void endVisit(simpleStringPrefixed n) { unimplementedVisitor("endVisit(simpleStringPrefixed)"); }
+
+ public boolean visit(valStringNoSubst n) { unimplementedVisitor("visit(valStringNoSubst)"); return true; }
+ public void endVisit(valStringNoSubst n) { unimplementedVisitor("endVisit(valStringNoSubst)"); }
+
+ public boolean visit(substPrefixed n) { unimplementedVisitor("visit(substPrefixed)"); return true; }
+ public void endVisit(substPrefixed n) { unimplementedVisitor("endVisit(substPrefixed)"); }
+
+ public boolean visit(substitutionList n) { unimplementedVisitor("visit(substitutionList)"); return true; }
+ public void endVisit(substitutionList n) { unimplementedVisitor("endVisit(substitutionList)"); }
+
+ public boolean visit(substitution n) { unimplementedVisitor("visit(substitution)"); return true; }
+ public void endVisit(substitution n) { unimplementedVisitor("endVisit(substitution)"); }
+
+ public boolean visit(optParameter n) { unimplementedVisitor("visit(optParameter)"); return true; }
+ public void endVisit(optParameter n) { unimplementedVisitor("endVisit(optParameter)"); }
+
+ public boolean visit(ident n) { unimplementedVisitor("visit(ident)"); return true; }
+ public void endVisit(ident n) { unimplementedVisitor("endVisit(ident)"); }
+
+ public boolean visit(escapedChar n) { unimplementedVisitor("visit(escapedChar)"); return true; }
+ public void endVisit(escapedChar n) { unimplementedVisitor("endVisit(escapedChar)"); }
+
+ public boolean visit(specialNoDollarRBrace0 n) { unimplementedVisitor("visit(specialNoDollarRBrace0)"); return true; }
+ public void endVisit(specialNoDollarRBrace0 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace0)"); }
+
+ public boolean visit(specialNoDollarRBrace1 n) { unimplementedVisitor("visit(specialNoDollarRBrace1)"); return true; }
+ public void endVisit(specialNoDollarRBrace1 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace1)"); }
+
+ public boolean visit(specialNoDollarRBrace2 n) { unimplementedVisitor("visit(specialNoDollarRBrace2)"); return true; }
+ public void endVisit(specialNoDollarRBrace2 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace2)"); }
+
+ public boolean visit(specialNoDollarRBrace3 n) { unimplementedVisitor("visit(specialNoDollarRBrace3)"); return true; }
+ public void endVisit(specialNoDollarRBrace3 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace3)"); }
+
+ public boolean visit(specialNoDollarRBrace4 n) { unimplementedVisitor("visit(specialNoDollarRBrace4)"); return true; }
+ public void endVisit(specialNoDollarRBrace4 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace4)"); }
+
+ public boolean visit(specialNoDollarRBrace5 n) { unimplementedVisitor("visit(specialNoDollarRBrace5)"); return true; }
+ public void endVisit(specialNoDollarRBrace5 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace5)"); }
+
+ public boolean visit(specialNoDollarRBrace6 n) { unimplementedVisitor("visit(specialNoDollarRBrace6)"); return true; }
+ public void endVisit(specialNoDollarRBrace6 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace6)"); }
+
+ public boolean visit(specialNoDollarRBrace7 n) { unimplementedVisitor("visit(specialNoDollarRBrace7)"); return true; }
+ public void endVisit(specialNoDollarRBrace7 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace7)"); }
+
+ public boolean visit(specialNoDollarRBrace8 n) { unimplementedVisitor("visit(specialNoDollarRBrace8)"); return true; }
+ public void endVisit(specialNoDollarRBrace8 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace8)"); }
+
+ public boolean visit(specialNoDollarRBrace9 n) { unimplementedVisitor("visit(specialNoDollarRBrace9)"); return true; }
+ public void endVisit(specialNoDollarRBrace9 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace9)"); }
+
+ public boolean visit(specialNoDollarRBrace10 n) { unimplementedVisitor("visit(specialNoDollarRBrace10)"); return true; }
+ public void endVisit(specialNoDollarRBrace10 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace10)"); }
+
+ public boolean visit(specialNoDollarRBrace11 n) { unimplementedVisitor("visit(specialNoDollarRBrace11)"); return true; }
+ public void endVisit(specialNoDollarRBrace11 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace11)"); }
+
+ public boolean visit(specialNoDollarRBrace12 n) { unimplementedVisitor("visit(specialNoDollarRBrace12)"); return true; }
+ public void endVisit(specialNoDollarRBrace12 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace12)"); }
+
+ public boolean visit(specialNoDollarRBrace13 n) { unimplementedVisitor("visit(specialNoDollarRBrace13)"); return true; }
+ public void endVisit(specialNoDollarRBrace13 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace13)"); }
+
+ public boolean visit(specialNoDollarRBrace14 n) { unimplementedVisitor("visit(specialNoDollarRBrace14)"); return true; }
+ public void endVisit(specialNoDollarRBrace14 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace14)"); }
+
+ public boolean visit(specialNoDollarRBrace15 n) { unimplementedVisitor("visit(specialNoDollarRBrace15)"); return true; }
+ public void endVisit(specialNoDollarRBrace15 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace15)"); }
+
+ public boolean visit(specialNoDollarRBrace16 n) { unimplementedVisitor("visit(specialNoDollarRBrace16)"); return true; }
+ public void endVisit(specialNoDollarRBrace16 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace16)"); }
+
+ public boolean visit(specialNoDollarRBrace17 n) { unimplementedVisitor("visit(specialNoDollarRBrace17)"); return true; }
+ public void endVisit(specialNoDollarRBrace17 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace17)"); }
+
+ public boolean visit(specialNoDollarRBrace18 n) { unimplementedVisitor("visit(specialNoDollarRBrace18)"); return true; }
+ public void endVisit(specialNoDollarRBrace18 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace18)"); }
+
+ public boolean visit(specialNoDollarRBrace19 n) { unimplementedVisitor("visit(specialNoDollarRBrace19)"); return true; }
+ public void endVisit(specialNoDollarRBrace19 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace19)"); }
+
+ public boolean visit(specialNoDollarRBrace20 n) { unimplementedVisitor("visit(specialNoDollarRBrace20)"); return true; }
+ public void endVisit(specialNoDollarRBrace20 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace20)"); }
+
+ public boolean visit(specialNoDollarRBrace21 n) { unimplementedVisitor("visit(specialNoDollarRBrace21)"); return true; }
+ public void endVisit(specialNoDollarRBrace21 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace21)"); }
+
+ public boolean visit(specialNoDollarRBrace22 n) { unimplementedVisitor("visit(specialNoDollarRBrace22)"); return true; }
+ public void endVisit(specialNoDollarRBrace22 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace22)"); }
+
+ public boolean visit(specialNoDollarRBrace23 n) { unimplementedVisitor("visit(specialNoDollarRBrace23)"); return true; }
+ public void endVisit(specialNoDollarRBrace23 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace23)"); }
+
+ public boolean visit(specialNoDollarRBrace24 n) { unimplementedVisitor("visit(specialNoDollarRBrace24)"); return true; }
+ public void endVisit(specialNoDollarRBrace24 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace24)"); }
+
+ public boolean visit(specialNoDollarRBrace25 n) { unimplementedVisitor("visit(specialNoDollarRBrace25)"); return true; }
+ public void endVisit(specialNoDollarRBrace25 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace25)"); }
+
+ public boolean visit(specialNoDollarRBrace26 n) { unimplementedVisitor("visit(specialNoDollarRBrace26)"); return true; }
+ public void endVisit(specialNoDollarRBrace26 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace26)"); }
+
+ public boolean visit(specialNoDollarRBrace27 n) { unimplementedVisitor("visit(specialNoDollarRBrace27)"); return true; }
+ public void endVisit(specialNoDollarRBrace27 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace27)"); }
+
+ public boolean visit(specialNoDollarRBrace28 n) { unimplementedVisitor("visit(specialNoDollarRBrace28)"); return true; }
+ public void endVisit(specialNoDollarRBrace28 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace28)"); }
+
+ public boolean visit(specialNoDollarRBrace29 n) { unimplementedVisitor("visit(specialNoDollarRBrace29)"); return true; }
+ public void endVisit(specialNoDollarRBrace29 n) { unimplementedVisitor("endVisit(specialNoDollarRBrace29)"); }
+
+ public boolean visit(special0 n) { unimplementedVisitor("visit(special0)"); return true; }
+ public void endVisit(special0 n) { unimplementedVisitor("endVisit(special0)"); }
+
+ public boolean visit(special1 n) { unimplementedVisitor("visit(special1)"); return true; }
+ public void endVisit(special1 n) { unimplementedVisitor("endVisit(special1)"); }
+
+ public boolean visit(special2 n) { unimplementedVisitor("visit(special2)"); return true; }
+ public void endVisit(special2 n) { unimplementedVisitor("endVisit(special2)"); }
+
+ public boolean visit(special3 n) { unimplementedVisitor("visit(special3)"); return true; }
+ public void endVisit(special3 n) { unimplementedVisitor("endVisit(special3)"); }
+
+ public boolean visit(special4 n) { unimplementedVisitor("visit(special4)"); return true; }
+ public void endVisit(special4 n) { unimplementedVisitor("endVisit(special4)"); }
+
+ public boolean visit(special5 n) { unimplementedVisitor("visit(special5)"); return true; }
+ public void endVisit(special5 n) { unimplementedVisitor("endVisit(special5)"); }
+
+ public boolean visit(special6 n) { unimplementedVisitor("visit(special6)"); return true; }
+ public void endVisit(special6 n) { unimplementedVisitor("endVisit(special6)"); }
+
+ public boolean visit(special7 n) { unimplementedVisitor("visit(special7)"); return true; }
+ public void endVisit(special7 n) { unimplementedVisitor("endVisit(special7)"); }
+
+ public boolean visit(special8 n) { unimplementedVisitor("visit(special8)"); return true; }
+ public void endVisit(special8 n) { unimplementedVisitor("endVisit(special8)"); }
+
+ public boolean visit(special9 n) { unimplementedVisitor("visit(special9)"); return true; }
+ public void endVisit(special9 n) { unimplementedVisitor("endVisit(special9)"); }
+
+ public boolean visit(special10 n) { unimplementedVisitor("visit(special10)"); return true; }
+ public void endVisit(special10 n) { unimplementedVisitor("endVisit(special10)"); }
+
+ public boolean visit(special11 n) { unimplementedVisitor("visit(special11)"); return true; }
+ public void endVisit(special11 n) { unimplementedVisitor("endVisit(special11)"); }
+
+ public boolean visit(special12 n) { unimplementedVisitor("visit(special12)"); return true; }
+ public void endVisit(special12 n) { unimplementedVisitor("endVisit(special12)"); }
+
+ public boolean visit(special13 n) { unimplementedVisitor("visit(special13)"); return true; }
+ public void endVisit(special13 n) { unimplementedVisitor("endVisit(special13)"); }
+
+ public boolean visit(special14 n) { unimplementedVisitor("visit(special14)"); return true; }
+ public void endVisit(special14 n) { unimplementedVisitor("endVisit(special14)"); }
+
+ public boolean visit(special15 n) { unimplementedVisitor("visit(special15)"); return true; }
+ public void endVisit(special15 n) { unimplementedVisitor("endVisit(special15)"); }
+
+ public boolean visit(special16 n) { unimplementedVisitor("visit(special16)"); return true; }
+ public void endVisit(special16 n) { unimplementedVisitor("endVisit(special16)"); }
+
+ public boolean visit(special17 n) { unimplementedVisitor("visit(special17)"); return true; }
+ public void endVisit(special17 n) { unimplementedVisitor("endVisit(special17)"); }
+
+ public boolean visit(special18 n) { unimplementedVisitor("visit(special18)"); return true; }
+ public void endVisit(special18 n) { unimplementedVisitor("endVisit(special18)"); }
+
+ public boolean visit(special19 n) { unimplementedVisitor("visit(special19)"); return true; }
+ public void endVisit(special19 n) { unimplementedVisitor("endVisit(special19)"); }
+
+ public boolean visit(special20 n) { unimplementedVisitor("visit(special20)"); return true; }
+ public void endVisit(special20 n) { unimplementedVisitor("endVisit(special20)"); }
+
+ public boolean visit(special21 n) { unimplementedVisitor("visit(special21)"); return true; }
+ public void endVisit(special21 n) { unimplementedVisitor("endVisit(special21)"); }
+
+ public boolean visit(special22 n) { unimplementedVisitor("visit(special22)"); return true; }
+ public void endVisit(special22 n) { unimplementedVisitor("endVisit(special22)"); }
+
+ public boolean visit(special23 n) { unimplementedVisitor("visit(special23)"); return true; }
+ public void endVisit(special23 n) { unimplementedVisitor("endVisit(special23)"); }
+
+ public boolean visit(special24 n) { unimplementedVisitor("visit(special24)"); return true; }
+ public void endVisit(special24 n) { unimplementedVisitor("endVisit(special24)"); }
+
+ public boolean visit(special25 n) { unimplementedVisitor("visit(special25)"); return true; }
+ public void endVisit(special25 n) { unimplementedVisitor("endVisit(special25)"); }
+
+ public boolean visit(special26 n) { unimplementedVisitor("visit(special26)"); return true; }
+ public void endVisit(special26 n) { unimplementedVisitor("endVisit(special26)"); }
+
+ public boolean visit(special27 n) { unimplementedVisitor("visit(special27)"); return true; }
+ public void endVisit(special27 n) { unimplementedVisitor("endVisit(special27)"); }
+
+ public boolean visit(special28 n) { unimplementedVisitor("visit(special28)"); return true; }
+ public void endVisit(special28 n) { unimplementedVisitor("endVisit(special28)"); }
+
+ public boolean visit(special29 n) { unimplementedVisitor("visit(special29)"); return true; }
+ public void endVisit(special29 n) { unimplementedVisitor("endVisit(special29)"); }
+
+ public boolean visit(special30 n) { unimplementedVisitor("visit(special30)"); return true; }
+ public void endVisit(special30 n) { unimplementedVisitor("endVisit(special30)"); }
+
+ public boolean visit(special31 n) { unimplementedVisitor("visit(special31)"); return true; }
+ public void endVisit(special31 n) { unimplementedVisitor("endVisit(special31)"); }
+
+ public boolean visit(special32 n) { unimplementedVisitor("visit(special32)"); return true; }
+ public void endVisit(special32 n) { unimplementedVisitor("endVisit(special32)"); }
+
+
+ public boolean visit(ASTNode n)
+ {
+ if (n instanceof ASTNodeToken) return visit((ASTNodeToken) n);
+ else if (n instanceof simpleStringPrefixed) return visit((simpleStringPrefixed) n);
+ else if (n instanceof valStringNoSubst) return visit((valStringNoSubst) n);
+ else if (n instanceof substPrefixed) return visit((substPrefixed) n);
+ else if (n instanceof substitutionList) return visit((substitutionList) n);
+ else if (n instanceof substitution) return visit((substitution) n);
+ else if (n instanceof optParameter) return visit((optParameter) n);
+ else if (n instanceof ident) return visit((ident) n);
+ else if (n instanceof escapedChar) return visit((escapedChar) n);
+ else if (n instanceof specialNoDollarRBrace0) return visit((specialNoDollarRBrace0) n);
+ else if (n instanceof specialNoDollarRBrace1) return visit((specialNoDollarRBrace1) n);
+ else if (n instanceof specialNoDollarRBrace2) return visit((specialNoDollarRBrace2) n);
+ else if (n instanceof specialNoDollarRBrace3) return visit((specialNoDollarRBrace3) n);
+ else if (n instanceof specialNoDollarRBrace4) return visit((specialNoDollarRBrace4) n);
+ else if (n instanceof specialNoDollarRBrace5) return visit((specialNoDollarRBrace5) n);
+ else if (n instanceof specialNoDollarRBrace6) return visit((specialNoDollarRBrace6) n);
+ else if (n instanceof specialNoDollarRBrace7) return visit((specialNoDollarRBrace7) n);
+ else if (n instanceof specialNoDollarRBrace8) return visit((specialNoDollarRBrace8) n);
+ else if (n instanceof specialNoDollarRBrace9) return visit((specialNoDollarRBrace9) n);
+ else if (n instanceof specialNoDollarRBrace10) return visit((specialNoDollarRBrace10) n);
+ else if (n instanceof specialNoDollarRBrace11) return visit((specialNoDollarRBrace11) n);
+ else if (n instanceof specialNoDollarRBrace12) return visit((specialNoDollarRBrace12) n);
+ else if (n instanceof specialNoDollarRBrace13) return visit((specialNoDollarRBrace13) n);
+ else if (n instanceof specialNoDollarRBrace14) return visit((specialNoDollarRBrace14) n);
+ else if (n instanceof specialNoDollarRBrace15) return visit((specialNoDollarRBrace15) n);
+ else if (n instanceof specialNoDollarRBrace16) return visit((specialNoDollarRBrace16) n);
+ else if (n instanceof specialNoDollarRBrace17) return visit((specialNoDollarRBrace17) n);
+ else if (n instanceof specialNoDollarRBrace18) return visit((specialNoDollarRBrace18) n);
+ else if (n instanceof specialNoDollarRBrace19) return visit((specialNoDollarRBrace19) n);
+ else if (n instanceof specialNoDollarRBrace20) return visit((specialNoDollarRBrace20) n);
+ else if (n instanceof specialNoDollarRBrace21) return visit((specialNoDollarRBrace21) n);
+ else if (n instanceof specialNoDollarRBrace22) return visit((specialNoDollarRBrace22) n);
+ else if (n instanceof specialNoDollarRBrace23) return visit((specialNoDollarRBrace23) n);
+ else if (n instanceof specialNoDollarRBrace24) return visit((specialNoDollarRBrace24) n);
+ else if (n instanceof specialNoDollarRBrace25) return visit((specialNoDollarRBrace25) n);
+ else if (n instanceof specialNoDollarRBrace26) return visit((specialNoDollarRBrace26) n);
+ else if (n instanceof specialNoDollarRBrace27) return visit((specialNoDollarRBrace27) n);
+ else if (n instanceof specialNoDollarRBrace28) return visit((specialNoDollarRBrace28) n);
+ else if (n instanceof specialNoDollarRBrace29) return visit((specialNoDollarRBrace29) n);
+ else if (n instanceof special0) return visit((special0) n);
+ else if (n instanceof special1) return visit((special1) n);
+ else if (n instanceof special2) return visit((special2) n);
+ else if (n instanceof special3) return visit((special3) n);
+ else if (n instanceof special4) return visit((special4) n);
+ else if (n instanceof special5) return visit((special5) n);
+ else if (n instanceof special6) return visit((special6) n);
+ else if (n instanceof special7) return visit((special7) n);
+ else if (n instanceof special8) return visit((special8) n);
+ else if (n instanceof special9) return visit((special9) n);
+ else if (n instanceof special10) return visit((special10) n);
+ else if (n instanceof special11) return visit((special11) n);
+ else if (n instanceof special12) return visit((special12) n);
+ else if (n instanceof special13) return visit((special13) n);
+ else if (n instanceof special14) return visit((special14) n);
+ else if (n instanceof special15) return visit((special15) n);
+ else if (n instanceof special16) return visit((special16) n);
+ else if (n instanceof special17) return visit((special17) n);
+ else if (n instanceof special18) return visit((special18) n);
+ else if (n instanceof special19) return visit((special19) n);
+ else if (n instanceof special20) return visit((special20) n);
+ else if (n instanceof special21) return visit((special21) n);
+ else if (n instanceof special22) return visit((special22) n);
+ else if (n instanceof special23) return visit((special23) n);
+ else if (n instanceof special24) return visit((special24) n);
+ else if (n instanceof special25) return visit((special25) n);
+ else if (n instanceof special26) return visit((special26) n);
+ else if (n instanceof special27) return visit((special27) n);
+ else if (n instanceof special28) return visit((special28) n);
+ else if (n instanceof special29) return visit((special29) n);
+ else if (n instanceof special30) return visit((special30) n);
+ else if (n instanceof special31) return visit((special31) n);
+ else if (n instanceof special32) return visit((special32) n);
+ throw new UnsupportedOperationException("visit(" + n.getClass().toString() + ")");
+ }
+ public void endVisit(ASTNode n)
+ {
+ if (n instanceof ASTNodeToken) endVisit((ASTNodeToken) n);
+ else if (n instanceof simpleStringPrefixed) endVisit((simpleStringPrefixed) n);
+ else if (n instanceof valStringNoSubst) endVisit((valStringNoSubst) n);
+ else if (n instanceof substPrefixed) endVisit((substPrefixed) n);
+ else if (n instanceof substitutionList) endVisit((substitutionList) n);
+ else if (n instanceof substitution) endVisit((substitution) n);
+ else if (n instanceof optParameter) endVisit((optParameter) n);
+ else if (n instanceof ident) endVisit((ident) n);
+ else if (n instanceof escapedChar) endVisit((escapedChar) n);
+ else if (n instanceof specialNoDollarRBrace0) endVisit((specialNoDollarRBrace0) n);
+ else if (n instanceof specialNoDollarRBrace1) endVisit((specialNoDollarRBrace1) n);
+ else if (n instanceof specialNoDollarRBrace2) endVisit((specialNoDollarRBrace2) n);
+ else if (n instanceof specialNoDollarRBrace3) endVisit((specialNoDollarRBrace3) n);
+ else if (n instanceof specialNoDollarRBrace4) endVisit((specialNoDollarRBrace4) n);
+ else if (n instanceof specialNoDollarRBrace5) endVisit((specialNoDollarRBrace5) n);
+ else if (n instanceof specialNoDollarRBrace6) endVisit((specialNoDollarRBrace6) n);
+ else if (n instanceof specialNoDollarRBrace7) endVisit((specialNoDollarRBrace7) n);
+ else if (n instanceof specialNoDollarRBrace8) endVisit((specialNoDollarRBrace8) n);
+ else if (n instanceof specialNoDollarRBrace9) endVisit((specialNoDollarRBrace9) n);
+ else if (n instanceof specialNoDollarRBrace10) endVisit((specialNoDollarRBrace10) n);
+ else if (n instanceof specialNoDollarRBrace11) endVisit((specialNoDollarRBrace11) n);
+ else if (n instanceof specialNoDollarRBrace12) endVisit((specialNoDollarRBrace12) n);
+ else if (n instanceof specialNoDollarRBrace13) endVisit((specialNoDollarRBrace13) n);
+ else if (n instanceof specialNoDollarRBrace14) endVisit((specialNoDollarRBrace14) n);
+ else if (n instanceof specialNoDollarRBrace15) endVisit((specialNoDollarRBrace15) n);
+ else if (n instanceof specialNoDollarRBrace16) endVisit((specialNoDollarRBrace16) n);
+ else if (n instanceof specialNoDollarRBrace17) endVisit((specialNoDollarRBrace17) n);
+ else if (n instanceof specialNoDollarRBrace18) endVisit((specialNoDollarRBrace18) n);
+ else if (n instanceof specialNoDollarRBrace19) endVisit((specialNoDollarRBrace19) n);
+ else if (n instanceof specialNoDollarRBrace20) endVisit((specialNoDollarRBrace20) n);
+ else if (n instanceof specialNoDollarRBrace21) endVisit((specialNoDollarRBrace21) n);
+ else if (n instanceof specialNoDollarRBrace22) endVisit((specialNoDollarRBrace22) n);
+ else if (n instanceof specialNoDollarRBrace23) endVisit((specialNoDollarRBrace23) n);
+ else if (n instanceof specialNoDollarRBrace24) endVisit((specialNoDollarRBrace24) n);
+ else if (n instanceof specialNoDollarRBrace25) endVisit((specialNoDollarRBrace25) n);
+ else if (n instanceof specialNoDollarRBrace26) endVisit((specialNoDollarRBrace26) n);
+ else if (n instanceof specialNoDollarRBrace27) endVisit((specialNoDollarRBrace27) n);
+ else if (n instanceof specialNoDollarRBrace28) endVisit((specialNoDollarRBrace28) n);
+ else if (n instanceof specialNoDollarRBrace29) endVisit((specialNoDollarRBrace29) n);
+ else if (n instanceof special0) endVisit((special0) n);
+ else if (n instanceof special1) endVisit((special1) n);
+ else if (n instanceof special2) endVisit((special2) n);
+ else if (n instanceof special3) endVisit((special3) n);
+ else if (n instanceof special4) endVisit((special4) n);
+ else if (n instanceof special5) endVisit((special5) n);
+ else if (n instanceof special6) endVisit((special6) n);
+ else if (n instanceof special7) endVisit((special7) n);
+ else if (n instanceof special8) endVisit((special8) n);
+ else if (n instanceof special9) endVisit((special9) n);
+ else if (n instanceof special10) endVisit((special10) n);
+ else if (n instanceof special11) endVisit((special11) n);
+ else if (n instanceof special12) endVisit((special12) n);
+ else if (n instanceof special13) endVisit((special13) n);
+ else if (n instanceof special14) endVisit((special14) n);
+ else if (n instanceof special15) endVisit((special15) n);
+ else if (n instanceof special16) endVisit((special16) n);
+ else if (n instanceof special17) endVisit((special17) n);
+ else if (n instanceof special18) endVisit((special18) n);
+ else if (n instanceof special19) endVisit((special19) n);
+ else if (n instanceof special20) endVisit((special20) n);
+ else if (n instanceof special21) endVisit((special21) n);
+ else if (n instanceof special22) endVisit((special22) n);
+ else if (n instanceof special23) endVisit((special23) n);
+ else if (n instanceof special24) endVisit((special24) n);
+ else if (n instanceof special25) endVisit((special25) n);
+ else if (n instanceof special26) endVisit((special26) n);
+ else if (n instanceof special27) endVisit((special27) n);
+ else if (n instanceof special28) endVisit((special28) n);
+ else if (n instanceof special29) endVisit((special29) n);
+ else if (n instanceof special30) endVisit((special30) n);
+ else if (n instanceof special31) endVisit((special31) n);
+ else if (n instanceof special32) endVisit((special32) n);
+ throw new UnsupportedOperationException("visit(" + n.getClass().toString() + ")");
+ }
+ }
+
+ public void ruleAction(int ruleNumber)
+ {
+ switch (ruleNumber)
+ {
+
+ //
+ // Rule 1: digit ::= 0
+ //
+ case 1: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 2: digit ::= 1
+ //
+ case 2: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 3: digit ::= 2
+ //
+ case 3: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 4: digit ::= 3
+ //
+ case 4: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 5: digit ::= 4
+ //
+ case 5: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 6: digit ::= 5
+ //
+ case 6: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 7: digit ::= 6
+ //
+ case 7: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 8: digit ::= 7
+ //
+ case 8: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 9: digit ::= 8
+ //
+ case 9: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 10: digit ::= 9
+ //
+ case 10: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 11: aA ::= a
+ //
+ case 11: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 12: aA ::= A
+ //
+ case 12: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 13: bB ::= b
+ //
+ case 13: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 14: bB ::= B
+ //
+ case 14: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 15: cC ::= c
+ //
+ case 15: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 16: cC ::= C
+ //
+ case 16: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 17: dD ::= d
+ //
+ case 17: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 18: dD ::= D
+ //
+ case 18: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 19: eE ::= e
+ //
+ case 19: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 20: eE ::= E
+ //
+ case 20: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 21: fF ::= f
+ //
+ case 21: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 22: fF ::= F
+ //
+ case 22: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 23: gG ::= g
+ //
+ case 23: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 24: gG ::= G
+ //
+ case 24: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 25: hH ::= h
+ //
+ case 25: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 26: hH ::= H
+ //
+ case 26: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 27: iI ::= i
+ //
+ case 27: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 28: iI ::= I
+ //
+ case 28: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 29: jJ ::= j
+ //
+ case 29: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 30: jJ ::= J
+ //
+ case 30: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 31: kK ::= k
+ //
+ case 31: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 32: kK ::= K
+ //
+ case 32: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 33: lL ::= l
+ //
+ case 33: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 34: lL ::= L
+ //
+ case 34: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 35: mM ::= m
+ //
+ case 35: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 36: mM ::= M
+ //
+ case 36: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 37: nN ::= n
+ //
+ case 37: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 38: nN ::= N
+ //
+ case 38: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 39: oO ::= o
+ //
+ case 39: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 40: oO ::= O
+ //
+ case 40: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 41: pP ::= p
+ //
+ case 41: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 42: pP ::= P
+ //
+ case 42: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 43: qQ ::= q
+ //
+ case 43: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 44: qQ ::= Q
+ //
+ case 44: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 45: rR ::= r
+ //
+ case 45: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 46: rR ::= R
+ //
+ case 46: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 47: sS ::= s
+ //
+ case 47: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 48: sS ::= S
+ //
+ case 48: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 49: tT ::= t
+ //
+ case 49: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 50: tT ::= T
+ //
+ case 50: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 51: uU ::= u
+ //
+ case 51: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 52: uU ::= U
+ //
+ case 52: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 53: vV ::= v
+ //
+ case 53: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 54: vV ::= V
+ //
+ case 54: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 55: wW ::= w
+ //
+ case 55: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 56: wW ::= W
+ //
+ case 56: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 57: xX ::= x
+ //
+ case 57: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 58: xX ::= X
+ //
+ case 58: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 59: yY ::= y
+ //
+ case 59: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 60: yY ::= Y
+ //
+ case 60: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 61: zZ ::= z
+ //
+ case 61: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 62: zZ ::= Z
+ //
+ case 62: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 63: letter ::= aA
+ //
+ case 63:
+ break;
+ //
+ // Rule 64: letter ::= bB
+ //
+ case 64:
+ break;
+ //
+ // Rule 65: letter ::= cC
+ //
+ case 65:
+ break;
+ //
+ // Rule 66: letter ::= dD
+ //
+ case 66:
+ break;
+ //
+ // Rule 67: letter ::= eE
+ //
+ case 67:
+ break;
+ //
+ // Rule 68: letter ::= fF
+ //
+ case 68:
+ break;
+ //
+ // Rule 69: letter ::= gG
+ //
+ case 69:
+ break;
+ //
+ // Rule 70: letter ::= hH
+ //
+ case 70:
+ break;
+ //
+ // Rule 71: letter ::= iI
+ //
+ case 71:
+ break;
+ //
+ // Rule 72: letter ::= jJ
+ //
+ case 72:
+ break;
+ //
+ // Rule 73: letter ::= kK
+ //
+ case 73:
+ break;
+ //
+ // Rule 74: letter ::= lL
+ //
+ case 74:
+ break;
+ //
+ // Rule 75: letter ::= mM
+ //
+ case 75:
+ break;
+ //
+ // Rule 76: letter ::= nN
+ //
+ case 76:
+ break;
+ //
+ // Rule 77: letter ::= oO
+ //
+ case 77:
+ break;
+ //
+ // Rule 78: letter ::= pP
+ //
+ case 78:
+ break;
+ //
+ // Rule 79: letter ::= qQ
+ //
+ case 79:
+ break;
+ //
+ // Rule 80: letter ::= rR
+ //
+ case 80:
+ break;
+ //
+ // Rule 81: letter ::= sS
+ //
+ case 81:
+ break;
+ //
+ // Rule 82: letter ::= tT
+ //
+ case 82:
+ break;
+ //
+ // Rule 83: letter ::= uU
+ //
+ case 83:
+ break;
+ //
+ // Rule 84: letter ::= vV
+ //
+ case 84:
+ break;
+ //
+ // Rule 85: letter ::= wW
+ //
+ case 85:
+ break;
+ //
+ // Rule 86: letter ::= xX
+ //
+ case 86:
+ break;
+ //
+ // Rule 87: letter ::= yY
+ //
+ case 87:
+ break;
+ //
+ // Rule 88: letter ::= zZ
+ //
+ case 88:
+ break;
+ //
+ // Rule 89: value ::= simpleStringPrefixed
+ //
+ case 89:
+ break;
+ //
+ // Rule 90: value ::= substPrefixed
+ //
+ case 90:
+ break;
+ //
+ // Rule 91: simpleStringPrefixed ::= valStringNoSubst
+ //
+ case 91: {
+ setResult(
+ new simpleStringPrefixed(getLeftIToken(), getRightIToken(),
+ (IvalStringNoSubst)getRhsSym(1),
+ (IsubstPrefixed)null)
+ );
+ break;
+ }
+ //
+ // Rule 92: simpleStringPrefixed ::= valStringNoSubst substPrefixed
+ //
+ case 92: {
+ setResult(
+ new simpleStringPrefixed(getLeftIToken(), getRightIToken(),
+ (IvalStringNoSubst)getRhsSym(1),
+ (IsubstPrefixed)getRhsSym(2))
+ );
+ break;
+ }
+ //
+ // Rule 93: valStringNoSubst ::= valueStringNoSubst$
+ //
+ case 93: {
+ setResult(
+ new valStringNoSubst(getLeftIToken(), getRightIToken())
+ );
+ break;
+ }
+ //
+ // Rule 94: substPrefixed ::= substitutionList
+ //
+ case 94:
+ break;
+ //
+ // Rule 95: substPrefixed ::= substitutionList simpleStringPrefixed
+ //
+ case 95: {
+ setResult(
+ new substPrefixed(getLeftIToken(), getRightIToken(),
+ (substitutionList)getRhsSym(1),
+ (IsimpleStringPrefixed)getRhsSym(2))
+ );
+ break;
+ }
+ //
+ // Rule 96: substitutionList ::= substitution
+ //
+ case 96: {
+ setResult(
+ new substitutionList((substitution)getRhsSym(1), true /* left recursive */)
+ );
+ break;
+ }
+ //
+ // Rule 97: substitutionList ::= substitutionList substitution
+ //
+ case 97: {
+ ((substitutionList)getRhsSym(1)).add((substitution)getRhsSym(2));
+ break;
+ }
+ //
+ // Rule 98: valueStringNoSubst ::= nonSubstStart
+ //
+ case 98:
+ break;
+ //
+ // Rule 99: valueStringNoSubst ::= escapedChar
+ //
+ case 99:
+ break;
+ //
+ // Rule 100: valueStringNoSubst ::= valueStringNoSubst escapedChar
+ //
+ case 100: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 101: valueStringNoSubst ::= valueStringNoSubst letter
+ //
+ case 101: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 102: valueStringNoSubst ::= valueStringNoSubst digit
+ //
+ case 102: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 103: valueStringNoSubst ::= valueStringNoSubst specialNoDollarRBrace
+ //
+ case 103: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 104: substitution ::= $$ {$ ident optParameter }$
+ //
+ case 104: {
+ setResult(
+ new substitution(getLeftIToken(), getRightIToken(),
+ (ident)getRhsSym(3),
+ (optParameter)getRhsSym(4))
+ );
+ break;
+ }
+ //
+ // Rule 105: optParameter ::= $Empty
+ //
+ case 105: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 106: optParameter ::= :$ value
+ //
+ case 106: {
+ setResult(
+ new optParameter(getLeftIToken(), getRightIToken(),
+ (Ivalue)getRhsSym(2))
+ );
+ break;
+ }
+ //
+ // Rule 107: ident ::= identChars$
+ //
+ case 107: {
+ setResult(
+ new ident(getLeftIToken(), getRightIToken())
+ );
+ break;
+ }
+ //
+ // Rule 108: identChars ::= letter
+ //
+ case 108:
+ break;
+ //
+ // Rule 109: identChars ::= identChars letter
+ //
+ case 109: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 110: identChars ::= identChars digit
+ //
+ case 110: {
+ setResult(null);
+ break;
+ }
+ //
+ // Rule 111: nonSubstStart ::= letter
+ //
+ case 111:
+ break;
+ //
+ // Rule 112: nonSubstStart ::= digit
+ //
+ case 112:
+ break;
+ //
+ // Rule 113: nonSubstStart ::= specialNoDollarRBrace
+ //
+ case 113:
+ break;
+ //
+ // Rule 114: escapedChar ::= \$ escapableChar
+ //
+ case 114: {
+ setResult(
+ new escapedChar(getLeftIToken(), getRightIToken(),
+ (IescapableChar)getRhsSym(2))
+ );
+ break;
+ }
+ //
+ // Rule 115: escapableChar ::= letter
+ //
+ case 115:
+ break;
+ //
+ // Rule 116: escapableChar ::= digit
+ //
+ case 116:
+ break;
+ //
+ // Rule 117: escapableChar ::= special
+ //
+ case 117:
+ break;
+ //
+ // Rule 118: specialNoDollarRBrace ::= +
+ //
+ case 118: {
+ setResult(
+ new specialNoDollarRBrace0(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 119: specialNoDollarRBrace ::= -
+ //
+ case 119: {
+ setResult(
+ new specialNoDollarRBrace1(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 120: specialNoDollarRBrace ::= (
+ //
+ case 120: {
+ setResult(
+ new specialNoDollarRBrace2(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 121: specialNoDollarRBrace ::= )
+ //
+ case 121: {
+ setResult(
+ new specialNoDollarRBrace3(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 122: specialNoDollarRBrace ::= "
+ //
+ case 122: {
+ setResult(
+ new specialNoDollarRBrace4(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 123: specialNoDollarRBrace ::= !
+ //
+ case 123: {
+ setResult(
+ new specialNoDollarRBrace5(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 124: specialNoDollarRBrace ::= @
+ //
+ case 124: {
+ setResult(
+ new specialNoDollarRBrace6(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 125: specialNoDollarRBrace ::= `
+ //
+ case 125: {
+ setResult(
+ new specialNoDollarRBrace7(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 126: specialNoDollarRBrace ::= ~
+ //
+ case 126: {
+ setResult(
+ new specialNoDollarRBrace8(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 127: specialNoDollarRBrace ::= .
+ //
+ case 127: {
+ setResult(
+ new specialNoDollarRBrace9(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 128: specialNoDollarRBrace ::= /
+ //
+ case 128: {
+ setResult(
+ new specialNoDollarRBrace10(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 129: specialNoDollarRBrace ::= %
+ //
+ case 129: {
+ setResult(
+ new specialNoDollarRBrace11(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 130: specialNoDollarRBrace ::= &
+ //
+ case 130: {
+ setResult(
+ new specialNoDollarRBrace12(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 131: specialNoDollarRBrace ::= ^
+ //
+ case 131: {
+ setResult(
+ new specialNoDollarRBrace13(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 132: specialNoDollarRBrace ::= :
+ //
+ case 132: {
+ setResult(
+ new specialNoDollarRBrace14(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 133: specialNoDollarRBrace ::= ;
+ //
+ case 133: {
+ setResult(
+ new specialNoDollarRBrace15(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 134: specialNoDollarRBrace ::= '
+ //
+ case 134: {
+ setResult(
+ new specialNoDollarRBrace16(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 135: specialNoDollarRBrace ::= |
+ //
+ case 135: {
+ setResult(
+ new specialNoDollarRBrace17(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 136: specialNoDollarRBrace ::= {
+ //
+ case 136: {
+ setResult(
+ new specialNoDollarRBrace18(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 137: specialNoDollarRBrace ::=
+ //
+ case 137: {
+ setResult(
+ new specialNoDollarRBrace19(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 138: specialNoDollarRBrace ::= [
+ //
+ case 138: {
+ setResult(
+ new specialNoDollarRBrace20(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 139: specialNoDollarRBrace ::= ]
+ //
+ case 139: {
+ setResult(
+ new specialNoDollarRBrace21(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 140: specialNoDollarRBrace ::= ?
+ //
+ case 140: {
+ setResult(
+ new specialNoDollarRBrace22(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 141: specialNoDollarRBrace ::= ,
+ //
+ case 141: {
+ setResult(
+ new specialNoDollarRBrace23(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 142: specialNoDollarRBrace ::= <
+ //
+ case 142: {
+ setResult(
+ new specialNoDollarRBrace24(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 143: specialNoDollarRBrace ::= >
+ //
+ case 143: {
+ setResult(
+ new specialNoDollarRBrace25(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 144: specialNoDollarRBrace ::= =
+ //
+ case 144: {
+ setResult(
+ new specialNoDollarRBrace26(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 145: specialNoDollarRBrace ::= #
+ //
+ case 145: {
+ setResult(
+ new specialNoDollarRBrace27(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 146: specialNoDollarRBrace ::= *
+ //
+ case 146: {
+ setResult(
+ new specialNoDollarRBrace28(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 147: specialNoDollarRBrace ::= _
+ //
+ case 147: {
+ setResult(
+ new specialNoDollarRBrace29(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 148: special ::= +
+ //
+ case 148: {
+ setResult(
+ new special0(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 149: special ::= -
+ //
+ case 149: {
+ setResult(
+ new special1(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 150: special ::= (
+ //
+ case 150: {
+ setResult(
+ new special2(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 151: special ::= )
+ //
+ case 151: {
+ setResult(
+ new special3(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 152: special ::= "
+ //
+ case 152: {
+ setResult(
+ new special4(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 153: special ::= !
+ //
+ case 153: {
+ setResult(
+ new special5(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 154: special ::= @
+ //
+ case 154: {
+ setResult(
+ new special6(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 155: special ::= `
+ //
+ case 155: {
+ setResult(
+ new special7(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 156: special ::= ~
+ //
+ case 156: {
+ setResult(
+ new special8(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 157: special ::= .
+ //
+ case 157: {
+ setResult(
+ new special9(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 158: special ::= /
+ //
+ case 158: {
+ setResult(
+ new special10(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 159: special ::= %
+ //
+ case 159: {
+ setResult(
+ new special11(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 160: special ::= &
+ //
+ case 160: {
+ setResult(
+ new special12(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 161: special ::= ^
+ //
+ case 161: {
+ setResult(
+ new special13(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 162: special ::= :
+ //
+ case 162: {
+ setResult(
+ new special14(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 163: special ::= ;
+ //
+ case 163: {
+ setResult(
+ new special15(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 164: special ::= '
+ //
+ case 164: {
+ setResult(
+ new special16(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 165: special ::= \
+ //
+ case 165: {
+ setResult(
+ new special17(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 166: special ::= |
+ //
+ case 166: {
+ setResult(
+ new special18(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 167: special ::= {
+ //
+ case 167: {
+ setResult(
+ new special19(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 168: special ::=
+ //
+ case 168: {
+ setResult(
+ new special20(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 169: special ::= }
+ //
+ case 169: {
+ setResult(
+ new special21(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 170: special ::= [
+ //
+ case 170: {
+ setResult(
+ new special22(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 171: special ::= ]
+ //
+ case 171: {
+ setResult(
+ new special23(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 172: special ::= ?
+ //
+ case 172: {
+ setResult(
+ new special24(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 173: special ::= ,
+ //
+ case 173: {
+ setResult(
+ new special25(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 174: special ::= <
+ //
+ case 174: {
+ setResult(
+ new special26(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 175: special ::= >
+ //
+ case 175: {
+ setResult(
+ new special27(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 176: special ::= =
+ //
+ case 176: {
+ setResult(
+ new special28(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 177: special ::= #
+ //
+ case 177: {
+ setResult(
+ new special29(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 178: special ::= *
+ //
+ case 178: {
+ setResult(
+ new special30(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 179: special ::= _
+ //
+ case 179: {
+ setResult(
+ new special31(getRhsIToken(1))
+ );
+ break;
+ }
+ //
+ // Rule 180: special ::= $
+ //
+ case 180: {
+ setResult(
+ new special32(getRhsIToken(1))
+ );
+ break;
+ }
+
+ default:
+ break;
+ }
+ return;
+ }
+}
+
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.l b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.l
new file mode 100644
index 000000000..4b02283f0
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.l
@@ -0,0 +1,85 @@
+
+Options in effect for C:/Development/QvtDeclarative/plugins/org.eclipse.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.g:
+
+ ACTION-BLOCK=("C:\Development\QvtDeclarative\plugins\org.eclipse.imp.runtime\src\org\eclipse\imp\preferences\PreferenceValueParser.java","/.","./")
+
+ AST-DIRECTORY="" AST-TYPE="ASTNode" NOATTRIBUTES AUTOMATIC-AST=NESTED
+ NOBACKTRACK BYTE CONFLICTS
+ DAT-DIRECTORY="C:\Development\QvtDeclarative\plugins\org.eclipse.imp.runtime\src\org\eclipse\imp\preferences\"
+
+ DAT-FILE="C:\Development\QvtDeclarative\plugins\org.eclipse.imp.runtime\src\org\eclipse\imp\preferences\PreferenceValueParserdcl.data"
+
+ DCL-FILE="C:\Development\QvtDeclarative\plugins\org.eclipse.imp.runtime\src\org\eclipse\imp\preferences\PreferenceValueParserdcl.java"
+ NODEBUG
+ DEF-FILE="C:\Development\QvtDeclarative\plugins\org.eclipse.imp.runtime\src\org\eclipse\imp\preferences\PreferenceValueParserdef.java"
+ NOEDIT NOERROR-MAPS ESCAPE='$'
+ EXPORT-TERMINALS=("C:\Development\QvtDeclarative\plugins\org.eclipse.imp.runtime\src\org\eclipse\imp\preferences\PreferenceValueParserexp.java","","")
+ EXTENDS-PARSETABLE FACTORY="new " FILE-PREFIX="PreferenceValueParser"
+ NOFIRST NOFOLLOW NOGLR NOGOTO-DEFAULT
+ GRM-FILE="C:/Development/QvtDeclarative/plugins/org.eclipse.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.g"
+
+ IMP-FILE="C:\Development\QvtDeclarative\plugins\org.eclipse.imp.runtime\src\org\eclipse\imp\preferences\PreferenceValueParserimp.java"
+
+ INCLUDE-DIRECTORY="C:\Development\QvtDeclarative\tools\lpg.runtime.java\templates;C:\Development.NoBackup\QVT\Workspace3.4\org.eclipse.imp.lpg.metatooling\templates;C:\Development\QvtDeclarative\tools\lpg.runtime.java\include;"
+ LALR=1 LEGACY NOLIST MARGIN=4 MAX-CASES=1024 NAMES=OPTIMIZED
+ NONT-CHECK OR_MARKER='|'
+ OUT-DIRECTORY="C:\Development\QvtDeclarative\plugins\org.eclipse.imp.runtime\src\org\eclipse\imp\preferences\"
+ PACKAGE="org.eclipse.imp.preferences" PARENT-SAVED
+ PARSETABLE-INTERFACES="lpg.runtime.ParseTable" PREFIX="Char_" PRIORITY
+ PROGRAMMING_LANGUAGE=JAVA
+ PRS-FILE="C:\Development\QvtDeclarative\plugins\org.eclipse.imp.runtime\src\org\eclipse\imp\preferences\PreferenceValueParserprs.java"
+ NOQUIET READ-REDUCE REMAP-TERMINALS NOSCOPES NOSERIALIZE
+ NOSHIFT-DEFAULT NOSINGLE-PRODUCTIONS NOSOFT-KEYWORDS NOSTATES SUFFIX=""
+ SYM-FILE="C:\Development\QvtDeclarative\plugins\org.eclipse.imp.runtime\src\org\eclipse\imp\preferences\PreferenceValueParsersym.java"
+ TAB-FILE="PreferenceValueParser.t" TABLE TEMPLATE="" TRACE=CONFLICTS
+ VARIABLES NOVERBOSE VISITOR=PREORDER VISITOR-TYPE="Visitor" WARNINGS
+ NOXREF
+
+C:/Development/QvtDeclarative/plugins/org.eclipse.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.g:143:5:143:16:3461:3472: Informative: The terminal CtlCharNotWS is useless.
+C:/Development/QvtDeclarative/plugins/org.eclipse.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.g:144:5:144:6:3479:3480: Informative: The terminal HT is useless.
+C:/Development/QvtDeclarative/plugins/org.eclipse.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.g:145:5:145:6:3487:3488: Informative: The terminal LF is useless.
+C:/Development/QvtDeclarative/plugins/org.eclipse.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.g:146:5:146:6:3495:3496: Informative: The terminal FF is useless.
+C:/Development/QvtDeclarative/plugins/org.eclipse.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.g:147:5:147:6:3503:3504: Informative: The terminal CR is useless.
+C:/Development/QvtDeclarative/plugins/org.eclipse.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.g:148:5:148:14:3511:3520: Informative: The terminal AfterASCII is useless.
+
+
+C:/Development/QvtDeclarative/plugins/org.eclipse.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParser.g:152:5:152:9:3543:3547: Informative: Grammar is LALR(1).
+
+Number of Terminals: 102
+Number of Nonterminals: 43
+Number of Productions: 181
+Number of Items: 376
+Number of States: 12
+Number of Shift actions: 10
+Number of Goto actions: 13
+Number of Shift/Reduce actions: 578
+Number of Goto/Reduce actions: 219
+Number of Reduce actions: 11
+Number of Shift-Reduce conflicts: 0
+Number of Reduce-Reduce conflicts: 0
+
+Number of entries in base Action Table: 244
+Additional space required for compaction of Action Table: 23.3%
+
+Number of unique terminal states: 11
+Number of Shift actions saved by merging: 94
+Number of Conflict points saved by merging: 0
+Number of Reduce actions saved by merging: 0
+Number of Reduce saved by default: 10
+
+Number of entries in Terminal Action Table: 506
+Additional space required for compaction of Terminal Table: 17.9%
+
+Actions in Compressed Tables:
+ Number of Shifts: 8
+ Number of Shift/Reduces: 486
+ Number of Gotos: 13
+ Number of Goto/Reduces: 219
+ Number of Reduces: 1
+ Number of Defaults: 5
+
+Parsing Tables storage:
+ Storage required for BASE_CHECK: 181 Bytes
+ Storage required for BASE_ACTION: 966 Bytes
+ Storage required for TERM_CHECK: 605 Bytes
+ Storage required for TERM_ACTION: 1196 Bytes
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParserprs.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParserprs.java
new file mode 100644
index 000000000..36500d938
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParserprs.java
@@ -0,0 +1,386 @@
+
+////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2007 IBM Corporation.
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+//Author: Robert Fuhrer (rfuhrer@watson.ibm.com)
+////////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.imp.preferences;
+
+public class PreferenceValueParserprs implements lpg.runtime.ParseTable, PreferenceValueParsersym {
+ public final static int ERROR_SYMBOL = 0;
+ public final int getErrorSymbol() { return ERROR_SYMBOL; }
+
+ public final static int SCOPE_UBOUND = 0;
+ public final int getScopeUbound() { return SCOPE_UBOUND; }
+
+ public final static int SCOPE_SIZE = 0;
+ public final int getScopeSize() { return SCOPE_SIZE; }
+
+ public final static int MAX_NAME_LENGTH = 0;
+ public final int getMaxNameLength() { return MAX_NAME_LENGTH; }
+
+ public final static int NUM_STATES = 12;
+ public final int getNumStates() { return NUM_STATES; }
+
+ public final static int NT_OFFSET = 102;
+ public final int getNtOffset() { return NT_OFFSET; }
+
+ public final static int LA_STATE_OFFSET = 663;
+ public final int getLaStateOffset() { return LA_STATE_OFFSET; }
+
+ public final static int MAX_LA = 1;
+ public final int getMaxLa() { return MAX_LA; }
+
+ public final static int NUM_RULES = 180;
+ public final int getNumRules() { return NUM_RULES; }
+
+ public final static int NUM_NONTERMINALS = 44;
+ public final int getNumNonterminals() { return NUM_NONTERMINALS; }
+
+ public final static int NUM_SYMBOLS = 146;
+ public final int getNumSymbols() { return NUM_SYMBOLS; }
+
+ public final static int SEGMENT_SIZE = 8192;
+ public final int getSegmentSize() { return SEGMENT_SIZE; }
+
+ public final static int START_STATE = 181;
+ public final int getStartState() { return START_STATE; }
+
+ public final static int IDENTIFIER_SYMBOL = 0;
+ public final int getIdentifier_SYMBOL() { return IDENTIFIER_SYMBOL; }
+
+ public final static int EOFT_SYMBOL = 96;
+ public final int getEoftSymbol() { return EOFT_SYMBOL; }
+
+ public final static int EOLT_SYMBOL = 103;
+ public final int getEoltSymbol() { return EOLT_SYMBOL; }
+
+ public final static int ACCEPT_ACTION = 482;
+ public final int getAcceptAction() { return ACCEPT_ACTION; }
+
+ public final static int ERROR_ACTION = 483;
+ public final int getErrorAction() { return ERROR_ACTION; }
+
+ public final static boolean BACKTRACK = false;
+ public final boolean getBacktrack() { return BACKTRACK; }
+
+ public final int getStartSymbol() { return lhs(0); }
+ public final boolean isValidForParser() { return PreferenceValueParsersym.isValidForParser; }
+
+
+ public interface IsNullable {
+ public final static byte isNullable[] = {0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0
+ };
+ };
+ public final static byte isNullable[] = IsNullable.isNullable;
+ public final boolean isNullable(int index) { return isNullable[index] != 0; }
+
+ public interface ProsthesesIndex {
+ public final static byte prosthesesIndex[] = {0,
+ 4,5,6,7,8,9,10,11,12,13,
+ 14,15,16,17,18,19,20,21,22,23,
+ 24,25,26,27,28,29,30,3,36,38,
+ 39,31,32,33,34,35,37,2,40,41,
+ 42,43,44,1
+ };
+ };
+ public final static byte prosthesesIndex[] = ProsthesesIndex.prosthesesIndex;
+ public final int prosthesesIndex(int index) { return prosthesesIndex[index]; }
+
+ public interface IsKeyword {
+ public final static byte isKeyword[] = {0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0
+ };
+ };
+ public final static byte isKeyword[] = IsKeyword.isKeyword;
+ public final boolean isKeyword(int index) { return isKeyword[index] != 0; }
+
+ public interface BaseCheck {
+ public final static byte baseCheck[] = {0,
+ 1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,
+ 1,2,1,1,2,1,2,1,1,2,
+ 2,2,2,5,0,2,1,1,2,2,
+ 1,1,1,2,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1
+ };
+ };
+ public final static byte baseCheck[] = BaseCheck.baseCheck;
+ public final int baseCheck(int index) { return baseCheck[index]; }
+ public final static byte rhs[] = baseCheck;
+ public final int rhs(int index) { return rhs[index]; };
+
+ public interface BaseAction {
+ public final static char baseAction[] = {
+ 38,28,28,28,28,28,28,28,28,28,
+ 28,1,1,2,2,3,3,4,4,5,
+ 5,6,6,7,7,8,8,9,9,10,
+ 10,11,11,12,12,13,13,14,14,15,
+ 15,16,16,17,17,18,18,19,19,20,
+ 20,21,21,22,22,23,23,24,24,25,
+ 25,26,26,27,27,27,27,27,27,27,
+ 27,27,27,27,27,27,27,27,27,27,
+ 27,27,27,27,27,27,27,27,27,38,
+ 38,32,32,34,33,33,36,36,35,35,
+ 35,35,35,35,29,40,40,39,41,41,
+ 41,37,37,37,30,42,42,42,31,31,
+ 31,31,31,31,31,31,31,31,31,31,
+ 31,31,31,31,31,31,31,31,31,31,
+ 31,31,31,31,31,31,31,31,43,43,
+ 43,43,43,43,43,43,43,43,43,43,
+ 43,43,43,43,43,43,43,43,43,43,
+ 43,43,43,43,43,43,43,43,43,43,
+ 43,97,63,64,65,66,67,68,69,70,
+ 71,72,73,74,75,76,77,78,79,80,
+ 81,82,83,84,85,86,87,88,111,112,
+ 96,99,113,89,90,444,341,259,98,295,
+ 97,63,64,65,66,67,68,69,70,71,
+ 72,73,74,75,76,77,78,79,80,81,
+ 82,83,84,85,86,87,88,111,112,96,
+ 99,113,89,90,444,341,259,98,106,192,
+ 63,64,65,66,67,68,69,70,71,72,
+ 73,74,75,76,77,78,79,80,81,82,
+ 83,84,85,86,87,88,111,112,97,99,
+ 113,95,501,444,341,498,98,1,63,64,
+ 65,66,67,68,69,70,71,72,73,74,
+ 75,76,77,78,79,80,81,82,83,84,
+ 85,86,87,88,115,116,499,502,483,483,
+ 483,483,327,483,483,483,483,483,483,114,
+ 117,287,63,64,65,66,67,68,69,70,
+ 71,72,73,74,75,76,77,78,79,80,
+ 81,82,83,84,85,86,87,88,101,102,
+ 483,100,103,445,63,64,65,66,67,68,
+ 69,70,71,72,73,74,75,76,77,78,
+ 79,80,81,82,83,84,85,86,87,88,
+ 108,483,483,483,483,483,483,483,483,483,
+ 483,483,292,483,415,382,63,64,65,66,
+ 67,68,69,70,71,72,73,74,75,76,
+ 77,78,79,80,81,82,83,84,85,86,
+ 87,88,109,110,500,483,483,483,483,483,
+ 483,483,483,483,483,483,483,483,483,483,
+ 483,483,483,483,483,483,483,483,483,483,
+ 483,483,483,96,483,483,483,92,483,483,
+ 259,483,483
+ };
+ };
+ public final static char baseAction[] = BaseAction.baseAction;
+ public final int baseAction(int index) { return baseAction[index]; }
+ public final static char lhs[] = baseAction;
+ public final int lhs(int index) { return lhs[index]; };
+
+ public interface TermCheck {
+ public final static byte termCheck[] = {0,
+ 0,1,2,3,4,5,6,7,8,9,
+ 10,11,12,13,14,15,16,17,18,19,
+ 20,21,22,23,24,25,26,27,28,29,
+ 30,31,32,33,34,35,36,37,38,39,
+ 40,41,42,43,44,45,46,47,48,49,
+ 50,51,52,53,54,55,56,57,58,59,
+ 60,61,62,63,64,65,66,67,68,69,
+ 70,71,72,73,74,75,76,77,78,79,
+ 80,81,82,83,84,85,86,87,88,89,
+ 90,91,92,93,94,95,0,1,2,3,
+ 4,5,6,7,8,9,10,11,12,13,
+ 14,15,16,17,18,19,20,21,22,23,
+ 24,25,26,27,28,29,30,31,32,33,
+ 34,35,36,37,38,39,40,41,42,43,
+ 44,45,46,47,48,49,50,51,52,53,
+ 54,55,56,57,58,59,60,61,62,63,
+ 64,65,66,67,68,69,70,71,72,73,
+ 74,75,76,77,78,79,80,81,82,83,
+ 84,85,86,87,88,89,90,91,92,93,
+ 94,0,1,2,3,4,5,6,7,8,
+ 9,10,11,12,13,14,15,16,17,18,
+ 19,20,21,22,23,24,25,26,27,28,
+ 29,30,31,32,33,34,35,36,37,38,
+ 39,40,41,42,43,44,45,46,47,48,
+ 49,50,51,52,53,54,55,56,57,58,
+ 59,60,61,62,63,64,65,66,67,68,
+ 69,70,71,72,73,74,75,76,77,78,
+ 79,80,81,82,83,84,85,86,87,88,
+ 89,90,91,92,93,94,0,1,2,3,
+ 4,5,6,7,8,9,10,11,12,13,
+ 14,15,16,17,18,19,20,21,22,23,
+ 24,25,26,27,28,29,30,31,32,33,
+ 34,35,36,37,38,39,40,41,42,43,
+ 44,45,46,47,48,49,50,51,52,53,
+ 54,55,56,57,58,59,60,61,62,63,
+ 64,65,66,67,68,69,70,71,72,73,
+ 74,0,76,77,78,79,80,81,82,83,
+ 84,85,86,87,88,89,90,91,92,93,
+ 94,0,1,2,3,4,5,6,7,8,
+ 9,10,11,12,13,14,15,16,17,18,
+ 19,20,21,22,23,24,25,26,27,28,
+ 29,30,31,32,33,34,35,36,37,38,
+ 39,40,41,42,43,44,45,46,47,48,
+ 49,50,51,52,53,54,55,56,57,58,
+ 59,60,61,62,0,1,2,3,4,5,
+ 6,7,8,9,10,11,12,13,14,15,
+ 16,17,18,19,20,21,22,23,24,25,
+ 26,27,28,29,30,31,32,33,34,35,
+ 36,37,38,39,40,41,42,43,44,45,
+ 46,47,48,49,50,51,52,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,64,63,0,0,0,0,0,0,
+ 0,0,0,0,75,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,96,0,0,95,0,0,0,
+ 0,0,0,0
+ };
+ };
+ public final static byte termCheck[] = TermCheck.termCheck;
+ public final int termCheck(int index) { return termCheck[index]; }
+
+ public interface TermAction {
+ public final static char termAction[] = {0,
+ 483,494,496,498,500,502,504,506,508,510,
+ 512,514,516,518,520,522,524,526,528,530,
+ 532,534,536,538,540,542,544,495,497,499,
+ 501,503,505,507,509,511,513,515,517,519,
+ 521,523,525,527,529,531,533,535,537,539,
+ 541,543,545,484,485,486,487,488,489,490,
+ 491,492,493,645,650,662,635,647,642,649,
+ 636,637,638,639,660,663,643,644,646,648,
+ 653,654,655,656,640,657,658,631,632,641,
+ 661,633,634,659,651,652,483,494,496,498,
+ 500,502,504,506,508,510,512,514,516,518,
+ 520,522,524,526,528,530,532,534,536,538,
+ 540,542,544,495,497,499,501,503,505,507,
+ 509,511,513,515,517,519,521,523,525,527,
+ 529,531,533,535,537,539,541,543,545,484,
+ 485,486,487,488,489,490,491,492,493,615,
+ 619,630,605,617,612,618,606,607,608,609,
+ 628,326,613,614,616,297,621,622,623,624,
+ 610,625,626,601,602,611,629,603,604,627,
+ 620,94,494,496,498,500,502,504,506,508,
+ 510,512,514,516,518,520,522,524,526,528,
+ 530,532,534,536,538,540,542,544,495,497,
+ 499,501,503,505,507,509,511,513,515,517,
+ 519,521,523,525,527,529,531,533,535,537,
+ 539,541,543,545,484,485,486,487,488,489,
+ 490,491,492,493,615,619,630,605,617,612,
+ 618,606,607,608,609,628,326,613,614,616,
+ 297,621,622,623,624,610,625,626,601,602,
+ 611,629,603,604,627,620,93,494,496,498,
+ 500,502,504,506,508,510,512,514,516,518,
+ 520,522,524,526,528,530,532,534,536,538,
+ 540,542,544,495,497,499,501,503,505,507,
+ 509,511,513,515,517,519,521,523,525,527,
+ 529,531,533,535,537,539,541,543,545,484,
+ 485,486,487,488,489,490,491,492,493,615,
+ 619,630,605,617,612,618,606,607,608,609,
+ 628,483,613,614,616,297,621,622,623,624,
+ 610,625,626,601,602,611,629,603,604,627,
+ 620,107,494,496,498,500,502,504,506,508,
+ 510,512,514,516,518,520,522,524,526,528,
+ 530,532,534,536,538,540,542,544,495,497,
+ 499,501,503,505,507,509,511,513,515,517,
+ 519,521,523,525,527,529,531,533,535,537,
+ 539,541,543,545,484,485,486,487,488,489,
+ 490,491,492,493,483,494,496,498,500,502,
+ 504,506,508,510,512,514,516,518,520,522,
+ 524,526,528,530,532,534,536,538,540,542,
+ 544,495,497,499,501,503,505,507,509,511,
+ 513,515,517,519,521,523,525,527,529,531,
+ 533,535,537,539,541,543,545,483,483,91,
+ 105,483,483,483,483,483,483,483,483,483,
+ 483,483,483,483,483,483,483,483,483,483,
+ 483,483,483,483,483,483,483,483,483,483,
+ 483,483,483,483,483,483,483,483,483,483,
+ 483,483,483,483,483,483,483,483,483,483,
+ 483,483,483,483,483,483,483,483,483,483,
+ 483,483,373,220,483,483,483,483,483,483,
+ 483,483,483,483,326,483,483,483,483,483,
+ 483,483,483,483,483,483,483,483,483,483,
+ 483,483,483,482,483,483,587
+ };
+ };
+ public final static char termAction[] = TermAction.termAction;
+ public final int termAction(int index) { return termAction[index]; }
+ public final int asb(int index) { return 0; }
+ public final int asr(int index) { return 0; }
+ public final int nasb(int index) { return 0; }
+ public final int nasr(int index) { return 0; }
+ public final int terminalIndex(int index) { return 0; }
+ public final int nonterminalIndex(int index) { return 0; }
+ public final int scopePrefix(int index) { return 0;}
+ public final int scopeSuffix(int index) { return 0;}
+ public final int scopeLhs(int index) { return 0;}
+ public final int scopeLa(int index) { return 0;}
+ public final int scopeStateSet(int index) { return 0;}
+ public final int scopeRhs(int index) { return 0;}
+ public final int scopeState(int index) { return 0;}
+ public final int inSymb(int index) { return 0;}
+ public final String name(int index) { return null; }
+ public final int originalState(int state) { return 0; }
+ public final int asi(int state) { return 0; }
+ public final int nasi(int state) { return 0; }
+ public final int inSymbol(int state) { return 0; }
+
+ /**
+ * assert(! goto_default);
+ */
+ public final int ntAction(int state, int sym) {
+ return baseAction[state + sym];
+ }
+
+ /**
+ * assert(! shift_default);
+ */
+ public final int tAction(int state, int sym) {
+ int i = baseAction[state],
+ k = i + sym;
+ return termAction[termCheck[k] == sym ? k : i];
+ }
+ public final int lookAhead(int la_state, int sym) {
+ int k = la_state + sym;
+ return termAction[termCheck[k] == sym ? k : la_state];
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParsersym.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParsersym.java
new file mode 100644
index 000000000..8e3dc2ceb
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferenceValueParsersym.java
@@ -0,0 +1,227 @@
+
+////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2007 IBM Corporation.
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+//Author: Robert Fuhrer (rfuhrer@watson.ibm.com)
+////////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.imp.preferences;
+
+public interface PreferenceValueParsersym {
+ public final static int
+ Char_a = 1,
+ Char_b = 2,
+ Char_c = 3,
+ Char_d = 4,
+ Char_e = 5,
+ Char_f = 6,
+ Char_g = 7,
+ Char_h = 8,
+ Char_i = 9,
+ Char_j = 10,
+ Char_k = 11,
+ Char_l = 12,
+ Char_m = 13,
+ Char_n = 14,
+ Char_o = 15,
+ Char_p = 16,
+ Char_q = 17,
+ Char_r = 18,
+ Char_s = 19,
+ Char_t = 20,
+ Char_u = 21,
+ Char_v = 22,
+ Char_w = 23,
+ Char_x = 24,
+ Char_y = 25,
+ Char_z = 26,
+ Char__ = 65,
+ Char_A = 27,
+ Char_B = 28,
+ Char_C = 29,
+ Char_D = 30,
+ Char_E = 31,
+ Char_F = 32,
+ Char_G = 33,
+ Char_H = 34,
+ Char_I = 35,
+ Char_J = 36,
+ Char_K = 37,
+ Char_L = 38,
+ Char_M = 39,
+ Char_N = 40,
+ Char_O = 41,
+ Char_P = 42,
+ Char_Q = 43,
+ Char_R = 44,
+ Char_S = 45,
+ Char_T = 46,
+ Char_U = 47,
+ Char_V = 48,
+ Char_W = 49,
+ Char_X = 50,
+ Char_Y = 51,
+ Char_Z = 52,
+ Char_0 = 53,
+ Char_1 = 54,
+ Char_2 = 55,
+ Char_3 = 56,
+ Char_4 = 57,
+ Char_5 = 58,
+ Char_6 = 59,
+ Char_7 = 60,
+ Char_8 = 61,
+ Char_9 = 62,
+ Char_DoubleQuote = 66,
+ Char_SingleQuote = 67,
+ Char_Percent = 68,
+ Char_VerticalBar = 69,
+ Char_Exclamation = 70,
+ Char_AtSign = 71,
+ Char_BackQuote = 72,
+ Char_Tilde = 73,
+ Char_Sharp = 74,
+ Char_DollarSign = 75,
+ Char_Ampersand = 76,
+ Char_Caret = 77,
+ Char_Colon = 63,
+ Char_SemiColon = 78,
+ Char_BackSlash = 79,
+ Char_LeftBrace = 64,
+ Char_RightBrace = 95,
+ Char_LeftBracket = 80,
+ Char_RightBracket = 81,
+ Char_QuestionMark = 82,
+ Char_Comma = 83,
+ Char_Dot = 84,
+ Char_LessThan = 85,
+ Char_GreaterThan = 86,
+ Char_Plus = 87,
+ Char_Minus = 88,
+ Char_Slash = 89,
+ Char_Star = 90,
+ Char_LeftParen = 91,
+ Char_RightParen = 92,
+ Char_Equal = 93,
+ Char_Space = 94,
+ Char_CtlCharNotWS = 97,
+ Char_HT = 98,
+ Char_LF = 99,
+ Char_FF = 100,
+ Char_CR = 101,
+ Char_AfterASCII = 102,
+ Char_EOF = 96;
+
+ public final static String orderedTerminalSymbols[] = {
+ "",
+ "a",
+ "b",
+ "c",
+ "d",
+ "e",
+ "f",
+ "g",
+ "h",
+ "i",
+ "j",
+ "k",
+ "l",
+ "m",
+ "n",
+ "o",
+ "p",
+ "q",
+ "r",
+ "s",
+ "t",
+ "u",
+ "v",
+ "w",
+ "x",
+ "y",
+ "z",
+ "A",
+ "B",
+ "C",
+ "D",
+ "E",
+ "F",
+ "G",
+ "H",
+ "I",
+ "J",
+ "K",
+ "L",
+ "M",
+ "N",
+ "O",
+ "P",
+ "Q",
+ "R",
+ "S",
+ "T",
+ "U",
+ "V",
+ "W",
+ "X",
+ "Y",
+ "Z",
+ "0",
+ "1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "6",
+ "7",
+ "8",
+ "9",
+ "Colon",
+ "LeftBrace",
+ "_",
+ "DoubleQuote",
+ "SingleQuote",
+ "Percent",
+ "VerticalBar",
+ "Exclamation",
+ "AtSign",
+ "BackQuote",
+ "Tilde",
+ "Sharp",
+ "DollarSign",
+ "Ampersand",
+ "Caret",
+ "SemiColon",
+ "BackSlash",
+ "LeftBracket",
+ "RightBracket",
+ "QuestionMark",
+ "Comma",
+ "Dot",
+ "LessThan",
+ "GreaterThan",
+ "Plus",
+ "Minus",
+ "Slash",
+ "Star",
+ "LeftParen",
+ "RightParen",
+ "Equal",
+ "Space",
+ "RightBrace",
+ "EOF",
+ "CtlCharNotWS",
+ "HT",
+ "LF",
+ "FF",
+ "CR",
+ "AfterASCII"
+ };
+
+ public final static int numTokenKinds = orderedTerminalSymbols.length;
+ public final static boolean isValidForParser = true;
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencesInitializer.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencesInitializer.java
new file mode 100644
index 000000000..fda37f636
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencesInitializer.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+
+public abstract class PreferencesInitializer extends AbstractPreferenceInitializer
+{
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+ */
+ public abstract void initializeDefaultPreferences();
+
+
+ /**
+ * For the given preferences level, clear the valeus of preferences that
+ * are initialized by this initializer.
+ *
+ * @param level The name of the preferences level for which preference
+ * values are to be cleared.
+ */
+ public abstract void clearPreferencesOnLevel(String level);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencesService.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencesService.java
new file mode 100644
index 000000000..4f0f85297
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencesService.java
@@ -0,0 +1,1748 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import lpg.runtime.IAst;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.preferences.ConfigurationScope;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.imp.preferences.PreferenceValueParser.ASTNode;
+import org.eclipse.imp.preferences.PreferenceValueParser.AbstractVisitor;
+import org.eclipse.imp.preferences.PreferenceValueParser.escapedChar;
+import org.eclipse.imp.preferences.PreferenceValueParser.optParameter;
+import org.eclipse.imp.preferences.PreferenceValueParser.simpleStringPrefixed;
+import org.eclipse.imp.preferences.PreferenceValueParser.substPrefixed;
+import org.eclipse.imp.preferences.PreferenceValueParser.substitution;
+import org.eclipse.imp.preferences.PreferenceValueParser.substitutionList;
+import org.osgi.framework.Bundle;
+import org.osgi.service.prefs.BackingStoreException;
+
+/**
+ * A Preferences Service for IMP. Intended as an adaptation of the
+ * Eclipse PreferencesService and built on top of it, with simplifications
+ * appropriate to use in IMP.
+ *
+ *
+ * @see org.eclipse.core.internal.PreferencesService.
+ *
+ * @author sutton
+ *
+ */
+
+public class PreferencesService implements IPreferencesService
+{
+
+ private IProject project = null;
+ private String projectName = null;
+ private String languageName = null;
+
+ org.eclipse.core.runtime.preferences.IPreferencesService preferencesService = null;
+ IEclipsePreferences preferencesRoot = null;
+
+ // Scopes at the four standard preference levels
+ // All are unique but the project scope
+ private ProjectScope projectScope = null;
+ private ConfigurationScope configurationScope = new ConfigurationScope();
+ private InstanceScope instanceScope = new InstanceScope();
+ private DefaultScope defaultScope = new DefaultScope();
+
+ /*
+ * Constructors
+ */
+
+ public PreferencesService() {
+ getPreferencesServiceAndRoot();
+ }
+
+ public PreferencesService(String projectName) {
+ this();
+ setProjectName(projectName);
+ }
+
+ public PreferencesService(IProject project) {
+ this();
+ setProject(project);
+ }
+
+ public PreferencesService(IProject project, String languageName) {
+ this(project);
+ setLanguageName(languageName);
+ }
+
+ /*
+ * Utilities for constructors and (re)initializations
+ */
+
+ private void getPreferencesServiceAndRoot() {
+ preferencesService = Platform.getPreferencesService();
+ preferencesRoot = (preferencesService != null) ? preferencesService.getRootNode() : null;
+ }
+
+ private static IProject getProjectFromName(String name) {
+ if (name == null || name.equals("")) return null;
+ IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+ IProject project = workspaceRoot.getProject(name);
+ if (project.exists()) return project;
+ return null;
+ }
+
+
+ /*
+ * Methods to get and set project, project name, and language name
+ * @see org.eclipse.imp.preferences.service.IPreferencesService#setLanguageName(java.lang.String)
+ */
+
+ // TODO: Add (or refine) error checks!
+
+ public void setLanguageName(String languageName) {
+ this.languageName = languageName;
+ }
+
+ public String getLanguageName() { return languageName; }
+
+
+ public void setProjectName(String projectName) {
+// if (projectName == null || projectName.equals("")) {
+// System.out.println("PreferencesService.setProjectName: name is null or empty; clearing project, project name, and project scope");
+// }
+ if (projectName != null && projectName.equals("")) projectName = null;
+ this.projectName = projectName;
+ project = getProjectFromName(projectName);
+ if (project != null ) {
+ ProjectScope oldProjectScope = projectScope;
+ projectScope = new ProjectScope(project);
+ toggleProject(oldProjectScope, projectScope, projectName);
+ }
+
+ else projectScope = null;
+ }
+
+
+ private void toggleProject(ProjectScope oldProjectScope, ProjectScope newProjectScope, String projectName)
+ {
+ ProjectSelectionEvent event = null;
+ if (projectName == null)
+ event = new ProjectSelectionEvent(null, null);
+ else if (oldProjectScope == null && newProjectScope == null)
+ event = new ProjectSelectionEvent(null, null);
+ else if (oldProjectScope == null && newProjectScope != null)
+ event = new ProjectSelectionEvent(null, newProjectScope.getNode(projectName));
+ else if (oldProjectScope != null && newProjectScope == null)
+ event = new ProjectSelectionEvent(oldProjectScope.getNode(projectName), null);
+ else if (oldProjectScope != null && newProjectScope != null)
+ event = new ProjectSelectionEvent(oldProjectScope.getNode(projectName), newProjectScope.getNode(projectName));
+
+ // so now event should be defined ...
+
+ fireProjectSelectionEvent(event);
+
+ }
+
+
+ public String getProjectName() { return projectName; }
+
+
+ public void setProject(IProject project)
+ {
+ ProjectScope oldProjectScope = projectScope;
+ this.project = project;
+ if (project != null) {
+ projectName = project.getName();
+ // oldProjectScope = projectScope;
+ projectScope = new ProjectScope(project);
+ //toggleProject(oldProjectScope, projectScope, projectName);
+ } else {
+ //System.out.println("PreferencesService.setProject: project is null; clearing project, project name, and project scope");
+ projectName = null;
+ projectScope = null;
+ }
+ toggleProject(oldProjectScope, projectScope, projectName);
+ }
+
+
+ public IProject getProject() { return project; }
+
+
+
+ /*
+ * Get and set preferences by batch by level
+ */
+
+ public IEclipsePreferences getPreferences(String level)
+ {
+ if (level == null) {
+ throw new IllegalArgumentException("PreferencesService.getPreferences: given level is null");
+ }
+ if (!isaPreferencesLevel(level)) {
+ throw new IllegalArgumentException("PreferencesService.getPreferences: given level is not valid (level = " + level);
+ }
+
+ IEclipsePreferences preferences = null;
+
+ if (level.equals(PROJECT_LEVEL)) {
+ if (projectScope != null && languageName != null) {
+ preferences = projectScope.getNode(languageName);
+ }
+ } else if (level.equals(INSTANCE_LEVEL)) {
+ preferences = instanceScope.getNode(languageName);
+ } else if (level.equals(CONFIGURATION_LEVEL)) {
+ preferences = configurationScope.getNode(languageName);
+ } else if (level.equals(DEFAULT_LEVEL)) {
+ preferences = defaultScope.getNode(languageName);
+ }
+
+ return preferences;
+ }
+
+
+ /**
+ * Set the preferences at the given level to the given new preferences,
+ * clearing any existing preferences. If the new preferences are null,
+ * just clear the existing preferences.
+ *
+ * @param level the level at which preferences are to be set; must be
+ * one of the values defined in IPreferencesService
+ * @param newPreferences the new preferences to be set at the given level (or
+ * null if the existing preferences are just to be cleared)
+ * @throws IllegalArgumentException
+ * if the given level is null or not one of the values
+ * defined in IPreferencesService
+ */
+ public void setPreferences(String level, IEclipsePreferences newPreferences)
+ {
+ if (level == null) {
+ throw new IllegalArgumentException(
+ "PreferencesService.getPreferences: given level is null");
+ }
+ if (!isaPreferencesLevel(level)) {
+ throw new IllegalArgumentException(
+ "PreferencesService.getPreferences: given level is not valid (level = " + level);
+ }
+
+ IEclipsePreferences node = clearPreferencesAtLevel(level);
+
+ if (newPreferences == null) return;
+
+ String[] keys = null;
+ try {
+ keys = newPreferences.keys();
+ } catch (BackingStoreException e) {
+ System.out.println("PreferencesService.setPreferences(): " +
+ "BackingStoreException getting keys; returning (note: preferences for this node may have been cleared)");
+ return;
+ }
+ for (int i = 0; i < keys.length; i++) {
+ // Assume that if we get values out they're legal, and
+ // and that if they're legal we can safely put them in
+ String val = newPreferences.get(keys[i], null);
+ node.put(keys[i], val);
+ }
+ try {
+ node.flush();
+ } catch (BackingStoreException e) {
+ System.out.println("PreferencesService.setPreferences(): " +
+ "BackingStoreException flushing new preferences; returning (note: preferences for this node may have been cleared and not set)");
+ return;
+ }
+
+ }
+
+
+ /*
+ * Documentatry interlude:
+ *
+ * The methods to get an applicable preference by type make use of the corresponding
+ * type-specific "get" methods in the Eclipse PreferencesService. Those methods take
+ * a qualifier (i.e., that designates a name space), a key, a default value, and
+ * a (possibly empty) list of scope contexts to be checked ahead of the standard
+ * contexts that are automatically checked in the standard order (project, instance,
+ * configuration, and default).
+ *
+ * Recall that, while the PreferencesService allows preference values to be gotten,
+ * it provides no way to set preference values. The setting of preference values
+ * has to be done through preference nodes that are associated with scope contexts.
+ *
+ * We would like to be able to use a single qualifier to get the preferences for
+ * a particular language (e.g., qualifier "X10" for language X10). When we set
+ * a preference at a level, we can provide just such a simple qualifier since
+ * we know the language name, e.g., in
+ * setIntPreference(String level, String key, int value)
+ * we can get the scope for the level, get the preferences node for the language-
+ * name qualifier, and set the value in the node. That's simple. If the level
+ * is (for example) "instance", then the path to the target preference node in the
+ * preferences model is
+ * /root/instance/<languageName>
+ * but if the level is "project" then the path to the target preference node is
+ * /root/project/<projectName>/<languageName>
+ * However, when you retrieve the preference from the Eclipse PreferencesService
+ * using the language name as qualifier and the appropriate key, the service
+ * will search on the project level for
+ * /root/project/<languageName>
+ * In other words, the project is not taken into account by the service and that
+ * level is ignored in the preferences model.
+ *
+ * The Eclipse PreferencesService can accommodate project names as part of the
+ * qualifier. So, given a preference stored in the project node as above, it
+ * can be retrieved using <projectName>/<languageName> as the qualifer. This leads
+ * the service to search the preferences model along the path
+ * root/project/<projectName>/<languageName>
+ * where it will be found. However, if you add the project name to the language
+ * name in the qualifier on the other preferences levels, that will lead to
+ * searching on paths like
+ * /root/instance/<projectName>/<languageName>
+ * which is not how the preferences would have been stored on the other levels
+ * if the qualifier was just the language name.
+ *
+ * It's possible to use the project name as part of the qualifier at the instance,
+ * configuration, and default levels. That would allow the same qualifier to be
+ * used at all levels. However, that would result, in effect, in project-specific
+ * preferences at levels that are supposed to be project independent. It would
+ * also complicate the setting of preferences, which, at the project-independent
+ * levels, would have to be done consistently for each project where a language
+ * is used rather than just once for all projects where a language is used.
+ *
+ * Alternatively, it's possible to use different qualifiers at the projec level
+ * and project-independent levels, but that complicates the use of the preferences
+ * service, requiring clients to query for preferences using different qualifiers
+ * in different cases.
+ *
+ * To keep things simple for clients, I've taken advantage of the ability to
+ * provide the Eclipse PreferencesService with scopes to be searched ahead of
+ * the standard scopes. That is, each of the type-specific "get" methods defined
+ * here calls the corresponding Eclipse-service get methdod, providing it with
+ * the project-specific scope in which the simple language-name qualifier will
+ * be recognized. Users can thus use the language name as a qualifier that will
+ * be meaningful across all scope levels. They will not have to worry about whether
+ * different qualifiers are needed on different levels and whether the project name
+ * should or should not be part of a qualifier.
+ */
+
+
+ /*
+ * Get applicable preferences by type
+ */
+
+ private IScopeContext[] specificProjectScope() {
+ if (projectScope == null) return new IScopeContext[0];
+ return new IScopeContext[] { getScopeForLevel(IPreferencesService.PROJECT_LEVEL)};
+ }
+
+
+ public boolean getBooleanPreference(String key) {
+ return preferencesService.getBoolean(languageName, key, false, specificProjectScope());
+ }
+
+ /*
+ * The implementation of the "get" method for byte arrays is more complicated
+ * than for other types due to the way in which the preferences nodes encode
+ * byte arrays while the preferences service ignores encoding.
+ *
+ * Things considered in this implementation:
+ * - Byte arrays are encoded when written to a preferences node and
+ * decoded when read from the node but not from the Eclipse Preferences
+ * Service; that is addressed here by getting the value from the
+ * preferences node rather than from the preferences service
+ * - The IMP Preferences Service and the Eclipse Preferences Service
+ * both have the same four standard levels and these are by default
+ * in the same standard order
+ * - But the Eclipse levels may have been reordered (although I'm not
+ * doing that), so this implementation does not assume that they're
+ * in the same order
+ * - The levels are named in different ways in the two services, e.g.,
+ * "project" in Eclipse and "PROJECT_LEVEL" in IMP, so that has to
+ * be accommodated
+ * Things not considered:
+ * - Additional levels that may have been added to the preferences model
+ * (but I'm certainly not adding any!)
+ *
+ * @see org.eclipse.imp.preferences.service.IPreferencesService#getByteArrayPreference(java.lang.String)
+ */
+ public byte[] getByteArrayPreference(String key)
+ {
+ byte[] result = null;
+ String[] lookupOrder = preferencesService.getLookupOrder(languageName, key);
+ String[] levels = IPreferencesService.levels;
+ outer: for (int i = 0; i < lookupOrder.length; i++) {
+ for (int j = 0; j < levels.length; j++) {
+ String level = null;
+ if (levels[j].startsWith(lookupOrder[i].toUpperCase())) {
+ level = levels[j];
+ IScopeContext context = getScopeForLevel(level);
+ IEclipsePreferences node = context.getNode(languageName);
+ result = node.getByteArray(key, new byte[0]);
+ if (result.length == 0) continue;
+ break outer;
+ }
+ }
+ }
+ return result;
+ }
+
+ public double getDoublePreference(String key) {
+ return preferencesService.getDouble(languageName, key, 0, specificProjectScope());
+ }
+
+ public float getFloatPreference(String key) {
+ return preferencesService.getFloat(languageName, key, 0, specificProjectScope());
+ }
+
+ public int getIntPreference(String key) {
+ return preferencesService.getInt(languageName, key, 0, specificProjectScope());
+ }
+
+ public long getLongPreference(String key) {
+ return preferencesService.getLong(languageName, key, 0, specificProjectScope());
+ }
+
+ public String getStringPreference(String key) {
+ String result = preferencesService.getString(languageName, key, null, specificProjectScope());
+ //if (result.equals("")) {
+ // result = null;
+ //}
+ return performSubstitutions(result);
+ }
+
+
+ public String getRawStringPreference(String key) {
+ String result = preferencesService.getString(languageName, key, null, specificProjectScope());
+ return result;
+ }
+
+ /*
+ * Get applicable preferences by project and type
+ *
+ * Requests are evaluated relative to an implicit "current language."
+ * It is an error to request a preference when the current langauge is
+ * not defined, because all preferences are assumed to be defined relative
+ * to some language.
+ *
+ * Requests are evaluated relative to a given project, regardless of
+ * whether there is a "current project" defined.
+ *
+ * Preferences are returned from the lowest level at which set. If no
+ * preference is defined for a given key at all levels, then an apporpriate
+ * default value is returned. This is 0 for the numeric preferences,
+ * false for boolean preferences, the empty string for String preferences,
+ * and the empty array for byte[].
+ */
+
+ public boolean getBooleanPreference(IProject project, String key)
+ {
+ return preferencesService.getBoolean(languageName, key, false, new IScopeContext[] { new ProjectScope(project) } );
+ }
+
+
+ /*
+ * This is more complicated than retrieving values for the other types because of
+ * the encoding that is done (or not done) differently between the preferences service
+ * and preferences nodes. See the version of getByteArrayPreference(..) that only takes
+ * a key for more detailed comments.
+ *
+ * @see org.eclipse.imp.preferences.IPreferencesService#getByteArrayPreference(org.eclipse.core.resources.IProject, java.lang.String)
+ */
+ public byte[] getByteArrayPreference(IProject project, String key)
+ {
+ byte[] result = null;
+ String[] lookupOrder = preferencesService.getLookupOrder(languageName, key);
+ String[] levels = IPreferencesService.levels;
+ outer: for (int i = 0; i < lookupOrder.length; i++) {
+ for (int j = 0; j < levels.length; j++) {
+ String level = null;
+ if (levels[j].startsWith(lookupOrder[i].toUpperCase())) {
+ level = levels[j];
+ IScopeContext context = null;
+ if (level.equals(PROJECT_LEVEL)) {
+ context = getScopeForProject(project);
+ } else {
+ context = getScopeForLevel(level);
+ }
+ IEclipsePreferences node = context.getNode(languageName);
+ result = node.getByteArray(key, new byte[0]);
+ if (result.length == 0) continue;
+ break outer;
+ }
+ }
+ }
+ return result;
+ }
+
+
+ public double getDoublePreference(IProject project, String key) {
+ return preferencesService.getDouble(languageName, key, 0, new IScopeContext[] { new ProjectScope(project) } );
+ }
+
+ public float getFloatPreference(IProject project, String key) {
+ return preferencesService.getFloat(languageName, key, 0, new IScopeContext[] { new ProjectScope(project) });
+ }
+
+ public int getIntPreference(IProject project, String key) {
+ return preferencesService.getInt(languageName, key, 0, new IScopeContext[] { new ProjectScope(project) });
+ }
+
+ public long getLongPreference(IProject project, String key) {
+ return preferencesService.getLong(languageName, key, 0, new IScopeContext[] { new ProjectScope(project) } );
+ }
+
+ public String getRawStringPreference(IProject project, String key) {
+ return preferencesService.getString(languageName, key, null, new IScopeContext[] { new ProjectScope(project) } );
+ }
+
+ public String getStringPreference(IProject project, String key) {
+ String value= getRawStringPreference(project, key);
+ String result= performSubstitutions(value, project);
+
+ return result;
+ }
+
+ /**
+ * An evaluator for non-parameterized (constant) references.
+ */
+ private interface ConstantEvaluator {
+ String getValue();
+ }
+
+ private static final Map<String,ConstantEvaluator> sConstantMap= new HashMap<String, ConstantEvaluator>();
+
+ static {
+ sConstantMap.put("workspaceLoc", new ConstantEvaluator() {
+ public String getValue() {
+ return ResourcesPlugin.getWorkspace().getRoot().getLocation().toPortableString();
+ }
+ });
+ sConstantMap.put("os", new ConstantEvaluator() {
+ public String getValue() {
+ return Platform.getOS();
+ }
+ });
+ sConstantMap.put("arch", new ConstantEvaluator() {
+ public String getValue() {
+ return Platform.getOSArch();
+ }
+ });
+ sConstantMap.put("nl", new ConstantEvaluator() {
+ public String getValue() {
+ return Platform.getNL();
+ }
+ });
+ sConstantMap.put("ws", new ConstantEvaluator() {
+ public String getValue() {
+ return Platform.getWS();
+ }
+ });
+ }
+
+ /**
+ * An evaluator for parameterized value references.
+ */
+ private interface ParamEvaluator {
+ String getValue(String param);
+ }
+
+ private static final Map<String,ParamEvaluator> sParamMap= new HashMap<String, ParamEvaluator>();
+
+ static {
+ sParamMap.put("pluginLoc", new ParamEvaluator() {
+ public String getValue(String pluginID) {
+ Bundle bundle= Platform.getBundle(pluginID);
+ if (bundle == null) {
+ return "<no such plugin: " + pluginID + ">";
+ }
+ try {
+ String bundleLoc= FileLocator.toFileURL(bundle.getEntry("")).getFile();
+ return bundleLoc;
+ } catch (IOException e) {
+ return "<error determining location of plugin: " + pluginID + ">";
+ }
+// Bundle[] fragments= Platform.getFragments(bundle);
+ }
+ });
+ sParamMap.put("pluginResource", new ParamEvaluator() {
+ public String getValue(String pluginResourceLoc) {
+ int idx= pluginResourceLoc.indexOf('/');
+ if (idx <= 0) {
+ return "<error in pluginResource specification: no plugin ID found: " + pluginResourceLoc + ">";
+ }
+ String pluginID= pluginResourceLoc.substring(0, idx);
+ String resourcePath= pluginResourceLoc.substring(idx+1);
+ Bundle bundle= Platform.getBundle(pluginID);
+ if (bundle == null) {
+ return "<no such plugin: " + pluginID + ">";
+ }
+ try {
+ URL resourceEntry= bundle.getEntry(resourcePath);
+ if (resourceEntry == null) {
+ Bundle[] fragments= Platform.getFragments(bundle);
+ if (fragments != null) {
+ for(int i= 0; i < fragments.length; i++) {
+ Bundle bundleFrag= fragments[i];
+ resourceEntry= bundleFrag.getEntry(resourcePath);
+ if (resourceEntry != null) {
+ break;
+ }
+ }
+ }
+ }
+ if (resourceEntry == null) {
+ return "<error: no resource '" + resourcePath + "' in plugin " + pluginID + " or its fragments>";
+ }
+ String resourceLoc= FileLocator.toFileURL(resourceEntry).getFile();
+ // RMF 3/17/2009 Make sure the path is really a valid one: toFileURL().getFile()
+ // for some reason sometimes produces invalid paths like "/C:/..." on Win32.
+ // Passing this through Path.toPortableString() seems to address the problem.
+ resourceLoc= new Path(resourceLoc).toPortableString();
+ return resourceLoc;
+ } catch (IOException e) {
+ return "<error determining location of plugin: " + pluginID + ">";
+ }
+ }
+ });
+ sParamMap.put("pluginVersion", new ParamEvaluator() {
+ public String getValue(String pluginID) {
+ Bundle bundle= Platform.getBundle(pluginID);
+ if (bundle == null) {
+ return "<no such plugin: " + pluginID + ">";
+ }
+ return (String) bundle.getHeaders().get("Bundle-Version");
+ }
+ });
+ sParamMap.put("projectLoc", new ParamEvaluator() {
+ public String getValue(String projectName) {
+ IProject project= getProjectFromName(projectName);
+ if (project == null) {
+ return "<no such project: " + projectName + ">";
+ }
+ return project.getLocation().toPortableString();
+ }
+ });
+ }
+
+ private static void initializeForTesting() {
+ sConstantMap.clear();
+ sConstantMap.put("workspaceLoc", new ConstantEvaluator() {
+ public String getValue() {
+ return "~/eclipse/workspace";
+ }
+ });
+ sConstantMap.put("os", new ConstantEvaluator() {
+ public String getValue() {
+ return "macosx";
+ }
+ });
+ sConstantMap.put("arch", new ConstantEvaluator() {
+ public String getValue() {
+ return "x86";
+ }
+ });
+ sConstantMap.put("nl", new ConstantEvaluator() {
+ public String getValue() {
+ return "enUS";
+ }
+ });
+ sConstantMap.put("ws", new ConstantEvaluator() {
+ public String getValue() {
+ return "mac";
+ }
+ });
+ sParamMap.clear();
+ sParamMap.put("pluginLoc", new ParamEvaluator() {
+ public String getValue(String pluginID) {
+ return "/System/Library/eclipse-3.3.2/plugins/" + pluginID;
+ }
+ });
+ sParamMap.put("pluginResource", new ParamEvaluator() {
+ public String getValue(String pluginResourceLoc) {
+ int idx= pluginResourceLoc.indexOf('/');
+ if (idx <= 0) {
+ return "<error in pluginResource specification: no plugin ID found: " + pluginResourceLoc + ">";
+ }
+ String pluginID= pluginResourceLoc.substring(0, idx);
+ String resourcePath= pluginResourceLoc.substring(idx+1);
+ return "/System/Library/eclipse-3.3.2/plugins/" + pluginID + "/" + resourcePath;
+ }
+ });
+ sParamMap.put("pluginVersion", new ParamEvaluator() {
+ public String getValue(String pluginID) {
+ return "1.0.0";
+ }
+ });
+ sParamMap.put("projectLoc", new ParamEvaluator() {
+ public String getValue(String projectName) {
+ return "~/eclipse/workspace/" + projectName;
+ }
+ });
+ }
+
+ public static void main(String args[]) {
+ initializeForTesting();
+ PreferencesService svc= new PreferencesService();
+ String[][] testPairs= new String[][] {
+ { "foo", "foo", },
+ { "${os}", "macosx" },
+ { "foo-${os}", "foo-macosx" },
+ { "${os}-bar", "macosx-bar" },
+ { "foo-${os}-bar", "foo-macosx-bar" },
+ { "${os}-${arch}", "macosx-x86" },
+ { "${os}${arch}", "macosxx86" },
+
+ { "${projectLoc:foo}", "~/eclipse/workspace/foo" },
+ { "${pluginResource:lpg.runtime/templates}", "/System/Library/eclipse-3.3.2/plugins/lpg.runtime/templates" },
+ { "${pluginResource:lpg.runtime/lpgexe/lpg-${os}_${arch}.exe}", "/System/Library/eclipse-3.3.2/plugins/lpg.runtime/lpgexe/lpg-macosx_x86.exe" },
+
+ { "\\$", "$" },
+ { "\\$abc", "$abc" },
+ { "\\$\\$", "$$" },
+ { "\\${blah\\}", "${blah}" },
+ { "\\a", "a" },
+ { "\\a\\b", "ab" },
+ { "\\a-\\b", "a-b" },
+
+ { "${blah", "Invalid preference: '${blah': unexpected end of string" },
+ { "$blah}", "Invalid preference: '$blah}': unexpected character 'b' at offset 1" },
+ { "${}", "Invalid preference: '${}': unexpected character '}' at offset 2" },
+ { "$", "Invalid preference: '$': unexpected end of string" },
+ };
+ int failedCount= 0;
+
+ for(int i= 0; i < testPairs.length; i++) {
+ String input= testPairs[i][0];
+ String expectedOutput= testPairs[i][1];
+ String result= svc.performSubstitutions(input);
+
+ System.out.println("Input = '" + input + "'");
+ System.out.println("Result = '" + result + "'");
+ if (!expectedOutput.equals(result)) {
+ System.err.println("Test failed: expected output '" + expectedOutput + "'!");
+ failedCount++;
+ } else {
+ System.out.println("Test passed.");
+ }
+ System.out.println();
+ }
+ if (failedCount > 0) {
+ System.err.println("" + failedCount + " tests failed.");
+ }
+ }
+
+ public String performSubstitutions(String value) {
+ return performSubstitutions(value, null);
+ }
+
+ public String performSubstitutions(final String value, final IProject project) {
+ if (value == null || value.length() == 0) {
+ return value;
+ }
+ PreferenceValueParser parser= new PreferenceValueParser();
+
+ ASTNode ast= parser.parser(value);
+
+ if (ast == null) { return "Invalid preference: '" + value + "': " + parser.getErrorMessage(); }
+
+ final Map<IAst,String> valueMap= new HashMap<IAst, String>();
+
+ ast.accept(new AbstractVisitor() {
+ public void postVisit(IAst node) {
+// System.out.println("post-visiting node '" + node + "'");
+ if (node instanceof escapedChar) {
+ escapedChar ch= (escapedChar) node;
+ String nodeStr= nodeString(ch);
+
+ if (nodeStr.charAt(1) == '$') {
+ valueMap.put(node, nodeStr.substring(1));
+ } else {
+ valueMap.put(node, nodeStr);
+ }
+ } else if (node instanceof simpleStringPrefixed) {
+ simpleStringPrefixed strPref= (simpleStringPrefixed) node;
+ String valString= nodeString((ASTNode) strPref.getvalStringNoSubst());
+
+ valString= valString.replaceAll("\\\\\\$", "$").replace("\\\\}", "}");
+ if (strPref.getsubstPrefixed() != null) {
+ String result= valString + valueMap.get(strPref.getsubstPrefixed());
+ valueMap.put(node, result);
+ } else {
+ valueMap.put(node, valString);
+ }
+ } else if (node instanceof substPrefixed) {
+ substPrefixed subPref= (substPrefixed) node;
+
+ if (subPref.getsimpleStringPrefixed() != null) {
+ String result= valueMap.get(subPref.getsubstitutionList()) + valueMap.get(subPref.getsimpleStringPrefixed());
+ valueMap.put(node, result);
+ } else {
+ valueMap.put(node, valueMap.get(subPref.getsubstitutionList()));
+ }
+ } else if (node instanceof substitutionList) {
+ substitutionList subList= (substitutionList) node;
+ StringBuilder sb= new StringBuilder();
+
+ for(int i=0; i < subList.size(); i++) {
+ sb.append(valueMap.get(subList.getsubstitutionAt(i)));
+ }
+ valueMap.put(node, sb.toString());
+ } else if (node instanceof substitution) {
+ substitution sub= (substitution) node;
+ String id= nodeString(sub.getident());
+ optParameter parm= sub.getoptParameter();
+
+ if (parm != null) {
+ ParamEvaluator e= sParamMap.get(id);
+ String parmStr= valueMap.get(parm.getvalue());
+ String parmVal= (e != null) ? e.getValue(parmStr) : ("<no such preference: " + id + ">");
+
+ valueMap.put(node, parmVal);
+ } else {
+ if (sConstantMap.containsKey(id)) {
+ String constVal= sConstantMap.get(id).getValue();
+ valueMap.put(node, constVal);
+ } else {
+ String refVal= (project != null) ? getStringPreference(project, id) : getStringPreference(id);
+ valueMap.put(node, refVal);
+ }
+ }
+ }
+ }
+ public boolean preVisit(IAst element) {
+ return true;
+ }
+ private String nodeString(ASTNode node) {
+ return value.substring(node.leftIToken.getStartOffset(), node.rightIToken.getEndOffset()+1);
+ }
+ @Override
+ public void unimplementedVisitor(String s) { }
+ });
+ String result= valueMap.get(ast);
+ return result;
+ }
+
+ /*
+ * Get preferences at a given level by type
+ */
+
+ // SMS 19 Sep 2006: Are these all wrong????
+
+ public boolean getBooleanPreference(String level, String key) {
+ //return preferencesService.getBoolean(languageName, key, false, new IScopeContext[] { getScopeForLevel(level)} );
+ IScopeContext scope = getScopeForLevel(level);
+ IEclipsePreferences node = scope.getNode(languageName);
+ boolean result = node.getBoolean(key, false);
+ return result;
+ }
+
+ public byte[] getByteArrayPreference(String level, String key) {
+ // SMS 19 Sep 2006: The following comment is now somewhat outdated in that
+ // direct access to the preferences nodes is used in all of the methods in this
+ // group, but the comment may still be informative with respect to particular
+ // issues that affect byte arrays.
+ //
+ // Why do the following instead of getting the value directly from the preferences service
+ // as is done with the other preferences types? Note that, while values are retrieved here
+ // from the preferences service, values are set through the preferences nodes for the individual
+ // scope contexts. (That is because the preferences service allows preferences to be retrieved
+ // directly but not set directly.) Also recall that all preferences are stored interanlly as
+ // Strings. When a byte array is set or retrieved through a preferences context, the byte
+ // array is encoded as a Base64 String. However, when a byte array is retrieved from the
+ // preferences service, it is just converted to a string in the "native" representation
+ // (that is, without regard to any specific encoding). Apparently the native encoding is not
+ // always Base64. Consequently, a byte array may be stored through the preferences node in
+ // one representation retrieved from the preferences service in another representation, so
+ // from the client's perspective the values stored and retrieved may be different. Since we
+ // elsewhere store byte array preferences through the node we retrieve them here from the node.
+ IScopeContext context = getScopeForLevel(level);
+ IEclipsePreferences node = context.getNode(languageName);
+ byte[] result = node.getByteArray(key, new byte[0]);
+ return result;
+ }
+
+ public double getDoublePreference(String level, String key) {
+ //return preferencesService.getDouble(languageName, key, 0, new IScopeContext[] { getScopeForLevel(level)} );
+ IScopeContext scope = getScopeForLevel(level);
+ IEclipsePreferences node = scope.getNode(languageName);
+ double result = node.getDouble(key, 0);
+ return result;
+ }
+
+ public float getFloatPreference(String level, String key) {
+ //return preferencesService.getFloat(languageName, key, 0, new IScopeContext[] { getScopeForLevel(level)} );
+ IScopeContext scope = getScopeForLevel(level);
+ IEclipsePreferences node = scope.getNode(languageName);
+ float result = node.getFloat(key, 0);
+ return result;
+ }
+
+ public int getIntPreference(String level, String key) {
+ //return preferencesService.getInt(languageName, key, 0, new IScopeContext[] { getScopeForLevel(level)} );
+ IScopeContext scope = getScopeForLevel(level);
+ IEclipsePreferences node = scope.getNode(languageName);
+ int result = node.getInt(key, 0);
+ return result;
+ }
+
+ public long getLongPreference(String level, String key) {
+ //return preferencesService.getLong(languageName, key, 0, new IScopeContext[] { getScopeForLevel(level)} );
+ IScopeContext scope = getScopeForLevel(level);
+ IEclipsePreferences node = scope.getNode(languageName);
+ long result = node.getLong(key, 0);
+ return result;
+ }
+
+ public String getStringPreference(String level, String key) {
+ /*
+ if (!isaPreferencesLevel(level)) return null;
+ String[] previousLevels = preferencesService.getDefaultLookupOrder(languageName, key);
+ String[] newLevels = new String[4];
+ for (int i = 0; i < newLevels.length; i++) {
+ newLevels[i] = level;
+ }
+ preferencesService.setDefaultLookupOrder(languageName, key, newLevels);
+ String result = preferencesService.getString(languageName, key, null, new IScopeContext[] { getScopeForLevel(level)} );
+ preferencesService.setDefaultLookupOrder(languageName, key, previousLevels);
+ // SMS 8 Sep 2006: leftover from debugging
+ if (result != null && result.equals("")) {
+ result = null;
+ result = "";
+ }
+ return result;
+ */
+ IScopeContext scope = getScopeForLevel(level);
+ IEclipsePreferences node = scope.getNode(languageName);
+ String result = node.get(key, null);
+ return performSubstitutions(result);
+ }
+
+
+ /*
+ * Return the "raw" (unsubstituted) version of the preference value.
+ * Needed at least by field editors that may want to inherit a raw
+ * value from a higher level.
+ * SMS 21 Feb 2008
+ */
+ public String getRawStringPreference(String level, String key) {
+ IScopeContext scope = getScopeForLevel(level);
+ IEclipsePreferences node = scope.getNode(languageName);
+ String result = node.get(key, null);
+ return result;
+ }
+
+
+
+ /*
+ * Get preferences for a given project by type
+ *
+ * Requests are evaluated relative to an implicit "current language."
+ * It is an error to request a preference when the current langauge is
+ * not defined, because all preferences are assumed to be defined relative
+ * to some language.
+ *
+ * Requests are evaluated relative to the given project only. If a
+ * preference for the given key is defined for that project, then the
+ * associated value is returned. If no preferences is defined
+ * for the given key in the given project, then a suitable default value
+ * is returned. This is 0 for the numeric preferences, false for boolean
+ * preferences, the null string for String preferences, and the empty
+ * array for byte[].
+ */
+ public boolean getBooleanPreferenceForProject(IProject project, String key) {
+ IScopeContext scope = getScopeForProject(project);
+ IEclipsePreferences node = scope.getNode(languageName);
+ boolean result = node.getBoolean(key, false);
+ return result;
+ }
+
+
+ public byte[] getByteArrayPreferenceForProject(IProject project, String key) {
+ IScopeContext scope = getScopeForProject(project);
+ IEclipsePreferences node = scope.getNode(languageName);
+ byte[] result = node.getByteArray(key, new byte[0]);
+ return result;
+ }
+
+
+ public double getDoublePreferenceForProject(IProject project, String key) {
+ IScopeContext scope = getScopeForProject(project);
+ IEclipsePreferences node = scope.getNode(languageName);
+ double result = node.getDouble(key, 0);
+ return result;
+ }
+
+
+ public float getFloatPreferenceForProject(IProject project, String key) {
+ IScopeContext scope = getScopeForProject(project);
+ IEclipsePreferences node = scope.getNode(languageName);
+ float result = node.getFloat(key, 0);
+ return result;
+ }
+
+
+ public int getIntPreferenceForProject(IProject project, String key) {
+ IScopeContext scope = getScopeForProject(project);
+ IEclipsePreferences node = scope.getNode(languageName);
+ int result = node.getInt(key, 0);
+ return result;
+ }
+
+
+ public long getLongPreferenceForProject(IProject project, String key) {
+ IScopeContext scope = getScopeForProject(project);
+ IEclipsePreferences node = scope.getNode(languageName);
+ long result = node.getLong(key, 0);
+ return result;
+ }
+
+
+ public String getStringPreferenceForProject(IProject project, String key) {
+ IScopeContext scope = getScopeForProject(project);
+ IEclipsePreferences node = scope.getNode(languageName);
+ String result = node.get(key, null);
+ return performSubstitutions(result, project);
+ }
+
+
+
+ public String getRawStringPreferenceForProject(IProject project, String key) {
+ IScopeContext scope = getScopeForProject(project);
+ IEclipsePreferences node = scope.getNode(languageName);
+ String result = node.get(key, null);
+ return result;
+ }
+
+
+
+ /*
+ * Set preferences at a given level by type
+ */
+
+ public void setBooleanPreference(String level, String key, boolean value) {
+ IScopeContext scope = getScopeForLevel(level);
+ IEclipsePreferences node = scope.getNode(languageName);
+ node.putBoolean(key, value);
+ try {
+ node.flush();
+ } catch (BackingStoreException e) {
+ System.out.println("PreferencesService.setByteArrayPreference(String, String, boolean): BackingStoreException");
+ System.out.println("\tlevel = " + level + "; key = " + key + "; value = " + value);
+ }
+ }
+
+ public void setByteArrayPreference(String level, String key, byte[] value) {
+ IScopeContext scope = getScopeForLevel(level);
+ IEclipsePreferences node = scope.getNode(languageName);
+ node.putByteArray(key, value);
+ try {
+ node.flush();
+ } catch (BackingStoreException e) {
+ System.out.println("PreferencesService.setByteArrayPreference(String, String, byte[]): BackingStoreException");
+ System.out.println("\tlevel = " + level + "; key = " + key + "; value = " + value);
+ }
+ }
+
+ public void setDoublePreference(String level, String key, double value) {
+ IScopeContext scope = getScopeForLevel(level);
+ IEclipsePreferences node = scope.getNode(languageName);
+ node.putDouble(key, value);
+ try {
+ node.flush();
+ } catch (BackingStoreException e) {
+ System.out.println("PreferencesService.setDoublePreference(String, String, double): BackingStoreException");
+ System.out.println("\tlevel = " + level + "; key = " + key + "; value = " + value);
+ }
+ }
+
+ public void setFloatPreference(String level, String key, float value) {
+ IScopeContext scope = getScopeForLevel(level);
+ IEclipsePreferences node = scope.getNode(languageName);
+ node.putFloat(key, value);
+ try {
+ node.flush();
+ } catch (BackingStoreException e) {
+ System.out.println("PreferencesService.setFloatPreference(String, String, float): BackingStoreException");
+ System.out.println("\tlevel = " + level + "; key = " + key + "; value = " + value);
+ }
+ }
+
+ public void setIntPreference(String level, String key, int value) {
+ IScopeContext scope = getScopeForLevel(level);
+ IEclipsePreferences node = scope.getNode(languageName);
+ node.putInt(key, value);
+ try {
+ node.flush();
+ } catch (BackingStoreException e) {
+ System.out.println("PreferencesService.setIntPreference(String, String, int): BackingStoreException");
+ System.out.println("\tlevel = " + level + "; key = " + key + "; value = " + value);
+ }
+ }
+
+ public void setLongPreference(String level, String key, long value) {
+ IScopeContext scope = getScopeForLevel(level);
+ IEclipsePreferences node = scope.getNode(languageName);
+ node.putLong(key, value);
+ try {
+ node.flush();
+ } catch (BackingStoreException e) {
+ System.out.println("PreferencesService.set LongPreference(String, String, long): BackingStoreException");
+ System.out.println("\tlevel = " + level + "; key = " + key + "; value = " + value);
+ }
+ }
+
+ public void setStringPreference(String level, String key, String value) {
+ IScopeContext scope = getScopeForLevel(level);
+ IEclipsePreferences node = scope.getNode(languageName);
+ node.put(key, value);
+ try {
+ node.flush();
+ } catch (BackingStoreException e) {
+ System.out.println("PreferencesService.setStringPreference(String, String, String): BackingStoreException");
+ System.out.println("\tlevel = " + level + "; key = " + key + "; value = " + value);
+ }
+ }
+
+
+
+ /*
+ * Get preferences for a given level, language, and project by type
+ */
+
+ public boolean getBooleanPreference(String languageName, String projectName, String level, String key, boolean def)
+ {
+ IEclipsePreferences node = getNodeForParameters("getBooleanPreference", languageName, level, projectName, key);
+ return node.getBoolean(key, def);
+ }
+
+
+ public byte[] getByteArrayPreference(String languageName, String projectName, String level, String key, byte[] def)
+ {
+ IEclipsePreferences node = getNodeForParameters("getByteArrayPreference", languageName, level, projectName, key);
+ return node.getByteArray(key, def);
+ }
+
+
+ public double getDoublePreference(String languageName, String projectName, String level, String key, double def)
+ {
+ IEclipsePreferences node = getNodeForParameters("getDoublePreference", languageName, level, projectName, key);
+ return node.getDouble(key, def);
+ }
+
+
+ public float getFloatPreference(String languageName, String projectName, String level, String key, float def)
+ {
+ IEclipsePreferences node = getNodeForParameters("getFloatPreference", languageName, level, projectName, key);
+ return node.getFloat(key, def);
+ }
+
+
+ public int getIntPreference(String languageName, String projectName, String level, String key, int def)
+ {
+ IEclipsePreferences node = getNodeForParameters("getIntPreference", languageName, level, projectName, key);
+ return node.getInt(key, def);
+ }
+
+ public long getLongPreference(String languageName, String projectName, String level, String key, long def)
+ {
+ IEclipsePreferences node = getNodeForParameters("getLongPreference", languageName, level, projectName, key);
+ return node.getLong(key, def);
+ }
+
+ public String getStringPreference(String languageName, String projectName, String level, String key, String def)
+ {
+ IEclipsePreferences node = getNodeForParameters("getStringPreference", languageName, level, projectName, key);
+ return performSubstitutions(node.get(key, def), getProjectFromName(projectName));
+ }
+
+
+ public String getRawStringPreference(String languageName, String projectName, String level, String key, String def)
+ {
+ IEclipsePreferences node = getNodeForParameters("getRawStringPreference", languageName, level, projectName, key);
+ return node.get(key, def);
+ }
+
+
+
+
+
+ /*
+ * Set preferences for a given level, language, and project by type
+ */
+
+ public void setBooleanPreference(String languageName, String projectName, String level, String key, boolean value)
+ {
+ IEclipsePreferences node = getNodeForParameters("setBooleanPreference", languageName, level, projectName, key);
+ node.putBoolean(key, value);
+ try {
+ node.flush();
+ } catch (BackingStoreException e) {
+ System.out.println("PreferencesService.setBooleanPreference(String, String, String, String, boolean): BackingStoreException");
+ System.out.println("\tlanguage = " + languageName + "; project = " + projectName + "; level = " + level + "; key = " + key + "; value = " + value);
+ }
+ }
+
+ public void setByteArrayPreference(String languageName, String projectName, String level, String key, byte[] value)
+ {
+ IEclipsePreferences node = getNodeForParameters("setByteArrayPreference", languageName, level, projectName, key);
+ node.putByteArray(key, value);
+ try {
+ node.flush();
+ } catch (BackingStoreException e) {
+ System.out.println("PreferencesService.setByteArrayPreference(String, String, String, String, byte[]): BackingStoreException");
+ System.out.println("\tlanguage = " + languageName + "; project = " + projectName + "; level = " + level + "; key = " + key + "; value = " + value);
+ }
+ }
+
+ public void setDoublePreference(String languageName, String projectName, String level, String key, double value)
+ {
+ IEclipsePreferences node = getNodeForParameters("setDoublePreference", languageName, level, projectName, key);
+ node.putDouble(key, value);
+ try {
+ node.flush();
+ } catch (BackingStoreException e) {
+ System.out.println("PreferencesService.setDoublePreference(String, String, String, String, double): BackingStoreException");
+ System.out.println("\tlanguage = " + languageName + "; project = " + projectName + "; level = " + level + "; key = " + key + "; value = " + value);
+ }
+ }
+
+ public void setFloatPreference(String languageName, String projectName, String level, String key, float value)
+ {
+ IEclipsePreferences node = getNodeForParameters("setFloatPreference", languageName, level, projectName, key);
+ node.putFloat(key, value);
+ try {
+ node.flush();
+ } catch (BackingStoreException e) {
+ System.out.println("PreferencesService.setFloatPreference(String, String, String, String, float): BackingStoreException");
+ System.out.println("\tlanguage = " + languageName + "; project = " + projectName + "; level = " + level + "; key = " + key + "; value = " + value);
+ }
+ }
+
+ public void setIntPreference(String languageName, String projectName, String level, String key, int value)
+ {
+ IEclipsePreferences node = getNodeForParameters("setIntPreference", languageName, level, projectName, key);
+ node.putInt(key, value);
+ try {
+ node.flush();
+ } catch (BackingStoreException e) {
+ System.out.println("PreferencesService.setIntPreference(String, String, String, String, int): BackingStoreException");
+ System.out.println("\tlanguage = " + languageName + "; project = " + projectName + "; level = " + level + "; key = " + key + "; value = " + value);
+ }
+ }
+
+ public void setLongPreference(String languageName, String projectName, String level, String key, long value)
+ {
+ IEclipsePreferences node = getNodeForParameters("setLongPreference", languageName, level, projectName, key);
+ node.putLong(key, value);
+ try {
+ node.flush();
+ } catch (BackingStoreException e) {
+ System.out.println("PreferencesService.setLongPreference(String, String, String, String, long): BackingStoreException");
+ System.out.println("\tlanguage = " + languageName + "; project = " + projectName + "; level = " + level + "; key = " + key + "; value = " + value);
+ }
+ }
+
+ public void setStringPreference(String languageName, String projectName, String level, String key, String value)
+ {
+ IEclipsePreferences node = getNodeForParameters("setStringPreference", languageName, level, projectName, key);
+ node.put(key, value);
+ try {
+ node.flush();
+ } catch (BackingStoreException e) {
+ System.out.println("PreferencesService.setStringPreference(String, String, String, String, String): BackingStoreException");
+ System.out.println("\tlanguage = " + languageName + "; project = " + projectName + "; level = " + level + "; key = " + key + "; value = " + value);
+ }
+ }
+
+
+
+ public IScopeContext getPreferencesScope(String level, IProject proj)
+ {
+ if (level.equals(PreferencesService.CONFIGURATION_LEVEL)) {
+ return configurationScope;
+ } else if (level.equals(PreferencesService.INSTANCE_LEVEL)) {
+ return instanceScope;
+ } else if (level.equals(PreferencesService.DEFAULT_LEVEL)) {
+ return defaultScope;
+ } else if (level.equals(PreferencesService.PROJECT_LEVEL)) {
+ return new ProjectScope(proj);
+ }
+ return null;
+ }
+
+
+ public void validateParameters(String methodName, String languageName, String level, String projectName, String key)
+ {
+ if (!isaPreferencesLevel(level)) {
+ throw new IllegalArgumentException(
+ "PreferencesService." + methodName + ": given level is not a valid preferences level: " + level);
+ }
+ if (languageName == null || languageName.equals("")) {
+ throw new IllegalArgumentException(
+ "PreferencesService." + methodName + ": given language name is null or empty");
+ }
+ if (level.equals(PreferencesService.PROJECT_LEVEL)) {
+ if ((projectName == null) || projectName.equals("")) {
+ throw new IllegalArgumentException(
+ "PreferencesService." + methodName + ": level is 'project' but project name is null or empty");
+ }
+ IProject proj = getProjectFromName(projectName);
+ if (proj == null) {
+ throw new IllegalArgumentException(
+ "PreferencesService." + methodName +
+ ": level is 'project' but project name '" + projectName + "' does not denote an existing project");
+ }
+ }
+ if (key == null || key.equals("")) {
+ throw new IllegalArgumentException(
+ "PreferencesService.setStringPreference: key is null or empty");
+ }
+ }
+
+
+ public IEclipsePreferences getNodeForParameters(String methodName, String languageName, String level, String projectName, String key)
+ {
+ validateParameters(methodName, languageName, level, projectName, key);
+
+ IProject proj = getProjectFromName(projectName);
+ IScopeContext scope = getPreferencesScope(level, proj);
+ if (scope == null) {
+ throw new IllegalStateException(
+ "PreferencesService." + methodName + ": unable to obtain valid preferences scope");
+ }
+
+ IEclipsePreferences node = scope.getNode(languageName);
+ if (node == null) {
+ throw new IllegalStateException(
+ "PreferencesService." + methodName + ": unable to obtain valid preferences node");
+ }
+
+ return node;
+ }
+
+
+ /*
+ * Clear preferences at a given level
+ */
+
+
+ /**
+ * Clear all of the preferences at a given level.
+ *
+ * @return the (cleared) preferences node for the given level
+ */
+ public IEclipsePreferences clearPreferencesAtLevel(String level) {
+ return clearPreferencesAtLevel(project, level);
+ }
+
+ /**
+ * Clear all of the preferences at a given level, considering the
+ * given project if the level is the project level.
+ *
+ * @return the (cleared) preferences node for the given level
+ */
+ public IEclipsePreferences clearPreferencesAtLevel(IProject project, String level)
+ {
+ if (level == null) {
+ throw new IllegalArgumentException(
+ "PreferencesService.clearPreferencesAtLevel (with project): given level is null");
+ }
+ if (!isaPreferencesLevel(level)) {
+ throw new IllegalArgumentException(
+ "PreferencesService.clearPreferencesAtLevel (with project): given level '" + level + "' is not a valid level");
+ }
+ if (project == null && level.equals(PROJECT_LEVEL)) {
+ //throw new IllegalStateException(
+ // "PreferencesService.clearPreferencesAtLevel (with project): given project is null when given level is 'project'");
+ return null;
+ }
+
+ IEclipsePreferences node = null;
+ try {
+ if (level.equals(PROJECT_LEVEL) && projectScope != null) {
+ node = projectScope.getNode(languageName);
+ } else if (level.equals(INSTANCE_LEVEL)) {
+ node = instanceScope.getNode(languageName);
+ } else if (level.equals(CONFIGURATION_LEVEL)) {
+ node = configurationScope.getNode(languageName);
+ } else if (level.equals(DEFAULT_LEVEL)) {
+ node = defaultScope.getNode(languageName);
+ }
+ if (node != null) {
+ //node.clear();
+ String[] keys = node.keys();
+ for (int i = 0; i < keys.length; i++) {
+ node.remove(keys[i]);
+ }
+ node.flush(); // SMS 28 Nov 2006
+ }
+ } catch (BackingStoreException e) {
+ System.out.println("PreferencesService.setPreferences(): " +
+ "BackingStoreException clearing existing preferences; attempting to add new preferences anyway");
+ }
+
+ return node;
+ }
+
+
+ /**
+ * Clear the specific preference associated with a given key at
+ * a given level.
+ *
+ * @return the cleared value (may be null)
+ */
+ public String clearPreferenceAtLevel(String level, String key)
+ {
+ return clearPreferenceAtLevel(project, level, key);
+ }
+
+
+ /**
+ * Clear the specific preference associated with a given key at
+ * a given level. Consider the given project if the given level
+ * is the project level.
+ *
+ * @return the cleared value (may be null)
+ */
+ public String clearPreferenceAtLevel(IProject project, String level, String key)
+ {
+ if (level == null) {
+ throw new IllegalArgumentException(
+ "PreferencesService.clearPreferenceAtLevel (with project): given level is null");
+ }
+ if (!isaPreferencesLevel(level)) {
+ throw new IllegalArgumentException(
+ "PreferencesService.clearPreferenceAtLevel (with project): given level '" + level + "' is not a valid level");
+ }
+ if (project == null && level.equals(PROJECT_LEVEL)) {
+ throw new IllegalStateException(
+ "PreferencesService.clearPreferenceAtLevel (with project): given project is null when given level is 'project'");
+ }
+
+ IScopeContext context = null;
+ if (level.equals(PROJECT_LEVEL)) {
+ context = getScopeForProject(project);
+ } else {
+ context = getScopeForLevel(level);
+ }
+ IEclipsePreferences node = context.getNode(languageName);
+ if (node == null) return null;
+ String preference = node.get(key, null);
+ node.remove(key);
+ try {
+ node.flush();
+ } catch (BackingStoreException e){
+ System.err.println("PreferencesService.clearPreferenceAtLevel(..): BackingStoreException trying to flush node with cleared preference;\n" +
+ "\tproject = " + project + "; level = " + level + "; key = " + key + "\n" +
+ "\tclearing may not have a persistent effect");
+ }
+ return preference;
+ }
+
+
+
+ /*
+ * Other useful things
+ */
+
+ /**
+ * The standard search order of preference levels in the IMP preferences
+ * service. This is the default search order in the Eclipse PreferencesService
+ * and it is presumed not to change during the operation of the IMP service.
+ *
+ */
+ public final static String[] levels = { PROJECT_LEVEL, INSTANCE_LEVEL, CONFIGURATION_LEVEL, DEFAULT_LEVEL };
+
+
+
+ public int indexForLevel(String levelName) {
+ for (int i = 0; i < levels.length; i++) {
+ if (levels[i].equals(levelName))
+ return i;
+ }
+ return -1;
+ }
+
+
+
+
+ /**
+ * Returns the first preference level in the standard search order
+ * at which the given key is defined for the current language.
+ * Returns null if the given key is not defined.
+ */
+ public String getApplicableLevel(String key, String level)
+ {
+ return getApplicableLevel(project, key, level);
+ }
+
+ /**
+ * Returns the first preference level in the standard search order
+ * at which the given key is defined for the current language.
+ * Returns null if the given key is not defined.
+ */
+ public String getApplicableLevel(IProject project, String key, String level)
+ {
+ // Level == null okay, as we can start at the bottom in that case
+
+ if (level != null && !isaPreferencesLevel(level)) {
+ throw new IllegalArgumentException("PreferencesService.getApplicableLevel (with project): given level '" + level + "' is not a real level");
+ }
+ if (key == null) {
+ throw new IllegalArgumentException("PreferencesService.getApplicableLevel (with project): given key is null");
+ }
+ if (level != null && level.equals(PROJECT_LEVEL) && projectScope == null) {
+ throw new IllegalStateException("PreferencesService.getApplicableLevel (with project): node for project requested when project scope is null");
+ }
+
+
+ int startIndex = level == null ? (project != null ? PROJECT_INDEX : INSTANCE_INDEX) : getIndexForLevel(level);
+
+ if (startIndex == PROJECT_INDEX) {
+ IScopeContext context = getScopeForProject(project);
+ IEclipsePreferences node = context.getNode(languageName);
+ String[] keys;
+ try {
+ keys = node.keys();
+ } catch (BackingStoreException e) {
+ keys = new String[0];
+ }
+ for (int i = 0; i < keys.length; i++) {
+ if (keys[i].equals(key)) return PROJECT_LEVEL;
+ }
+ startIndex++;
+ }
+
+ for (int i = startIndex; i < levels.length; i++) {
+ // Since all preference values are stored as strings,
+ // regardless of attributed base type, I believe that
+ // all can be safely retrieved as strings, so long as
+ // we don't care about their actual values
+ String pref = getStringPreference(levels[i], key);
+ if (pref == null) continue;
+ return levels[i];
+ }
+ return null;
+ }
+
+
+ public boolean isDefault(String key, String level) {
+ return isDefault(project, key, level);
+ }
+
+
+ public boolean isDefault(IProject project, String key, String level) {
+ return DEFAULT_LEVEL.equals(getApplicableLevel(project, key, level));
+ }
+
+
+ public boolean isDefined(String key) {
+ return isDefined(project, key);
+ }
+
+ public boolean isDefined(IProject project, String key) {
+ return getApplicableLevel(project, key, null) != null;
+ }
+
+
+
+ public boolean isaPreferencesLevel(String possibleLevel) {
+ for (int i = 0; i < levels.length; i++) {
+ if (levels[i].equals(possibleLevel)) return true;
+ }
+ return false;
+ }
+
+
+ public IEclipsePreferences getRootNode() {
+ return preferencesService.getRootNode();
+ }
+
+ public IEclipsePreferences getNodeForLevel(String level)
+ {
+ if (level == null) {
+ throw new IllegalArgumentException("PreferencesService.getNodeForLevel: given level is null");
+ }
+ if (!isaPreferencesLevel(level)) {
+ throw new IllegalArgumentException("PreferencesService.getNodeForLevel: given level '" + level + "' is not a real level");
+ }
+ if (level.equals(PROJECT_LEVEL) && projectScope == null) {
+ throw new IllegalStateException("PreferencesService.getNodeForLevel: node for project requested when project scope is null");
+ }
+
+ IEclipsePreferences node = null;
+
+ if (level.equals(PROJECT_LEVEL)) {
+ node = projectScope.getNode(languageName);
+ } else if (level.equals(INSTANCE_LEVEL)) {
+ node = instanceScope.getNode(languageName);
+ } else if (level.equals(CONFIGURATION_LEVEL)) {
+ node = configurationScope.getNode(languageName);
+ } else if (level.equals(DEFAULT_LEVEL)) {
+ node = defaultScope.getNode(languageName);
+ }
+ return node;
+ }
+
+
+ public IEclipsePreferences[] getNodesForLevels()
+ {
+ if (languageName == null || languageName.equals("")) {
+ throw new IllegalStateException("PreferencesService.getNodesForLevels: language name is invalid (null or empty); no associated preferences nodes");
+ }
+ IEclipsePreferences[] nodes = new IEclipsePreferences[4];
+
+ if (projectScope != null)
+ nodes[0] = projectScope.getNode(languageName);
+ else
+ nodes[0] = null;
+
+ nodes[1] = instanceScope.getNode(languageName);
+ nodes[2] = configurationScope.getNode(languageName);
+ nodes[3] = defaultScope.getNode(languageName);
+
+ return nodes;
+ }
+
+
+
+
+ public IScopeContext getScopeForLevel(String level)
+ {
+ if (!isaPreferencesLevel(level)) {
+ throw new IllegalArgumentException("PreferencesService.getScopeForLevel: level = '" + level + "' is not a valid level");
+ }
+ //if (level.equals(PROJECT_LEVEL) && projectScope == null) {
+ // throw new IllegalStateException("PreferencesService.scopeForLevel: scope for project requested when project scope is null");
+ //}
+
+ IScopeContext result = null;
+
+ //if (!isaPreferencesLevel(level)) return result;
+
+ if (level.equals(PROJECT_LEVEL)) {
+ if (projectScope == null) { return null; }
+ else { return projectScope; }
+ } else if (level.equals(INSTANCE_LEVEL)) {
+ return instanceScope;
+ } else if (level.equals(CONFIGURATION_LEVEL)) {
+ return configurationScope;
+ } else if (level.equals(DEFAULT_LEVEL)) {
+ return defaultScope;
+ }
+ return result;
+ }
+
+
+ public IScopeContext getScopeForProject(IProject project) {
+ if (project == null) {
+ throw new IllegalArgumentException("PreferencesService.getScopeForProject: given project is null");
+ }
+ return new ProjectScope(project);
+ }
+
+
+ public IEclipsePreferences[] getNodesForLevels(IProject project) {
+ if (project == null) {
+ throw new IllegalArgumentException("PreferencesService.getNodesForLevels: given project is null");
+ }
+
+ IEclipsePreferences[] nodes = new IEclipsePreferences[4];
+
+ nodes[0] = new ProjectScope(project).getNode(languageName);
+ nodes[1] = instanceScope.getNode(languageName);
+ nodes[2] = configurationScope.getNode(languageName);
+ nodes[3] = defaultScope.getNode(languageName);
+
+ return nodes;
+ }
+
+
+ public IEclipsePreferences getNodeForProject(IProject project) {
+ if (project == null) {
+ throw new IllegalArgumentException("PreferencesService.getNodeForProject: given project is null");
+ }
+
+ return new ProjectScope(project).getNode(languageName);
+ }
+
+
+ public int getIndexForLevel(String level)
+ {
+ // Special case, e.g., for "applicable" preferences
+ if (level == null) return 0;
+
+ if (!isaPreferencesLevel(level)) {
+ throw new IllegalArgumentException("PreferencesService.getIndexForLevel: level = '" + level + "' is not a valid level");
+ }
+ // Maybe better let people get the index for the project level
+ // even if there is not project assigned (index considered not harmful)
+ //if (level.equals(PROJECT_LEVEL) && projectScope == null) {
+ // throw new IllegalStateException("PreferencesService.getIndexForLevel: scope for project requested when project scope is null");
+ //}
+
+ if (level.equals(PROJECT_LEVEL))return 0;
+ else if (level.equals(INSTANCE_LEVEL)) return 1;
+ else if (level.equals(CONFIGURATION_LEVEL)) return 2;
+ else if (level.equals(DEFAULT_LEVEL)) return 3;
+
+ throw new IllegalStateException("PreferencesService.getIndexForLevel: found no index to return for level = " + level);
+ }
+
+
+ /*
+ * For listeners
+ */
+
+
+ private List<IProjectSelectionListener> projectSelectionListeners = new ArrayList<IProjectSelectionListener>();
+
+ public void addProjectSelectionListener(IProjectSelectionListener listener) {
+ projectSelectionListeners.add(listener);
+ }
+
+ public void removeProjectSelectionListener(IProjectSelectionListener listener) {
+ projectSelectionListeners.remove(listener);
+ }
+
+ protected void fireProjectSelectionEvent(final ProjectSelectionEvent event)
+ {
+ if (projectSelectionListeners == null || projectSelectionListeners.size() == 0)
+ return;
+ //Object[] listeners = projectSelectionListeners.toArray();
+ for (int i = 0; i < projectSelectionListeners.size(); i++) {
+ final IProjectSelectionListener listener = projectSelectionListeners.get(i);
+ ISafeRunnable job = new ISafeRunnable() {
+ public void handleException(Throwable exception) {
+ // already logged in Platform#run()
+ }
+ public void run() throws Exception {
+ listener.selection(event);
+ }
+ };
+ Platform.run(job);
+ }
+ }
+
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencesTab.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencesTab.java
new file mode 100644
index 000000000..b2acf24c0
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencesTab.java
@@ -0,0 +1,340 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.imp.preferences.fields.FieldEditor;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+
+public abstract class PreferencesTab
+{
+ // The following fields are shared among specific
+ // subtypes of preferences tab, which generally represent
+ // the various levels on which preferences are set.
+ // However, most of the fields have language-dependent
+ // impementations, so they are not set here.
+
+ // The page on which this tab occurs
+ protected TabbedPreferencesPage fPrefPage = null;
+
+ // Utilities for creating and managing preference fields
+ protected PreferencesUtilities fPrefUtils;
+
+ // The service for storing and accessing preference values
+ protected IPreferencesService fPrefService;
+
+ // The fields that occur on this tab
+ protected FieldEditor[] fFields = null;
+
+ protected boolean fNoDetails = false;
+
+ // The details links that are associated with the fields
+ // (to be in one-to-one correspondence)
+ protected List<Link> fDetailsLinks = new ArrayList<Link>();
+
+ protected String fLevel;
+
+ // Whether this tab is valid, that is, whether
+ // all of its fields are valid
+ protected boolean fIsValid = true;
+
+ // The buttons on this tab
+ protected Control[] fButtons = null;
+
+ // SMS 17 Nov 2006
+ protected TabItem fTabItem = null;
+
+
+ public PreferencesTab(String level, boolean noDetails) {
+ fLevel= level;
+ fNoDetails= noDetails;
+ }
+
+ public TabItem getTabItem() {
+ return fTabItem;
+ }
+
+ public String getLevel() {
+ return fLevel;
+ }
+
+ public boolean getNoDetails() {
+ return fNoDetails;
+ }
+
+ /**
+ * Creates specific preferences fields.
+ * Must be overridden, typically by language-specific tab classes.
+ */
+ protected abstract FieldEditor[] createFields(TabbedPreferencesPage page, Composite parent);
+
+
+ /**
+ * Creates the contents of the entire tab. Calls createFields().
+ * Overridden by level-specific tab classes, but not typically overridden in language-specific
+ * tab classes (which, instead, override createFields()).
+ */
+ public abstract Composite createTabContents(TabbedPreferencesPage page, final TabFolder tabFolder);
+
+
+ /*
+ * Methods to set or clear an "error mark" on tab labels
+ */
+
+ public void setErrorMarkOnTab() {
+ if (errorMessages.isEmpty()) {
+ return;
+ }
+ String label = fTabItem.getText();
+ if (!label.startsWith(Markings.TAB_ERROR_MARK)) {
+ label = Markings.TAB_ERROR_MARK + label;
+ }
+ if (!label.endsWith(Markings.TAB_ERROR_MARK)) {
+ label = label + Markings.TAB_ERROR_MARK;
+ }
+ fTabItem.setText(label);
+ }
+
+ public void clearErrorMarkOnTab() {
+ if (!errorMessages.isEmpty()) {
+ return;
+ }
+ String label = fTabItem.getText();
+ if (label.startsWith(Markings.TAB_ERROR_MARK)) {
+ label = label.substring(2);
+ }
+ if (label.endsWith(Markings.TAB_ERROR_MARK)) {
+ label = label.substring(0, label.length()-2);
+ }
+ fTabItem.setText(label);
+ }
+
+
+ /*
+ * Methods and a field related to setting and clearing error messages
+ * for the tab
+ */
+
+
+ public HashMap errorMessages = new HashMap();
+
+
+ public void clearErrorMessages(Object key) {
+ String currentMessage = (String) errorMessages.get(key);
+// System.out.println("Tab = " + tabItem.getText() + ", field = " + ((FieldEditor)key).getPreferenceName() + ": clearErrorMessages(), clearing message = " + currentMessage);
+ errorMessages.remove(key);
+ if (fPrefPage == null) return;
+ if (errorMessages.size() == 0) {
+// System.out.println("Tab = " + tabItem.getText() + ", field = " + ((FieldEditor)key).getPreferenceName() + ": clearErrorMessages(), setting message to null");
+ fPrefPage.setErrorMessage(null); // to clear
+ return;
+ }
+ Iterator it = errorMessages.keySet().iterator();
+ Object nextKey = it.next();
+ String nextMessage = (String) errorMessages.get(nextKey);
+// System.out.println("Tab = " + tabItem.getText() + ", field = " + ((FieldEditor)key).getPreferenceName() + "clearErrorMessages(), setting message to: " + nextMessage);
+ fPrefPage.setErrorMessage(nextMessage);
+ }
+
+
+ public void setErrorMessage(Object key, String msg) {
+ if (key != null && msg != null) {
+// System.out.println("Tab = " + tabItem.getText() + ", field = " + ((FieldEditor)key).getPreferenceName() + ": setErrorMessage(), setting message to: " + msg);
+ errorMessages.put(key, msg);
+ fPrefPage.setErrorMessage(msg);
+ }
+ }
+
+
+
+ /*
+ * A method to clear the modified mark on field labels
+ */
+
+ public void clearModifiedMarksOnLabels()
+ {
+ for (int i = 0; i < fFields.length; i++) {
+ fFields[i].clearModifiedMarkOnLabel();
+ }
+ }
+
+
+
+ /*
+ * A listener class for responding to selection of the tab
+ */
+
+
+ /**
+ * A listener for responding to selection of the tab, mainly by
+ * clearing or setting the error message on the page according to
+ * whether there are error messages associated with the tab.
+ */
+ public class TabSelectionListener implements SelectionListener
+ {
+ private PreferencePage page = null;
+ private TabItem item = null;
+
+ public TabSelectionListener(PreferencePage page, TabItem item) {
+ this.page = page;
+ this.item = item;
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ if (fPrefPage == null) return;
+ if (e.item != item) return;
+ if (errorMessages.size() == 0) {
+ fPrefPage.setErrorMessage(null);
+ return;
+ }
+
+ Iterator it = errorMessages.keySet().iterator();
+ Object nextKey = it.next();
+ String nextMessage = (String) errorMessages.get(nextKey);
+ fPrefPage.setErrorMessage(nextMessage);
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {}
+ }
+
+
+ /*
+ * Methods for responding to buttons, with very simple implementations.
+ *
+ * SMS 4 Dec 2006: These could be made abstract, but why not provide
+ * a minimal useful representation?
+ */
+
+
+ /**
+ * Apply the currently set preferences to the preferences model.
+ * More specifically store each field and clear its "modified" mark
+ * (not all fields will be modified, but that's not a problem).
+ *
+ * This implementation of performApply is adequate for the provided
+ * implementations of the Default, Configuration, and Instance tabs
+ * but needs to be overridden in the Project tab to address the
+ * situation in which the project is not set.
+ */
+ public void performApply()
+ {
+ for (int i = 0; i < fFields.length; i++) {
+ fFields[i].store();
+ fFields[i].clearModifiedMarkOnLabel();
+ }
+ }
+
+
+
+ public boolean performCancel() {
+ return true;
+ }
+
+
+ public void performDefaults() {
+
+ }
+
+
+ /**
+ * Apply the currently set preferences to the preferences model.
+ * More specifically store each field and clear its "modified" mark
+ * (not all fields will be modified, but that's not a problem).
+ *
+ * This implementation of performOk is adequate for the provided
+ * implementations of the Default, Configuration, and Instance tabs
+ * but needs to be overridden in the Project tab to address the
+ * situation in which the project is not set and to unset the
+ * project when it is set.
+ *
+ */
+ public boolean performOk() {
+ if (fFields != null) {
+ for (int i = 0; i < fFields.length; i++) {
+ fFields[i].store();
+ fFields[i].clearModifiedMarkOnLabel();
+ // RMF 1/9/2009 - For some reason, some performOk() implementations (like the X10DT's)
+ // call setPresentsDefaultValue(false), which seems wrong...
+ }
+ }
+ return true;
+ }
+
+
+
+
+ /*
+ * Methods to set and get the "valid" state of the tab
+ * and to update the enabled state of buttons on the
+ * tab according to the valid state.
+ */
+
+
+ /**
+ * Set the "valid" state of the tab according to the given
+ * value in conjunction with the occurrence of error messages.
+ *
+ * Note: This method will be called (indirectly) whenever a
+ * preference field is validated. However, the state of the
+ * tab overall depends on the conjunction of the states of
+ * all of its fields. The value provided here represents the
+ * state of one field;
+ */
+ public void setValid(boolean state) {
+ // SMS 8 Dec 2006: added second conjunct
+ fIsValid = /*state &&*/ errorMessages.size() == 0;
+ if (!fIsValid) {
+ setErrorMarkOnTab();
+ } else {
+ clearErrorMarkOnTab();
+ }
+ fPrefPage.notifyState(fIsValid);
+ updateButtons();
+ }
+
+
+ public boolean isValid() {
+ //int numMessages = errorMessages.size();
+ return fIsValid;
+ }
+
+
+ public void updateButtons() {
+ if (fButtons != null) {
+ //System.out.println("SPT.updateButtons(): buttons not null");
+ for (int i = 0; i < fButtons.length; i++) {
+ Button button = (Button) fButtons[i];
+ if (button != null)
+ // TODO: define string constants for button texts
+ if (button.getText().startsWith("Restore"))
+ continue;
+ button.setEnabled(isValid() /* && errorMessages.size() == 0*/);
+ }
+ } else {
+ //System.out.println("SPT.updateButtons(): buttons null");
+ }
+
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencesUtilities.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencesUtilities.java
new file mode 100644
index 000000000..35e251158
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/PreferencesUtilities.java
@@ -0,0 +1,1639 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.preferences;
+
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
+import org.eclipse.imp.preferences.fields.BooleanFieldEditor;
+import org.eclipse.imp.preferences.fields.ChangeButtonFieldEditor;
+import org.eclipse.imp.preferences.fields.ColorFieldEditor;
+import org.eclipse.imp.preferences.fields.ComboFieldEditor;
+import org.eclipse.imp.preferences.fields.DirectoryFieldEditor;
+import org.eclipse.imp.preferences.fields.DirectoryListFieldEditor;
+import org.eclipse.imp.preferences.fields.DoubleFieldEditor;
+import org.eclipse.imp.preferences.fields.FieldEditor;
+import org.eclipse.imp.preferences.fields.FileFieldEditor;
+import org.eclipse.imp.preferences.fields.FontFieldEditor;
+import org.eclipse.imp.preferences.fields.IntegerFieldEditor;
+import org.eclipse.imp.preferences.fields.RadioGroupFieldEditor;
+import org.eclipse.imp.preferences.fields.StringButtonFieldEditor;
+import org.eclipse.imp.preferences.fields.StringFieldEditor;
+import org.eclipse.imp.preferences.fields.details.DetailsDialogForBooleanFields;
+import org.eclipse.imp.preferences.fields.details.DetailsDialogForColorFields;
+import org.eclipse.imp.preferences.fields.details.DetailsDialogForComboFields;
+import org.eclipse.imp.preferences.fields.details.DetailsDialogForFontFields;
+import org.eclipse.imp.preferences.fields.details.DetailsDialogForRadioGroupFields;
+import org.eclipse.imp.preferences.fields.details.DetailsDialogForStringFields;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+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.Color;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.swt.widgets.Text;
+
+public class PreferencesUtilities {
+ public static final Color colorBlack = new Color(null, 0, 0, 0);
+ public static final Color colorWhite = new Color(null, 255, 255, 255);
+ public static final Color colorBluish = new Color(null, 175, 207, 239);
+ public static final Color colorGreenish = new Color(null, 0, 127, 239);
+ public static final Color colorLightGray = new Color(null, 224, 223, 226);
+ public static final Color colorRed = new Color(null, 255, 0, 0);
+
+ public static final String comboDefaultValue = "none selected";
+ public static final String comboDefaultName = "None selected";
+
+ protected IPreferencesService service = null;
+
+ public PreferencesUtilities(IPreferencesService service) {
+ this.service = service;
+ }
+
+ public String setField(BooleanFieldEditor field, Composite parent) {
+ // TODO: Add checks on input validity (see below)
+ // Note: so far assumes that the given level is the one to which the
+ // field belongs (which should be true but isn't guaranteed (?))
+
+ String level = field.getPreferencesLevel();
+
+ // If the level is "project" and project == null then just set
+ // the field here (as a special case).
+ // Note: without some project selected the field should not be
+ // editable. Field will have to be set back to editable when
+ // (and probably where) a project is selected. We might take
+ // care of this elsewhere but, until that is verified, keep
+ // doing it here.
+ // Note also: loadWithInheritance (which calls setField(..))
+ // won't know that project == null and will try to set the field
+ // from some higher level
+ if (IPreferencesService.PROJECT_LEVEL.equals(level) && service.getProject() == null) {
+ if (parent == null) {
+ System.err.println("PreferencesUtilities.setField(): parent is null");
+ }
+ if (parent.isDisposed()) {
+ System.err.println("PreferencesUtilities.setField(): parent is disposed");
+ }
+ // Don't have a null boolean value to set field to,
+ // but would like to show it as "cleared" somehow
+ // (presumably "false" shows as empty
+ field.setFieldValueFromOutside(false);
+ if (!parent.isDisposed()) {
+ field.getChangeControl().setEnabled(false);
+ field.getChangeControl().setBackground(colorBluish);
+ }
+ // Pretend that this was set at the project level?
+ // (It was certainly cleared at that level)
+ return IPreferencesService.PROJECT_LEVEL;
+ }
+
+ // Otherwise, we have a legitimate level, so set normally
+ String levelFromWhichSet = field.loadWithInheritance();
+
+ // Note: You can evidently load a field even when its control
+ // is disposed. In that case (evidently) you can change the
+ // text in the field but not the background color.
+
+ if (parent != null && !parent.isDisposed()) {
+ if (level != null && level.equals(levelFromWhichSet)) {
+ field.getChangeControl().setBackground(colorWhite);
+ } else if (level != null && field.getChangeControl().getEnabled()) {
+ field.getChangeControl().setBackground(colorBluish);
+ }
+ } else {
+ // If composite.isDisposed(), then both field.getTextControl(composite)
+ // and field.getTextControl() will return null; if needed, a text control
+ // must be obtained from somewhere else--but I have no idea where that
+ // might be. Not sure why composite.isDisposed() here in the first place,
+ // especially considering that the field can be set
+ }
+
+ return levelFromWhichSet;
+ }
+
+ private void checkArgs(FieldEditor field, Composite parent, String whoiam) {
+ if (field == null)
+ throw new IllegalArgumentException(whoiam + "given field is null");
+ if (parent == null)
+ throw new IllegalArgumentException(whoiam + "given parent is null");
+
+ if (parent.isDisposed())
+ throw new IllegalStateException(whoiam + "parent is disposed");
+ if (IPreferencesService.PROJECT_LEVEL.equals(field.getPreferencesLevel()) && service.getProject() == null)
+ throw new IllegalStateException(whoiam + "field represents a project-level preference and project is not set");
+ }
+
+ private void checkArgs(ChangeButtonFieldEditor field, Composite parent, String whoiam) {
+ checkArgs((FieldEditor) field, parent, whoiam);
+ if (!field.getChangeControl().getEnabled())
+ throw new IllegalStateException(whoiam + "field is not editable");
+ }
+
+ private void checkArgs(FieldEditor field, Composite parent, Object value, String whoiam) {
+ checkArgs(field, parent, whoiam);
+ if (value == null)
+ throw new IllegalArgumentException(whoiam + "given value is null");
+ }
+
+ private void checkArgs(ChangeButtonFieldEditor field, Composite parent, Object value, String whoiam) {
+ checkArgs((FieldEditor) field, parent, value, whoiam);
+ if (!field.getChangeControl().getEnabled())
+ throw new IllegalStateException(whoiam + "field is not editable");
+ }
+
+ public String setField(BooleanFieldEditor field, Composite parent, boolean value) {
+ final String whoiam = "PreferencesUtilities.setField(BooleanFieldEditor field, parent, value): ";
+
+ checkArgs(field, parent, whoiam);
+
+ String level = field.getPreferencesLevel();
+
+ field.setFieldValueFromOutside(value);
+ field.getChangeControl().setBackground(colorWhite);
+
+ return level;
+ }
+
+ public String setField(ComboFieldEditor field, Composite parent) {
+ // TODO: Add checks on input validity (see below)
+ // Note: so far assumes that the given level is the one to which the
+ // field belongs (which should be true but isn't guaranteed (?))
+
+ String level = field.getPreferencesLevel();
+
+ // If the level is "project" and project == null then just set
+ // the field here (as a special case).
+ if (IPreferencesService.PROJECT_LEVEL.equals(level) && service.getProject() == null) {
+ if (parent.isDisposed()) {
+ System.err.println("PreferencesUtilities.setField(): composite is disposed");
+ }
+ // Updating a radio field with a null value should
+ // cause the first button to be selected
+ field.setFieldValueFromOutside(null);
+ if (!parent.isDisposed()) {
+ // Assume that editability on the project level is set
+ // appropriately by a project-selection listener
+ //field.getTextControl(composite).setEditable(false);
+ field.getComboBoxControl().setBackground(colorWhite);
+ Control[] children = field.getComboBoxControl().getChildren();
+ if (children != null) {
+ for (int i = 0; i < children.length; i++) {
+ Button button = (Button) children[i];
+ button.setBackground(PreferencesUtilities.colorWhite);
+ }
+ }
+ }
+ // Pretend that this was set at the project level?
+ // (It was certainly cleared at that level)
+ return IPreferencesService.PROJECT_LEVEL;
+ }
+
+ // Otherwise, we have a legitimate level, so set normally
+ String levelFromWhichSet = field.loadWithInheritance();
+
+ // Note: You can evidently load a field even when it's control
+ // is disposed. In that case you can (evidently) change the
+ // text in the field but not the background color.
+
+ if (!parent.isDisposed()) {
+ // Needed if color is set in loadWithInheritance()?
+ // (Should the color be set in loadWithInheritance()?
+// if (field.isInherited()) {
+// field.getComboBoxControl(composite).setBackground(colorBluish);
+// } else {
+// field.getComboBoxControl(composite).setBackground(colorWhite);
+// }
+ } else {
+ // If composite.isDisposed(), then both field.getTextControl(composite)
+ // and field.getTextControl() will return null; if needed, a text control
+ // must be obtained from somewhere else--but I have no idea where that
+ // might be. Not sure why composite.isDisposed() here in the first place,
+ // especially considering that the field can be set
+ }
+
+ return levelFromWhichSet;
+ }
+
+ public String setField(ComboFieldEditor field, Composite parent, String value) {
+ final String whoiam = "PreferencesUtilities.setField(ComboFieldEditor field, parent, value): ";
+
+ checkArgs(field, parent, value, whoiam);
+
+ String level = field.getPreferencesLevel();
+
+ field.setFieldValueFromOutside(value);
+ // setString(value) takes care of setting isInherited
+ // and presentsDefaultValue, but not ...
+ field.getComboBoxControl().setBackground(colorWhite);
+
+ return level;
+ }
+
+ public String setField(ColorFieldEditor field, Composite parent, String value) {
+ final String whoiam = "PreferencesUtilities.setField(ColorFieldEditor field, parent, value): ";
+
+ checkArgs(field, parent, value, whoiam);
+
+ String level = field.getPreferencesLevel();
+
+ field.setFieldValueFromOutside(value);
+ // setString(value) takes care of setting isInherited
+ // and presentsDefaultValue, but not ...
+ field.getLabelControl(parent).setBackground(colorWhite);
+
+ return level;
+ }
+
+
+ public String setField(FontFieldEditor field, Composite parent, FontData[] value) {
+ final String whoiam = "PreferencesUtilities.setField(FontFieldEditor field, composite, value): ";
+
+ checkArgs(field, parent, value, whoiam);
+
+ String level = field.getPreferencesLevel();
+
+ field.setFieldValueFromOutside(value);
+ // setString(value) takes care of setting isInherited
+ // and presentsDefaultValue, but not ...
+ field.getChangeControl().setBackground(colorWhite);
+
+ return level;
+ }
+
+
+ public String setField(RadioGroupFieldEditor field, Composite composite) {
+ // TODO: Add checks on input validity (see below)
+ // Note: so far assumes that the given level is the one to which the
+ // field belongs (which should be true but isn't guaranteed (?))
+
+ String level = field.getPreferencesLevel();
+
+ // If the level is "project" and project == null then just set
+ // the field here (as a special case).
+ if (IPreferencesService.PROJECT_LEVEL.equals(level) && service.getProject() == null) {
+ if (composite.isDisposed()) {
+ System.err.println("PreferencesUtilities.setField(): composite is disposed");
+ }
+ // Updating a radio field with a null value should
+ // cause the first button to be selected
+ field.setFieldValueFromOutside(null);
+ if (!composite.isDisposed()) {
+ // Assume that editability on the project level is set
+ // appropriately by a project-selection listener
+ //field.getTextControl(composite).setEditable(false);
+ field.getRadioBoxControl().setBackground(colorBluish);
+ Button[] radioButtons = field.getRadioButtons();
+ if (radioButtons != null) {
+ for (int i = 0; i < radioButtons.length; i++) {
+ Button button = (Button) radioButtons[i];
+ button.setBackground(colorBluish);
+ }
+ }
+ }
+ // Pretend that this was set at the project level?
+ // (It was certainly cleared at that level)
+ return IPreferencesService.PROJECT_LEVEL;
+ }
+
+ // Otherwise, we have a legitimate level, so set normally
+ String levelFromWhichSet = field.loadWithInheritance();
+
+ // Note: You can evidently load a field even when it's control
+ // is disposed. In that case (evidently) you can change the
+ // text in the field but not the background color.
+
+ if (!composite.isDisposed()) {
+ // Needed if color is set in loadWithInheritance()?
+ // (Should the color be set in loadWithInheritance()?
+// if (field.isInherited()) {
+// field.getRadioBoxControl(composite).setBackground(colorBluish);
+// } else {
+// field.getRadioBoxControl(composite).setBackground(colorWhite);
+// }
+ } else {
+ // If composite.isDisposed(), then both field.getTextControl(composite)
+ // and field.getTextControl() will return null; if needed, a text control
+ // must be obtained from somewhere else--but I have no idea where that
+ // might be. Not sure why composite.isDisposed() here in the first place,
+ // especially considering that the field can be set
+ }
+
+ return levelFromWhichSet;
+ }
+
+
+ public String setField(RadioGroupFieldEditor field, Composite composite, String value) {
+ final String whoiam = "PreferenesUtilities.setField(RadioGroupFieldEditor field, composite, value): ";
+
+ checkArgs(field, composite, value, whoiam);
+
+ String level = field.getPreferencesLevel();
+
+ field.setFieldValueFromOutside(value);
+ // setString(value) takes care of setting isInherited
+ // and presentsDefaultValue, but not coloring
+ field.getRadioBoxControl().setBackground(colorWhite);
+ Button[] radioButtons = field.getRadioButtons();
+ if (radioButtons != null) {
+ for (int i = 0; i < radioButtons.length; i++) {
+ ((Button) radioButtons[i]).setBackground(colorWhite);
+ }
+ }
+
+ return level;
+ }
+
+
+ public String setField(StringFieldEditor field, Composite composite) {
+ // TODO: Add checks on input validity (see below)
+ // Note: so far assumes that the given level is the one to which the
+ // field belongs (which should be true but isn't guaranteed (?))
+
+ String level = field.getPreferencesLevel();
+
+ // If the level is "project" and project == null then just set
+ // the field here (as a special case).
+ if (IPreferencesService.PROJECT_LEVEL.equals(level) && service.getProject() == null) {
+ if (composite.isDisposed()) {
+ System.err.println("PreferencesUtilities.setField(): composite is disposed");
+ }
+ field.setFieldValueFromOutside(null);
+ if (!composite.isDisposed()) {
+ // Assume that editability on the project level is set
+ // appropriately by a project-selection listener
+ //field.getTextControl(composite).setEditable(false);
+ field.getTextControl(composite).setBackground(colorBluish);
+ }
+ // Pretend that this was set at the project level?
+ // (It was certainly cleared at that level)
+ return IPreferencesService.PROJECT_LEVEL;
+ }
+
+ // Otherwise, we have a legitimate level, so set normally
+ String levelFromWhichSet = field.loadWithInheritance();
+
+ // Note: You can evidently load a field even when it's control
+ // is disposed. In that case (evidently) you can change the
+ // text in the field but not the background color.
+
+ if (!composite.isDisposed()) {
+ /*
+ if (level != null && level.equals(levelFromWhichSet)) {
+ field.getTextControl(composite).setBackground(colorWhite);
+ } else if (level != null && field.getTextControl(composite).getEditable()) {
+ field.getTextControl(composite).setBackground(colorBluish);
+ }
+ */
+ if (field.isInherited()) {
+ field.getTextControl(composite).setBackground(colorBluish);
+ } else {
+ field.getTextControl(composite).setBackground(colorWhite);
+ }
+ } else {
+ // If composite.isDisposed(), then both field.getTextControl(composite)
+ // and field.getTextControl() will return null; if needed, a text control
+ // must be obtained from somewhere else--but I have no idea where that
+ // might be. Not sure why composite.isDisposed() here in the first place,
+ // especially considering that the field can be set
+ }
+
+ return levelFromWhichSet;
+ }
+
+
+ public String setField(StringFieldEditor field, Composite composite, String value) {
+ final String whoiam = "PreferencesUtilities.setField(StringFieldEditor field, composite, value): ";
+
+ checkArgs(field, composite, value, whoiam);
+
+ if (!field.getTextControl(composite).getEditable())
+ throw new IllegalStateException(whoiam + "field is not editable");
+ if (value.equals("") && !field.isEmptyValueAllowed())
+ throw new IllegalArgumentException(whoiam + "value is empty and field does not allow empty values");
+
+ String level = field.getPreferencesLevel();
+
+ field.setFieldValueFromOutside(value);
+ // setString(value) takes care of setting isInherited
+ // and presentsDefaultValue, but not ...
+ field.getTextControl(composite).setBackground(colorWhite);
+
+ return level;
+ }
+
+
+ public String setField(FontFieldEditor field, Composite parent) {
+ // TODO: Add checks on input validity (see below)
+ // Note: so far assumes that the given level is the one to which the
+ // field belongs (which should be true but isn't guaranteed (?))
+
+ String level = field.getPreferencesLevel();
+
+ // If the level is "project" and project == null then just set
+ // the field here (as a special case).
+ // Note: without some project selected the field should not be
+ // editable. Field will have to be set back to editable when
+ // (and probably where) a project is selected. We might take
+ // care of this elsewhere but, until that is verified, keep
+ // doing it here.
+ // Note also: loadWithInheritance (which calls setField(..))
+ // won't know that project == null and will try to set the field
+ // from some higher level
+ if (IPreferencesService.PROJECT_LEVEL.equals(level) &&
+ service.getProject() == null)
+ {
+ if (parent == null) {
+ System.err.println("PreferencesUtilities.setField(): parent is null");
+ }
+ if (parent.isDisposed()) {
+ System.err.println("PreferencesUtilities.setField(): parent is disposed");
+ }
+ field.setFieldValueFromOutside(null);
+ if (!parent.isDisposed()) {
+ field.getChangeControl().setEnabled(false);
+ // TODO RMF 1/10/2009 - The change control probably isn't the control whose color we ought to change...
+ field.getChangeControl().setBackground(colorBluish);
+ }
+ // Pretend that this was set at the project level?
+ // (It was certainly cleared at that level)
+ return IPreferencesService.PROJECT_LEVEL;
+ }
+
+ // Otherwise, we have a legitimate level, so set normally
+ String levelFromWhichSet = field.loadWithInheritance();
+
+ // Note: You can evidently load a field even when its control
+ // is disposed. In that case (evidently) you can change the
+ // text in the field but not the background color.
+
+ if (parent != null && !parent.isDisposed()) {
+ // TODO RMF 1/10/2009 - The change control probably isn't the control whose color we ought to change...
+ if (level != null && level.equals(levelFromWhichSet)) {
+ field.getChangeControl().setBackground(colorWhite);
+ } else if (level != null && field.getChangeControl().getEnabled()) {
+ field.getChangeControl().setBackground(colorBluish);
+ }
+ } else {
+ // If composite.isDisposed(), then both field.getTextControl(composite)
+ // and field.getTextControl() will return null; if needed, a text control
+ // must be obtained from somewhere else--but I have no idea where that
+ // might be. Not sure why composite.isDisposed() here in the first place,
+ // especially considering that the field can be set
+ }
+
+ return levelFromWhichSet;
+ }
+
+ public String setField(ColorFieldEditor field, Composite parent)
+ {
+ // TODO: Add checks on input validity (see below)
+ // Note: so far assumes that the given level is the one to which the
+ // field belongs (which should be true but isn't guaranteed (?))
+
+ String level = field.getPreferencesLevel();
+
+ // If the level is "project" and project == null then just set
+ // the field here (as a special case).
+ // Note: without some project selected the field should not be
+ // editable. Field will have to be set back to editable when
+ // (and probably where) a project is selected. We might take
+ // care of this elsewhere but, until that is verified, keep
+ // doing it here.
+ // Note also: loadWithInheritance (which calls setField(..))
+ // won't know that project == null and will try to set the field
+ // from some higher level
+ if (IPreferencesService.PROJECT_LEVEL.equals(level) && service.getProject() == null)
+ {
+ if (parent == null) {
+ System.err.println("PreferencesUtilities.setField(): parent is null");
+ }
+ if (parent.isDisposed()) {
+ System.err.println("PreferencesUtilities.setField(): parent is disposed");
+ }
+ field.setFieldValueFromOutside(null);
+ if (!parent.isDisposed()) {
+ field.getColorSelector().setEnabled(false);
+ // TODO RMF 1/10/2009 - The change control probably isn't the control whose color we ought to change...
+ field.getLabelControl(parent).setBackground(colorBluish);
+ }
+ // Pretend that this was set at the project level?
+ // (It was certainly cleared at that level)
+ return IPreferencesService.PROJECT_LEVEL;
+ }
+
+ // Otherwise, we have a legitimate level, so set normally
+ String levelFromWhichSet = field.loadWithInheritance();
+
+ // Note: You can evidently load a field even when its control
+ // is disposed. In that case (evidently) you can change the
+ // text in the field but not the background color.
+
+ if (parent != null && !parent.isDisposed()) {
+ // TODO RMF 1/10/2009 - The change control probably isn't the control whose color we ought to change...
+ if (level != null && level.equals(levelFromWhichSet)) {
+ field.getLabelControl(parent).setBackground(colorWhite);
+ } else if (level != null && field.getLabelControl(parent).getEnabled()) {
+ field.getLabelControl(parent).setBackground(colorBluish);
+ }
+ } else {
+ // If composite.isDisposed(), then both field.getTextControl(composite)
+ // and field.getTextControl() will return null; if needed, a text control
+ // must be obtained from somewhere else--but I have no idea where that
+ // might be. Not sure why composite.isDisposed() here in the first place,
+ // especially considering that the field can be set
+ }
+
+ return levelFromWhichSet;
+ }
+
+ // RMF 1/10/2009 - Not sure this is at all necessary... but does it hurt? The X10DT PrefUtils did this...
+ protected void initializeField(FieldEditor pe, PreferencePage page) {
+ if (page instanceof IPropertyChangeListener) {
+ pe.setPropertyChangeListener((IPropertyChangeListener)page);
+ }
+ pe.setPreferenceStore(page.getPreferenceStore());
+
+ }
+
+ public BooleanFieldEditor makeNewBooleanField(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service,
+ String level, String key, String text, String toolTip,
+ Composite parent,
+ boolean isEnabled, boolean isEditable, boolean hasSpecialValue, boolean specialValue,
+ boolean emptyValueAllowed, boolean emptyValue, boolean isRemovable)
+ {
+ //System.err.println("SPU.makeNewBooleanField() starting for key = " + key);
+ Composite fieldHolder = new Composite(parent, SWT.NONE);
+ fieldHolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ BooleanFieldEditor field = new BooleanFieldEditor(page, tab, service, level, key, text, fieldHolder);
+
+ field.setToolTipText(toolTip);
+ if (level != null && level.equals(IPreferencesService.PROJECT_LEVEL) && service.getProject() != null) {
+ setField(field, fieldHolder);
+ addBooleanPropertyChangeListeners(service, level, field, key, fieldHolder);
+ } else {
+ setField(field, fieldHolder);
+ addBooleanPropertyChangeListeners(service, level, field, key, fieldHolder);
+ }
+ field.getChangeControl().setEnabled(isEnabled);
+ // boolean controls have no setEditable() method
+ // SMS 19 Jun 2007
+ if (!hasSpecialValue)
+ field.setNoSpecialValue();
+ else
+ field.setSpecialValue(specialValue);
+ // also cannot be empty
+ //field.setEmptyValueAllowed(false);
+
+ if (level == null) field.setRemovable(false);
+ else if (level.equals(IPreferencesService.DEFAULT_LEVEL)) field.setRemovable(false);
+ else field.setRemovable(isRemovable);
+
+ initializeField(field, page);
+ return field;
+ }
+
+
+ public ComboFieldEditor makeNewComboField(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level,
+ String name, String labelText, String toolTip,
+ int numColumns, String[] valueList, String[] labelList,
+ Composite parent, boolean isEnabled, boolean isRemovable)
+ {
+ // Note: for a RadioGroupFieldEditor, the Radio Box plays the
+ // role of fieldHolder, and that is created by the Radio Group.
+ // It appears to work to use the parent as the container of the field here.
+ // Not sure if this may still be unnecessary
+ Composite fieldHolder = new Composite(parent, SWT.NONE);
+ fieldHolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ boolean onProjectLevelWithNullProject =
+ level != null && level.equals(IPreferencesService.PROJECT_LEVEL) && service.getProject() == null;
+ //boolean notOnARealLevel = level == null;
+ //boolean onAFunctioningLevel = !onProjectLevelWithNullProject && !notOnARealLevel;
+
+ ComboFieldEditor field = new ComboFieldEditor(page, tab, service, level,
+ name, labelText, valueList, labelList, numColumns, fieldHolder,
+ isEnabled, isRemovable);
+
+ field.setToolTipText(toolTip);
+ //Composite comboControl = field.getComboBoxControl(parent);
+ //Composite radioBoxControlParent = field.getComboBoxControl(parent).getParent();
+
+ if (!onProjectLevelWithNullProject) {
+ setField(field, fieldHolder);
+ addComboPropertyChangeListeners(service, level, field, name, fieldHolder);
+ } else {
+ //setField(field, parent);
+ //addStringPropertyChangeListeners(service, level, field, key, fieldHolder);
+ }
+
+ field.setEnabled(isEnabled, fieldHolder);
+
+ if (level == null) field.setRemovable(false); // can never remove from a field that doesn't have a stored value
+ else if (level.equals(IPreferencesService.DEFAULT_LEVEL)) field.setRemovable(false); // can never remove from Default level
+ else field.setRemovable(isRemovable);
+
+ return field;
+ }
+
+ public void setupStringButtonField(StringButtonFieldEditor field,
+ PreferencePage page, PreferencesTab tab, IPreferencesService service,
+ String level, String key, String text, String toolTip,
+ boolean isEnabled, boolean isEditable, boolean emptyValueAllowed, String emptyValue, boolean isRemovable)
+ {
+ setupStringField(field, page, tab, service, level, key, text, toolTip, isEnabled, isEditable, emptyValueAllowed, emptyValue, isRemovable);
+
+ // This sort of field has a button, that should be
+ // enabled or disabled in conjunction with the text
+ field.getChangeControl(field.getParent()).setEnabled(isEnabled);
+ }
+
+ public void setupStringField(StringFieldEditor field,
+ PreferencePage page, PreferencesTab tab, IPreferencesService service,
+ String level, String key, String text, String toolTip,
+ boolean isEnabled, boolean isEditable, boolean emptyValueAllowed, String emptyValue, boolean isRemovable)
+ {
+ Composite fieldHolder = field.getParent();
+ boolean onProjectLevelWithNullProject = IPreferencesService.PROJECT_LEVEL.equals(level) && service.getProject() == null;
+ boolean notOnARealLevel = level == null;
+ boolean onAFunctioningLevel = !onProjectLevelWithNullProject && notOnARealLevel;
+
+ field.setToolTipText(toolTip);
+ if (!onProjectLevelWithNullProject) {
+ setField(field, fieldHolder);
+ addStringPropertyChangeListeners(service, level, field, key, fieldHolder);
+ }
+
+ Text textControl = field.getTextControl();
+ // Want to set enabled differently from editable since
+ // disabling has the effect of graying out whereas setting
+ // not editable leaves the appearance alone and just renders
+ // the control inoperative
+ textControl.setEnabled(isEnabled);
+ //field.setEnabled(isEnabled, fieldHolder);
+ if (onProjectLevelWithNullProject || notOnARealLevel) {
+ textControl.setEditable(false);
+ } else if (onAFunctioningLevel) {
+ textControl.setEditable(isEditable);
+ }
+
+// if (hasSpecialValue)
+// field.setSpecialValue(specialValue);
+// else
+ field.setNoSpecialValue();
+ field.setEmptyValueAllowed(emptyValueAllowed);
+
+ if (level == null) field.setRemovable(false); // can never remove from "Applicable" level (if that's what this is)
+ else if (level.equals(IPreferencesService.DEFAULT_LEVEL)) field.setRemovable(false); // can never remove from Default level
+ else field.setRemovable(isRemovable);
+ }
+
+ public FileFieldEditor makeNewFileField(
+ PreferencePage page, PreferencesTab tab, IPreferencesService service,
+ String level, String key, String text, String toolTip,
+ Composite parent,
+ boolean isEnabled, boolean isEditable, boolean hasSpecialValue, String specialValue,
+ boolean emptyValueAllowed, String emptyValue, boolean isRemovable)
+ {
+ Composite fieldHolder = new Composite(parent, SWT.NONE);
+ fieldHolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ FileFieldEditor field = new FileFieldEditor(page, tab, service, level, key, text, fieldHolder);
+
+ setupStringButtonField(field, page, tab, service, level, key, text, toolTip, isEnabled, isEditable, emptyValueAllowed, emptyValue, isRemovable);
+
+ return field;
+ }
+
+ public DirectoryFieldEditor makeNewDirectoryField(
+ PreferencePage page, PreferencesTab tab, IPreferencesService service,
+ String level, String key, String text, String toolTip,
+ Composite parent,
+ boolean isEnabled, boolean isEditable, boolean hasSpecialValue, String specialValue,
+ boolean emptyValueAllowed, String emptyValue, boolean isRemovable)
+ {
+ Composite fieldHolder = new Composite(parent, SWT.NONE);
+ fieldHolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ DirectoryFieldEditor field = new DirectoryFieldEditor(page, tab, service, level, key, text, fieldHolder);
+
+ setupStringButtonField(field, page, tab, service, level, key, text, toolTip, isEnabled, isEditable, emptyValueAllowed, emptyValue, isRemovable);
+
+ return field;
+ }
+
+ public DirectoryListFieldEditor makeNewDirectoryListField(
+ PreferencePage page, PreferencesTab tab, IPreferencesService service,
+ String level, String key, String text, String toolTip,
+ Composite parent,
+ boolean isEnabled, boolean isEditable, boolean hasSpecialValue, String specialValue,
+ boolean emptyValueAllowed, String emptyValue, boolean isRemovable)
+ {
+ Composite fieldHolder = new Composite(parent, SWT.NONE);
+ fieldHolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ DirectoryListFieldEditor field = new DirectoryListFieldEditor(page, tab, service, level, key, text, fieldHolder);
+
+ setupStringButtonField(field, page, tab, service, level, key, text, toolTip, isEnabled, isEditable, emptyValueAllowed, emptyValue, isRemovable);
+
+ return field;
+ }
+
+ public IntegerFieldEditor makeNewIntegerField(
+ PreferencePage page, PreferencesTab tab, IPreferencesService service,
+ String level, String key, String text, String toolTip,
+ Composite parent,
+ boolean isEnabled, boolean isEditable, boolean hasSpecialValue, String specialValue,
+ boolean emptyValueAllowed, String emptyValue, boolean isRemovable)
+ {
+ Composite fieldHolder = new Composite(parent, SWT.NONE);
+ fieldHolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ IntegerFieldEditor field = new IntegerFieldEditor(page, tab, service, level, key, text, fieldHolder);
+
+ setupStringField(field, page, tab, service, level, key, text, toolTip, isEnabled, isEditable, emptyValueAllowed, emptyValue, isRemovable);
+ initializeField(field, page);
+
+ return field;
+ }
+
+ public DoubleFieldEditor makeNewDoubleField(
+ PreferencePage page, PreferencesTab tab, IPreferencesService service,
+ String level, String key, String text, String toolTip,
+ Composite parent,
+ boolean isEnabled, boolean isEditable, boolean emptyValueAllowed, String emptyValue,
+ boolean isRemovable)
+ {
+ Composite fieldHolder = new Composite(parent, SWT.NONE);
+ fieldHolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ DoubleFieldEditor field = new DoubleFieldEditor(page, tab, service, level, key, text, fieldHolder);
+
+ setupStringField(field, page, tab, service, level, key, text, toolTip, isEnabled, isEditable, emptyValueAllowed, emptyValue, isRemovable);
+ initializeField(field, page);
+
+ return field;
+ }
+
+
+ public FontFieldEditor makeNewFontField(
+ PreferencePage page, PreferencesTab tab, IPreferencesService service,
+ String level, String key, String text, String toolTip,
+ Composite parent,
+ boolean isEnabled, boolean isEditable, boolean isRemovable)
+ {
+ Composite fieldHolder = new Composite(parent, SWT.NONE);
+ fieldHolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ boolean onProjectLevelWithNullProject =
+ level != null && level.equals(IPreferencesService.PROJECT_LEVEL) && service.getProject() == null;
+ boolean notOnARealLevel = level == null;
+ boolean onAFunctioningLevel = !onProjectLevelWithNullProject && !notOnARealLevel;
+
+ FontFieldEditor field = new FontFieldEditor(page, tab, service, level, key, text, fieldHolder);
+
+ field.setToolTipText(toolTip);
+ if (!onProjectLevelWithNullProject) {
+ setField(field, fieldHolder);
+ addFontPropertyChangeListeners(service, level, field, key, fieldHolder);
+ } else {
+ //setField(field, fieldHolder);
+ //addStringPropertyChangeListeners(service, level, field, key, fieldHolder);
+ }
+
+ if (onProjectLevelWithNullProject || notOnARealLevel) {
+ field.getPreviewControl().setEnabled(false);
+ // field.getPreviewControl().setEditable(false);
+ field.setEnabled(false, field.getParent());
+ } else if (onAFunctioningLevel) {
+ field.getPreviewControl().setEnabled(isEnabled);
+ // field.getTextControl().setEditable(isEditable);
+ field.setEnabled(isEnabled, field.getParent());
+ }
+
+ if (level == null) field.setRemovable(false); // can never remove from a field that doesn't have a stored value
+ else if (level.equals(IPreferencesService.DEFAULT_LEVEL)) field.setRemovable(false); // can never remove from Default level
+ else field.setRemovable(isRemovable);
+
+ initializeField(field, page);
+ return field;
+ }
+
+ public ColorFieldEditor makeNewColorField(
+ PreferencePage page, PreferencesTab tab, IPreferencesService service,
+ String level, String key, String text, String toolTip,
+ Composite parent,
+ boolean isEnabled, boolean isEditable, boolean isRemovable)
+ {
+ Composite fieldHolder = new Composite(parent, SWT.NONE);
+ fieldHolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ boolean onProjectLevelWithNullProject =
+ level != null && level.equals(IPreferencesService.PROJECT_LEVEL) && service.getProject() == null;
+ boolean notOnARealLevel = level == null;
+ boolean onAFunctioningLevel = !onProjectLevelWithNullProject && !notOnARealLevel;
+
+ ColorFieldEditor field = new ColorFieldEditor(page, tab, service, level, key, text, fieldHolder);
+
+ field.setToolTipText(toolTip);
+ if (!onProjectLevelWithNullProject) {
+ setField(field, fieldHolder);
+ addColorPropertyChangeListeners(service, level, field, key, fieldHolder);
+ } else {
+ //setField(field, fieldHolder);
+ //addStringPropertyChangeListeners(service, level, field, key, fieldHolder);
+ }
+
+ if (onProjectLevelWithNullProject || notOnARealLevel) {
+ field.getColorSelector().setEnabled(false);
+// field.getPreviewControl().setEditable(false);
+ field.setEnabled(false, field.getParent());
+ } else if (onAFunctioningLevel) {
+ field.getColorSelector().setEnabled(isEnabled);
+// field.getTextControl().setEditable(isEditable);
+ field.setEnabled(isEnabled, field.getParent());
+ }
+
+ if (level == null) field.setRemovable(false); // can never remove from a field that doesn't have a stored value
+ else if (level.equals(IPreferencesService.DEFAULT_LEVEL)) field.setRemovable(false); // can never remove from Default level
+ else field.setRemovable(isRemovable);
+
+ initializeField(field, page);
+ return field;
+ }
+
+
+ public RadioGroupFieldEditor makeNewRadioGroupField(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level,
+ String name, String labelText, String toolTip, int numColumns,
+ String[] values, String[] labels, Composite parent, boolean useGroup,
+ boolean isEnabled, boolean isRemovable)
+ {
+ // Note: for a RadioGroupFieldEditor, the Radio Box plays the
+ // role of fieldHolder, and that is created by the Radio Group.
+ // It appears to work to use the parent as the container of the field here.
+ //
+ //Composite fieldHolder = new Composite(parent, SWT.NONE);
+ //fieldHolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ boolean onProjectLevelWithNullProject =
+ level != null && level.equals(IPreferencesService.PROJECT_LEVEL) && service.getProject() == null;
+ boolean notOnARealLevel = level == null;
+ boolean onAFunctioningLevel = !onProjectLevelWithNullProject && !notOnARealLevel;
+
+ RadioGroupFieldEditor field = new RadioGroupFieldEditor(
+ page, tab, service, level, name, labelText, numColumns,
+ values, labels, parent, useGroup);
+
+ field.setToolTipText(toolTip);
+ //Composite radioBoxControl = field.getRadioBoxControl(parent);
+ //Composite radioBoxControlParent = field.getRadioBoxControl(parent).getParent();
+
+ if (!onProjectLevelWithNullProject) {
+ setField(field, parent);
+ addRadioGroupPropertyChangeListeners(service, level, field, name, parent);
+ } else {
+ //setField(field, parent);
+ //addStringPropertyChangeListeners(service, level, field, key, fieldHolder);
+ }
+
+ // Set the enabled state
+ // Assumes that RadioGroups use the Group representation for the button box;
+ // if a Group is not used, then fill out the elxe branches below accordingly
+ if (onProjectLevelWithNullProject || notOnARealLevel) {
+ if (useGroup) {
+ Group radioGroup = (Group) field.getRadioBoxControl();
+ radioGroup.setEnabled(false);
+ } else {
+ // do something else as appropriate to the representation
+ }
+ field.setEnabled(false, parent);
+ } else if (onAFunctioningLevel) {
+ if (useGroup) {
+ Group radioGroup = (Group) field.getRadioBoxControl();
+ radioGroup.setEnabled(isEnabled);
+ } else {
+ // do something else as appropriate to the representation
+ }
+ field.setEnabled(isEnabled, parent);
+ }
+
+ if (level == null) field.setRemovable(false); // can never remove from a field that doesn't have a stored value
+ else if (level.equals(IPreferencesService.DEFAULT_LEVEL)) field.setRemovable(false); // can never remove from Default level
+ else field.setRemovable(isRemovable);
+
+ return field;
+ }
+
+ public StringFieldEditor makeNewStringField(
+ PreferencePage page, PreferencesTab tab, IPreferencesService service,
+ String level, String key, String text, String toolTip,
+ Composite parent,
+ boolean isEnabled, boolean isEditable, boolean hasSpecialValue, String specialValue,
+ boolean emptyValueAllowed, String emptyValue, boolean isRemovable)
+ {
+ Composite fieldHolder = new Composite(parent, SWT.NONE);
+ fieldHolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ boolean onProjectLevelWithNullProject =
+ level != null && level.equals(IPreferencesService.PROJECT_LEVEL) && service.getProject() == null;
+ boolean notOnARealLevel = level == null;
+ boolean onAFunctioningLevel = !onProjectLevelWithNullProject && !notOnARealLevel;
+
+ StringFieldEditor field = new StringFieldEditor(page, tab, service, level, key, text, fieldHolder);
+
+ field.setToolTipText(toolTip);
+ if (!onProjectLevelWithNullProject) {
+ setField(field, fieldHolder);
+ addStringPropertyChangeListeners(service, level, field, key, fieldHolder);
+ } else {
+ //setField(field, fieldHolder);
+ //addStringPropertyChangeListeners(service, level, field, key, fieldHolder);
+ }
+
+ //field.getTextControl().setEnabled(isEnabled);
+ if (onProjectLevelWithNullProject || notOnARealLevel) {
+ //System.out.println("SPU.makeNewStringField(..): disabling all");
+ field.getTextControl().setEnabled(false);
+ field.getTextControl().setEditable(false);
+ field.setEnabled(false, field.getParent());
+ } else if (onAFunctioningLevel) {
+ //System.out.println("SPU.makeNewStringField(..): setting all to " + isEnabled);
+ field.getTextControl().setEnabled(isEnabled);
+ field.getTextControl().setEditable(isEditable);
+ field.setEnabled(isEnabled, field.getParent());
+ }
+
+ if (hasSpecialValue)
+ field.setSpecialValue(specialValue);
+ else
+ field.setNoSpecialValue();
+ field.setEmptyValueAllowed(emptyValueAllowed);
+
+ if (level == null) field.setRemovable(false); // can never remove from a field that doesn't have a stored value
+ else if (level.equals(IPreferencesService.DEFAULT_LEVEL)) field.setRemovable(false); // can never remove from Default level
+ else field.setRemovable(isRemovable);
+
+ initializeField(field, page);
+ return field;
+ }
+
+ public StringFieldEditor makeNewModifiedMarkField(
+ PreferencePage page, PreferencesTab tab, IPreferencesService service,
+ String level, String key, String text,
+ Composite parent
+// boolean isEnabled, boolean isEditable,
+// boolean hasSpecialValue, String specialValue,
+// boolean emptyValueAllowed, String emptyValue,
+// boolean isRemovable
+ )
+ {
+ //System.err.println("SPU.makeNewStringField() starting for key = " + key);
+ Composite fieldHolder = new Composite(parent, SWT.NONE);
+ fieldHolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+// boolean onProjectLevelWithNullProject =
+// level != null && level.equals(IPreferencesService.PROJECT_LEVEL) && service.getProject() == null;
+// boolean notOnARealLevel = level == null;
+// boolean onAFunctioningLevel = !onProjectLevelWithNullProject && !notOnARealLevel;
+
+ StringFieldEditor field = new StringFieldEditor(page, tab, service, level, key + "Marker", "", 1, fieldHolder);
+
+// if (!onProjectLevelWithNullProject) {
+// setField(field, fieldHolder);
+// addStringPropertyChangeListeners(service, level, field, key, fieldHolder);
+// } else {
+// //setField(field, fieldHolder);
+// //addStringPropertyChangeListeners(service, level, field, key, fieldHolder);
+// }
+
+// //field.getTextControl().setEnabled(isEnabled);
+// if (onProjectLevelWithNullProject || notOnARealLevel) {
+// //System.out.println("SPU.makeNewStringField(..): disabling all");
+// field.getTextControl().setEnabled(false);
+// field.getTextControl().setEditable(false);
+// field.setEnabled(false, field.getParent());
+// } else if (onAFunctioningLevel) {
+// //System.out.println("SPU.makeNewStringField(..): setting all to " + isEnabled);
+// field.getTextControl().setEnabled(isEnabled);
+// field.getTextControl().setEditable(isEditable);
+// field.setEnabled(isEnabled, field.getParent());
+// }
+//
+// if (hasSpecialValue)
+// field.setSpecialValue(specialValue);
+// else
+// field.setNoSpecialValue();
+// field.setEmptyValueAllowed(emptyValueAllowed);
+
+// if (level == null) field.setRemovable(false); // can never remove from a field that doesn't have a stored value
+// else if (level.equals(IPreferencesService.DEFAULT_LEVEL)) field.setRemovable(false); // can never remove from Default level
+// else field.setRemovable(isRemovable);
+
+ //System.err.println("SPU.makeNewStringField() ending for key = " + key);
+ return field;
+ }
+
+
+
+ private void addBooleanPropertyChangeListeners(
+ IPreferencesService service, String level, BooleanFieldEditor field, String key, Composite composite)
+ {
+ int levelIndex = service.getIndexForLevel(level);
+ IEclipsePreferences[] nodes = service.getNodesForLevels();
+
+ for (int i = levelIndex + 1; i < nodes.length; i++) {
+ if (nodes[i] != null) {
+ nodes[i].addPreferenceChangeListener(new BooleanPreferenceChangeListener(field, key, composite));
+ } else {
+ //System.err.println("JsdivConfigurationPreferencesPage.addPropetyChangeListeners(..): no listener added at level = " + i + "; node at that level is null");
+ }
+ }
+ }
+
+
+ public abstract class PreferenceChangeListener implements IEclipsePreferences.IPreferenceChangeListener {
+ Composite composite = null;
+ String key = null;
+ FieldEditor field = null;
+
+ public PreferenceChangeListener(FieldEditor field, String key, Composite composite) {
+ this.field = field;
+ this.key = key;
+ this.composite = composite;
+ if (!field.getParent().equals(composite)) {
+ System.err.println("PreferencesUtilities.PreferenceChangeListener(): field and composite don't match!");
+ System.err.println("\tfield = " + field.getLabelText());
+ }
+ }
+
+ abstract protected void setFieldByListener(FieldEditor field, Composite composite);
+
+ public void preferenceChange(PreferenceChangeEvent event) {
+ if (!event.getKey().equals(key)) return; // may receive many wrong events
+ if (event.getNewValue() == null && event.getOldValue() == null) return;
+ if (event.getNewValue() != null && event.getNewValue().equals(event.getOldValue())) return;
+
+ // Does the change that actually affect the field?
+ String fieldLevel = field.getPreferencesLevel();
+ String eventLevel = event.getNode().parent().name();
+ String levelAtWhichSet = field.getLevelFromWhichLoaded();
+ if (levelAtWhichSet != null && firstLevelAboveSecond(eventLevel, levelAtWhichSet))
+ return;
+
+ if (!composite.isDisposed() &&
+ (!IPreferencesService.PROJECT_LEVEL.equals(fieldLevel) || service.getProject() != null)) {
+ setFieldByListener(field, field.getParent());
+ }
+ }
+ }
+
+
+ public class BooleanPreferenceChangeListener extends PreferenceChangeListener {
+ public BooleanPreferenceChangeListener(FieldEditor field, String key, Composite composite) {
+ super(field, key, composite);
+ }
+
+ protected void setFieldByListener(FieldEditor field, Composite composite) {
+ setField((BooleanFieldEditor) field, composite);
+ }
+ }
+
+
+ public class ComboPreferenceChangeListener extends PreferenceChangeListener {
+ public ComboPreferenceChangeListener(FieldEditor field, String key, Composite composite) {
+ super(field, key, composite);
+ }
+
+ protected void setFieldByListener(FieldEditor field, Composite composite) {
+ setField((ComboFieldEditor) field, composite);
+ }
+ }
+
+
+ public class RadioGroupPreferenceChangeListener extends PreferenceChangeListener {
+ public RadioGroupPreferenceChangeListener(FieldEditor field, String key, Composite composite) {
+ super(field, key, composite);
+ }
+
+ protected void setFieldByListener(FieldEditor field, Composite composite) {
+ setField((RadioGroupFieldEditor) field, composite);
+ }
+ }
+
+
+ public class StringPreferenceChangeListener extends PreferenceChangeListener {
+ public StringPreferenceChangeListener(FieldEditor field, String key, Composite composite) {
+ super(field, key, composite);
+ }
+
+ protected void setFieldByListener(FieldEditor field, Composite composite) {
+ setField((StringFieldEditor) field, composite);
+ }
+ }
+
+
+ public class FontPreferenceChangeListener extends PreferenceChangeListener {
+ public FontPreferenceChangeListener(FieldEditor field, String key, Composite composite) {
+ super(field, key, composite);
+ }
+
+ protected void setFieldByListener(FieldEditor field, Composite composite) {
+ setField((FontFieldEditor) field, composite);
+ }
+ }
+
+ public class ColorPreferenceChangeListener extends PreferenceChangeListener {
+ public ColorPreferenceChangeListener(FieldEditor field, String key, Composite composite) {
+ super(field, key, composite);
+ }
+
+ protected void setFieldByListener(FieldEditor field, Composite composite) {
+ setField((ColorFieldEditor) field, composite);
+ }
+ }
+
+
+ protected void addComboPropertyChangeListeners(
+ IPreferencesService service, String level, ComboFieldEditor field, String key, Composite composite)
+ {
+ int levelIndex = service.getIndexForLevel(level);
+ IEclipsePreferences[] nodes = service.getNodesForLevels();
+
+ for (int i = levelIndex + 1; i < nodes.length; i++) {
+ if (nodes[i] != null) {
+ nodes[i].addPreferenceChangeListener(new ComboPreferenceChangeListener(field, key, composite));
+ } else {
+ // System.err.println("PreferencesUtilities.addComboPropertyChangeListeners(..): no listener added at level = " + i + "; node at that level is null");
+ }
+ }
+ }
+
+ protected void addRadioGroupPropertyChangeListeners(
+ IPreferencesService service, String level, RadioGroupFieldEditor field, String key, Composite composite)
+ {
+ int levelIndex = service.getIndexForLevel(level);
+ IEclipsePreferences[] nodes = service.getNodesForLevels();
+
+ for (int i = levelIndex + 1; i < nodes.length; i++) {
+ if (nodes[i] != null) {
+ nodes[i].addPreferenceChangeListener(new RadioGroupPreferenceChangeListener(field, key, composite));
+ } else {
+ // System.err.println("PreferencesUtilities.addRadioGroupPropertyChangeListeners(..): no listener added at level = " + i + "; node at that level is null");
+ }
+ }
+ }
+
+ protected void addStringPropertyChangeListeners(
+ IPreferencesService service, String level, StringFieldEditor field, String key, Composite composite)
+ {
+ int levelIndex = service.getIndexForLevel(level);
+ IEclipsePreferences[] nodes = service.getNodesForLevels();
+
+ for (int i = levelIndex + 1; i < nodes.length; i++) {
+ if (nodes[i] != null) {
+ nodes[i].addPreferenceChangeListener(new StringPreferenceChangeListener(field, key, composite));
+ } else {
+ // System.err.println("PreferencesUtilities.addStringPropertyChangeListeners(..): no listener added at level = " + i + "; node at that level is null");
+ }
+ }
+ }
+
+
+ protected void addFontPropertyChangeListeners(
+ IPreferencesService service, String level, FontFieldEditor field, String key, Composite composite)
+ {
+ int levelIndex = service.getIndexForLevel(level);
+ IEclipsePreferences[] nodes = service.getNodesForLevels();
+
+ for (int i = levelIndex + 1; i < nodes.length; i++) {
+ if (nodes[i] != null) {
+ nodes[i].addPreferenceChangeListener(new FontPreferenceChangeListener(field, key, composite));
+ } else {
+ //System.err.println("PreferencesUtilities.addFontPropertyChangeListeners(..): no listener added at level = " + i + "; node at that level is null");
+ }
+ }
+ }
+
+
+ protected void addColorPropertyChangeListeners(
+ IPreferencesService service, String level, ColorFieldEditor field, String key, Composite composite)
+ {
+ int levelIndex = service.getIndexForLevel(level);
+ IEclipsePreferences[] nodes = service.getNodesForLevels();
+
+ for (int i = levelIndex + 1; i < nodes.length; i++) {
+ if (nodes[i] != null) {
+ nodes[i].addPreferenceChangeListener(new ColorPreferenceChangeListener(field, key, composite));
+ } else {
+ //System.err.println("PreferencesUtilities.addColorPropertyChangeListeners(..): no listener added at level = " + i + "; node at that level is null");
+ }
+ }
+ }
+
+
+ public boolean firstLevelAboveSecond(String first, String second) {
+ return service.indexForLevel(first) > service.indexForLevel(second);
+ }
+
+
+
+ public void createToggleFieldListener(BooleanFieldEditor booleanField, StringFieldEditor stringField, boolean sense) {
+ createFieldControlToggle(booleanField, stringField, sense);
+ createFieldStateToggle(booleanField, stringField, sense);
+ }
+
+
+ public FieldControlToggleListener createFieldControlToggle(
+ BooleanFieldEditor booleanField, StringFieldEditor stringField, boolean sense)
+ {
+ FieldControlToggleListener listener = new FieldControlToggleListener(booleanField, stringField, sense);
+ booleanField.getChangeControl().addSelectionListener(listener);
+ return listener;
+ }
+
+
+ public FieldStateToggleListener createFieldStateToggle(
+ BooleanFieldEditor booleanField, StringFieldEditor stringField, boolean sense)
+ {
+ FieldStateToggleListener listener = new FieldStateToggleListener(booleanField, stringField, sense);
+ booleanField.setPropertyChangeListener(listener);
+ return listener;
+ }
+
+
+ /*
+ * SMS 16 Nov 2006
+ *
+ * The following two listeners toggle the enabled/editable state
+ * of a text field according to the value of a boolean field.
+ * In the wigetSelected(SelectionEvent) methods,
+ * stringField.getTextControl() returns the text field itself,
+ * which can be both enabled and editable (separately)
+ * whereas
+ * stringField.getParent() returns the larger control in which
+ * the text field occurs (e.g., a "string button" field), which
+ * will have an enabled state but not an editable state.
+ *
+ * The FieldStateToggleListener is the effective one in the examples
+ * I've developed. The FieldcontrolToggleListener isn't used now and
+ * I'm not sure it will actually have a role.
+ */
+
+ public class FieldControlToggleListener implements SelectionListener {
+ public BooleanFieldEditor booleanField = null;
+ public StringFieldEditor stringField = null;
+ boolean sense = true;
+
+ public FieldControlToggleListener(BooleanFieldEditor booleanField, StringFieldEditor stringField, boolean sense) {
+ this.booleanField = booleanField;
+ this.stringField = stringField;
+ this.sense = sense;
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ //System.out.println("SPU.FieldControlToggleListener.wigetSelected(..)");
+ boolean value = booleanField.getBooleanValue();
+ value = sense? value : !value;
+ stringField.getTextControl().setEditable(value);
+ stringField.getTextControl().setEnabled(value);
+ stringField.setEnabled(value, stringField.getParent());
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ //System.out.println("SPU.FieldControlToggleListener.wigetDefaultSelected(..)");
+ boolean value = booleanField.getBooleanValue();
+ value = sense? value : !value;
+ stringField.getTextControl().setEditable(value);
+ stringField.getTextControl().setEnabled(value);
+ stringField.setEnabled(value, stringField.getParent());
+ }
+ }
+
+
+ public class FieldStateToggleListener implements IPropertyChangeListener {
+ public BooleanFieldEditor booleanField = null;
+ public StringFieldEditor stringField = null;
+ boolean sense = true;
+
+ public FieldStateToggleListener(BooleanFieldEditor booleanField, StringFieldEditor stringField, boolean sense) {
+ this.booleanField = booleanField;
+ this.stringField = stringField;
+ this.sense = sense;
+ }
+
+ public void propertyChange(PropertyChangeEvent event) {
+ //System.out.println("SPU.FieldStateToggleListener.propertyChange(..)");
+ boolean value = ((Boolean)event.getNewValue()).booleanValue();
+ value = sense? value : !value;
+ stringField.getTextControl().setEditable(value);
+ stringField.getTextControl().setEnabled(value);
+ stringField.setEnabled(value, stringField.getParent());
+ }
+ }
+
+
+
+ public Link createDetailsLink(Composite parent, final BooleanFieldEditor field, final Composite fieldHolder, String text) {
+ Composite detailsHolder = new Composite(parent, SWT.NONE);
+ GridLayout gl = new GridLayout();
+ detailsHolder.setLayout(gl);
+
+ Link link = new Link(detailsHolder, SWT.NONE);
+ link.setFont(detailsHolder.getFont());
+ link.setText("<A>" + text + "</A>");
+
+ final class DetailsLinkListener implements SelectionListener {
+ //DetailsLinkListener(Composite fieldHolder) {
+ //}
+ public void widgetSelected(SelectionEvent e) {
+ doDetailsLinkActivated((Link) e.widget, field, fieldHolder);
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ doDetailsLinkActivated((Link) e.widget, field, fieldHolder);
+ }
+ }
+ DetailsLinkListener detailsLinkListener = new DetailsLinkListener(/*detailsHolder*/);
+
+ link.addSelectionListener(detailsLinkListener);
+
+ return link;
+ }
+
+
+ public Link createDetailsLink(Composite detailsHolder, final ComboFieldEditor field, final Composite fieldHolder, String text) {
+ Link link = new Link(detailsHolder, SWT.NONE);
+ link.setFont(detailsHolder.getFont());
+ // Blanks added ahead of text to better align vertically links
+ // for text fields with links for boolean fields. This is a
+ // kludge and should be done some better way, but right now
+ // it's not worth the effort to figure that out.
+ link.setText(" <A>" + text + "</A>");
+
+ final class DetailsLinkListener implements SelectionListener {
+ DetailsLinkListener(Composite fieldHolder) {
+ }
+ public void widgetSelected(SelectionEvent e) {
+ doDetailsLinkActivated((Link) e.widget, field, fieldHolder);
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ doDetailsLinkActivated((Link) e.widget, field, fieldHolder);
+ }
+ }
+ DetailsLinkListener detailsLinkListener = new DetailsLinkListener(detailsHolder);
+
+ link.addSelectionListener(detailsLinkListener);
+
+ return link;
+ }
+
+ public Link createDetailsLink(Composite detailsHolder, final RadioGroupFieldEditor field, final Composite fieldHolder, String text) {
+ Link link = new Link(detailsHolder, SWT.NONE);
+ link.setFont(detailsHolder.getFont());
+ // Blanks added ahead of text to better align vertically links
+ // for text fields with links for boolean fields. This is a
+ // kludge and should be done some better way, but right now
+ // it's not worth the effort to figure that out.
+ link.setText(" <A>" + text + "</A>");
+
+ final class DetailsLinkListener implements SelectionListener {
+ DetailsLinkListener(Composite fieldHolder) {
+ }
+ public void widgetSelected(SelectionEvent e) {
+ doDetailsLinkActivated((Link) e.widget, field, fieldHolder);
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ doDetailsLinkActivated((Link) e.widget, field, fieldHolder);
+ }
+ }
+ DetailsLinkListener detailsLinkListener = new DetailsLinkListener(detailsHolder);
+
+ link.addSelectionListener(detailsLinkListener);
+
+ return link;
+ }
+
+ public Link createDetailsLink(Composite detailsHolder, final StringFieldEditor field, final Composite fieldHolder, String text) {
+ Link link = new Link(detailsHolder, SWT.NONE);
+ link.setFont(detailsHolder.getFont());
+ // Blanks added ahead of text to better align vertically links
+ // for text fields with links for boolean fields. This is a
+ // kludge and should be done some better way, but right now
+ // it's not worth the effort to figure that out.
+ link.setText(" <A>" + text + "</A>");
+
+ final class DetailsLinkListener implements SelectionListener {
+ DetailsLinkListener(Composite fieldHolder) {
+ }
+ public void widgetSelected(SelectionEvent e) {
+ doDetailsLinkActivated((Link) e.widget, field, fieldHolder);
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ doDetailsLinkActivated((Link) e.widget, field, fieldHolder);
+ }
+ }
+ DetailsLinkListener detailsLinkListener = new DetailsLinkListener(detailsHolder);
+
+ link.addSelectionListener(detailsLinkListener);
+
+ return link;
+ }
+
+
+ public Link createDetailsLinkDefault(Composite detailsHolder, final BooleanFieldEditor field, final Composite fieldHolder, String text) {
+ Link link = new Link(detailsHolder, SWT.NONE);
+ link.setFont(detailsHolder.getFont());
+ link.setText("<A>" + text + "</A>");
+
+ final class DetailsLinkListener implements SelectionListener {
+ DetailsLinkListener(Composite fieldHolder) {
+ }
+ public void widgetSelected(SelectionEvent e) {
+ doDetailsLinkActivated((Link) e.widget, field, fieldHolder);
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ doDetailsLinkActivated((Link) e.widget, field, fieldHolder);
+ }
+ }
+ DetailsLinkListener detailsLinkListener = new DetailsLinkListener(detailsHolder);
+
+ link.addSelectionListener(detailsLinkListener);
+
+ return link;
+ }
+
+ public Link createDetailsLink(Composite detailsHolder, final FontFieldEditor field, final Composite fieldHolder, String text) {
+ Link link = new Link(detailsHolder, SWT.NONE);
+ link.setFont(detailsHolder.getFont());
+ // Blanks added ahead of text to better align vertically links
+ // for text fields with links for boolean fields. This is a
+ // kludge and should be done some better way, but right now
+ // it's not worth the effort to figure that out.
+ link.setText(" <A>" + text + "</A>");
+
+ final class DetailsLinkListener implements SelectionListener {
+ DetailsLinkListener(Composite fieldHolder) {
+ }
+ public void widgetSelected(SelectionEvent e) {
+ doDetailsLinkActivated((Link) e.widget, field, fieldHolder);
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ doDetailsLinkActivated((Link) e.widget, field, fieldHolder);
+ }
+ }
+ DetailsLinkListener detailsLinkListener = new DetailsLinkListener(detailsHolder);
+
+ link.addSelectionListener(detailsLinkListener);
+
+ return link;
+ }
+
+
+ final void doDetailsLinkActivated(Link link, BooleanFieldEditor field, Composite fieldHolder) {
+ DetailsDialogForBooleanFields dialog = new DetailsDialogForBooleanFields(fieldHolder.getShell(), field, fieldHolder, service);
+ dialog.open();
+ }
+
+
+ final void doDetailsLinkActivated(Link link, ComboFieldEditor field, Composite fieldHolder) {
+ DetailsDialogForComboFields dialog = new DetailsDialogForComboFields(fieldHolder.getShell(), field, fieldHolder, service);
+ dialog.open();
+ }
+
+
+ final void doDetailsLinkActivated(Link link, RadioGroupFieldEditor field, Composite fieldHolder) {
+ DetailsDialogForRadioGroupFields dialog = new DetailsDialogForRadioGroupFields(fieldHolder.getShell(), field, fieldHolder, service);
+ dialog.open();
+ }
+
+
+ void doDetailsLinkActivated(Link link, StringFieldEditor field, Composite fieldHolder) {
+ DetailsDialogForStringFields dialog = new DetailsDialogForStringFields(fieldHolder.getShell(), field, fieldHolder, service);
+ dialog.open();
+ }
+
+
+ final void doDetailsLinkActivated(Link link, FontFieldEditor field, Composite fieldHolder) {
+ DetailsDialogForFontFields dialog = new DetailsDialogForFontFields(fieldHolder.getShell(), field, fieldHolder, service);
+ dialog.open();
+ }
+
+
+ final void doDetailsLinkActivated(Link link, ColorFieldEditor field, Composite fieldHolder) {
+ DetailsDialogForColorFields dialog = new DetailsDialogForColorFields(fieldHolder.getShell(), field, fieldHolder, service);
+ dialog.open();
+ }
+
+
+ /*
+ * Elements relating to project selection
+ * (As of 13 Sep 2006 these are only needed in the project preferences tab,
+ * so I have not made versions of them publicly available in the utilities
+ * class. They might be represented here if and when there is a need for
+ * creating project selection/deselection links in other places.)
+ */
+
+
+ public Control[] createDefaultAndApplyButtons(Composite parent, final PreferencesTab buttonHolder) {
+ Composite buttonBar = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 0;
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ layout.makeColumnsEqualWidth = false;
+ buttonBar.setLayout(layout);
+
+ GridData bbgd = new GridData(SWT.END);
+ buttonBar.setLayoutData(bbgd);
+
+ //contributeButtons(buttonBar);
+ boolean createDefaultAndApplyButton = true;
+ if (createDefaultAndApplyButton) {
+ layout.numColumns = layout.numColumns + 2;
+ String[] labels = JFaceResources.getStrings(new String[] {
+ "defaults", "apply" }); //$NON-NLS-2$//$NON-NLS-1$
+ //int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
+ Button defaultsButton = new Button(buttonBar, SWT.PUSH);
+ defaultsButton.setText(labels[0]);
+ Dialog.applyDialogFont(defaultsButton);
+ //GridData
+ GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+ Point minButtonSize = defaultsButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
+ //data.widthHint = Math.max(widthHint, minButtonSize.x);
+ defaultsButton.setLayoutData(data);
+ defaultsButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ buttonHolder.performDefaults();
+ }
+ });
+
+ Button applyButton = new Button(buttonBar, SWT.PUSH);
+ applyButton.setText(labels[1]);
+ Dialog.applyDialogFont(applyButton);
+ data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+ minButtonSize = applyButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
+ //data.widthHint = Math.max(widthHint, minButtonSize.x);
+ applyButton.setLayoutData(data);
+ applyButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ buttonHolder.performApply();
+ }
+ });
+ //applyButton.setEnabled(true); //isValid());
+ Dialog.applyDialogFont(buttonBar);
+ } else {
+ /* Check if there are any other buttons on the button bar.
+ * If not, throw away the button bar composite. Otherwise
+ * there is an unusually large button bar.
+ */
+ if (buttonBar.getChildren().length < 1)
+ buttonBar.dispose();
+ }
+ return buttonBar.getChildren();
+ }
+
+
+ /*
+ * For laying out grid data in widgets for preferences pages (or anything else)
+ */
+ public static void fillGridPlace(Composite composite, int num) {
+ for (int i = 1; i <= num; i++) {
+ Label label = new Label(composite, SWT.NONE);
+ label.setText("This space intentionally left blank");
+ label.setVisible(false);
+ }
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/ProjectPreferencesTab.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/ProjectPreferencesTab.java
new file mode 100644
index 000000000..08ca5ed92
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/ProjectPreferencesTab.java
@@ -0,0 +1,499 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.preferences;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.imp.preferences.PreferencesUtilities.PreferenceChangeListener;
+import org.eclipse.imp.preferences.fields.BooleanFieldEditor;
+import org.eclipse.imp.preferences.fields.ColorFieldEditor;
+import org.eclipse.imp.preferences.fields.ComboFieldEditor;
+import org.eclipse.imp.preferences.fields.FontFieldEditor;
+import org.eclipse.imp.preferences.fields.RadioGroupFieldEditor;
+import org.eclipse.imp.preferences.fields.StringFieldEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.ui.dialogs.ContainerSelectionDialog;
+import org.osgi.service.prefs.Preferences;
+
+public abstract class ProjectPreferencesTab extends PreferencesTab {
+ protected List<Link> detailsLinks = new ArrayList<Link>();
+
+ protected IProject fProject = null;
+
+ protected Combo selectedProjectCombo;
+
+ public ProjectPreferencesTab(IPreferencesService prefService, boolean noDetails) {
+ super(IPreferencesService.PROJECT_LEVEL, noDetails);
+ this.fPrefService = prefService;
+ fPrefUtils = new PreferencesUtilities(prefService);
+ }
+
+ @Override
+ public Composite createTabContents(TabbedPreferencesPage page, final TabFolder tabFolder) {
+ fPrefPage = page;
+
+ int numColumns= getNoDetails() ? 1 : 2;
+
+ GridLayout layout = null;
+
+ final Composite composite= new Composite(tabFolder, SWT.NONE);
+ composite.setFont(tabFolder.getFont());
+ final GridData gd= new GridData(SWT.FILL, SWT.CENTER, true, false);
+ gd.widthHint= 0;
+ gd.heightHint= SWT.DEFAULT;
+ gd.horizontalSpan= 1;
+ composite.setLayoutData(gd);
+
+ layout = new GridLayout();
+ layout.numColumns = numColumns;
+ composite.setLayout(layout);
+
+ // The "tab" on the tab folder
+ fTabItem = new TabItem(tabFolder, SWT.NONE);
+ fTabItem.setText("Project");
+ fTabItem.setControl(composite);
+ PreferencesTab.TabSelectionListener listener =
+ new PreferencesTab.TabSelectionListener(fPrefPage, fTabItem);
+ tabFolder.addSelectionListener(listener);
+
+ /*
+ * Add the elements relating to preferences fields and their associated "details" links.
+ */
+ fFields = createFields(page, composite);
+
+
+ // Clear some space
+ PreferencesUtilities.fillGridPlace(composite, numColumns);
+
+ // Disable the details links since no project is selected at the start
+ for (int i = 0; i < detailsLinks.size(); i++) {
+ ((Link)detailsLinks.get(i)).setEnabled(false);
+ }
+
+ PreferencesUtilities.fillGridPlace(composite, 2);
+
+ // Being newly loaded, the fields may be displayed with some
+ // indication that they have been modified. This should reset
+ // that marking.
+ clearModifiedMarksOnLabels();
+
+ /*
+ * Put in the elements related to selecting a project
+ */
+ Group groupHolder = new Group(composite, SWT.SHADOW_ETCHED_IN);
+ groupHolder.setText("Project selection");
+ groupHolder.setLayout(new GridLayout(2, false));
+ groupHolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Label projLabel= new Label(groupHolder, SWT.LEFT);
+ projLabel.setText("Project:");
+
+ selectedProjectCombo= new Combo(groupHolder, SWT.DROP_DOWN | SWT.READ_ONLY);
+ final Combo projCombo= selectedProjectCombo;
+ IProject[] pluginProjects= ResourcesPlugin.getWorkspace().getRoot().getProjects();
+
+ projCombo.add("none selected");
+ for(int i= 0; i < pluginProjects.length; i++) {
+ projCombo.add(pluginProjects[i].getName());
+ }
+ projCombo.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) { }
+
+ public void widgetSelected(SelectionEvent e) {
+ String projName= projCombo.getText();
+ ProjectPreferencesTab.this.fPrefService.setProjectName(projName);
+ }
+ });
+ projCombo.setSize(150, 24);
+ Label pad = new Label(groupHolder, SWT.NONE);
+
+ // Clear these here in case there are any saved from a previous interaction with the page
+ // (assuming that we should start each new page with no project selected)
+ fPrefService.clearPreferencesAtLevel(IPreferencesService.PROJECT_LEVEL);
+
+ addProjectSelectionListener(composite);
+
+ PreferencesUtilities.fillGridPlace(composite, 3);
+
+ /*
+ * Put explanatory notes toward the bottom
+ * (not sure whether WRAP is helpful here; can manually
+ * wrap text in labels with '\n')
+ */
+
+ final Composite bottom = new Composite(composite, SWT.BOTTOM | SWT.WRAP);
+ layout = new GridLayout();
+ bottom.setLayout(layout);
+ bottom.setLayoutData(new GridData(SWT.BOTTOM));
+
+ Label bar = new Label(bottom, SWT.WRAP);
+ GridData data = new GridData();
+ data.verticalAlignment = SWT.WRAP;
+ bar.setLayoutData(data);
+ bar.setText("Preferences are shown here only when a project is selected.\n\n" +
+ "Preferences shown with a white background are set on this level.\n\n" +
+ "Preferences shown with a colored background are inherited from a\nhigher level.\n\n" +
+ Markings.MODIFIED_NOTE + "\n\n" +
+ Markings.TAB_ERROR_NOTE);
+
+ PreferencesUtilities.fillGridPlace(bottom, 1);
+
+ /*
+ * Put Restore Defaults and Apply buttons at the very bottom,
+ * disabled if (as expected) there is no project selected and
+ * the tab is otherwise mainly disabled
+ */
+ fButtons = fPrefUtils.createDefaultAndApplyButtons(composite, this);
+ if (fPrefService.getProject() == null) {
+ for (int i = 0; i < fButtons.length; i++)
+ fButtons[i].setEnabled(false);
+ }
+ return composite;
+ }
+
+
+ private void addProjectSelectionListener(Composite composite)
+ {
+ fPrefService.addProjectSelectionListener(new ProjectSelectionListener(composite));
+ }
+
+
+
+ private class ProjectSelectionListener implements PreferencesService.IProjectSelectionListener
+ {
+ Composite composite = null;
+ IEclipsePreferences.IPreferenceChangeListener currentListener = null;
+
+ ProjectSelectionListener(Composite composite) {
+ this.composite = composite;
+ }
+
+ /**
+ * Notification that a project was selected for inclusion in the preferences hierarchy.
+ * The given event must not be <code>null</code>.
+ *
+ * @param event an event specifying the details about the new node
+ * @see IEclipsePreferences.NodeChangeEvent
+ * @see IEclipsePreferences#addNodeChangeListener(IEclipsePreferences.INodeChangeListener)
+ * @see IEclipsePreferences#removeNodeChangeListener(IEclipsePreferences.INodeChangeListener)
+ */
+ public void selection(IPreferencesService.ProjectSelectionEvent event) {
+ addressProjectSelection(event, composite);
+ }
+ }
+
+
+ protected List<PreferenceChangeListener> currentListeners = new ArrayList<PreferenceChangeListener>();
+ protected List<IEclipsePreferences> currentListenerNodes = new ArrayList<IEclipsePreferences>();
+
+
+ protected void addressProjectSelection(IPreferencesService.ProjectSelectionEvent event, Composite composite) {
+ // TODO: Override in subtype with a real implementation
+// System.err.println("ProjectPreferencesTab.addressProjectSelection(..): unimplemented");
+
+ // SMS 20 Jun 2007
+ // Adding code from JikesPG project tab implementation to try
+ // to flesh out a skeleton (field-independent) implementation)
+ // just to see what there may be of that
+ boolean haveCurrentListeners = false;
+
+ Preferences oldeNode = event.getPrevious();
+ Preferences newNode = event.getNew();
+
+ if (oldeNode == null && newNode == null) {
+ // This is what happens for some reason when you clear the project selection.
+ // Nothing, really, to do in this case ...
+ return;
+ }
+
+ // If oldeNode is not null, we want to remove any preference-change listeners from it
+ if (oldeNode != null && oldeNode instanceof IEclipsePreferences && haveCurrentListeners) {
+ removeProjectPreferenceChangeListeners();
+ haveCurrentListeners = false;
+ } else {
+ // Print an advisory message if you want to
+ }
+
+ // If we have a new project preferences node, then do various things
+ // to set up the project's preferences
+ if (newNode != null && newNode instanceof IEclipsePreferences) {
+ // If the containing composite is not disposed, then set the fields' values
+ // and make them enabled and editable (as appropriate to the type of field)
+
+ if (!composite.isDisposed()) {
+ // Note: Where there are toggles between fields, it is a good idea to set the
+ // properties of the dependent field here according to the values they should have
+ // based on the independent field. There should be listeners to take care of
+ // that sort of adjustment once the tab is established, but when properties are
+ // first initialized here, the properties may not always be set correctly through
+ // the toggle. I'm not entirely sure why that happens, except that there may be
+ // a race condition between the setting of the dependent values by the listener
+ // and the setting of those values here. If the values are set by the listener
+ // first (which might be surprising, but may be possible) then they will be
+ // overwritten by values set here--so the values set here should be consistent
+ // with what the listener would set.
+
+ // Used in setting enabled and editable status
+// boolean enabledState = false;
+
+ // Example:
+// // Pretend field1 is a boolean field (checkbox)
+// prefUtils.setField(field1, field1.getHolder());
+// field1.getChangeControl().setEnabled(true);
+//
+// // Pretend field2 is a text-based field
+// prefUtils.setField(field2, field2.getHolder());
+// // field2 enabled iff field1 not checked
+// enabledState = !field1.getBooleanValue();
+// field2.getTextControl().setEditable(enabledState);
+// field2.getTextControl().setEnabled(enabledState);
+// field2.setEnabled(enabledState, field2.getParent());
+
+ // And so on for other fields
+
+ clearModifiedMarksOnLabels();
+ }
+
+ // Add property change listeners
+ // Example
+// if (field1.getHolder() != null) addProjectPreferenceChangeListeners(field1, PreferenceConstants.P_FIELD_1, field1.getHolder());
+// if (field2.getHolder() != null) addProjectPreferenceChangeListeners(fieldw, PreferenceConstants.P_FIELD_2, field2.getHolder());
+ // And so on for other fields ...
+
+ haveCurrentListeners = true;
+ }
+
+ // Or if we don't have a new project preferences node ...
+ if (newNode == null || !(newNode instanceof IEclipsePreferences)) {
+ // May happen when the preferences page is first brought up, or
+ // if we allow the project to be deselected
+
+ // Clear the preferences from the store
+ fPrefService.clearPreferencesAtLevel(IPreferencesService.PROJECT_LEVEL);
+
+ // Disable fields and make them non-editable
+ if (!composite.isDisposed()) {
+ // Example:
+// field1.getChangeControl().setEnabled(false);
+//
+// field2.getTextControl(field2.getHolder()).setEnabled(false);
+// field2.getTextControl(field2.getHolder()).setEditable(false);
+ }
+
+ // Remove listeners
+ removeProjectPreferenceChangeListeners();
+ haveCurrentListeners = false;
+ }
+ }
+
+
+
+ protected void addProjectPreferenceChangeListeners(BooleanFieldEditor field, String key, Composite composite)
+ {
+ IEclipsePreferences[] nodes = fPrefService.getNodesForLevels();
+ for (int i = IPreferencesService.PROJECT_INDEX; i < nodes.length; i++) {
+ if (nodes[i] != null) {
+ PreferencesUtilities.BooleanPreferenceChangeListener listener =
+ fPrefUtils.new BooleanPreferenceChangeListener(field, key, composite);
+ nodes[i].addPreferenceChangeListener(listener);
+ currentListeners.add(listener);
+ currentListenerNodes.add(nodes[i]);
+ } else {
+ //System.err.println("ProjectPreferencesTab.addPropertyChangeListeners(..): no listener added at level = " + i + "; node at that level is null");
+ }
+ }
+ }
+
+
+ protected void addProjectPreferenceChangeListeners(FontFieldEditor field, String key, Composite composite)
+ {
+ IEclipsePreferences[] nodes = fPrefService.getNodesForLevels();
+ for (int i = IPreferencesService.PROJECT_INDEX; i < nodes.length; i++) {
+ if (nodes[i] != null) {
+ PreferencesUtilities.FontPreferenceChangeListener listener =
+ fPrefUtils.new FontPreferenceChangeListener(field, key, composite);
+ nodes[i].addPreferenceChangeListener(listener);
+ currentListeners.add(listener);
+ currentListenerNodes.add(nodes[i]);
+ } else {
+ //System.err.println("ProjectPreferencesTab.addPropertyChangeListeners(..): no listener added at level = " + i + "; node at that level is null");
+ }
+ }
+ }
+
+
+ protected void addProjectPreferenceChangeListeners(ColorFieldEditor field, String key, Composite composite)
+ {
+ IEclipsePreferences[] nodes = fPrefService.getNodesForLevels();
+ for (int i = IPreferencesService.PROJECT_INDEX; i < nodes.length; i++) {
+ if (nodes[i] != null) {
+ PreferencesUtilities.ColorPreferenceChangeListener listener =
+ fPrefUtils.new ColorPreferenceChangeListener(field, key, composite);
+ nodes[i].addPreferenceChangeListener(listener);
+ currentListeners.add(listener);
+ currentListenerNodes.add(nodes[i]);
+ } else {
+ //System.err.println("ProjectPreferencesTab.addPropertyChangeListeners(..): no listener added at level = " + i + "; node at that level is null");
+ }
+ }
+ }
+
+
+ protected void addProjectPreferenceChangeListeners(ComboFieldEditor field, String key, Composite composite)
+ {
+ IEclipsePreferences[] nodes = fPrefService.getNodesForLevels();
+ for (int i = IPreferencesService.PROJECT_INDEX; i < nodes.length; i++) {
+ if (nodes[i] != null) {
+ PreferencesUtilities.ComboPreferenceChangeListener listener =
+ fPrefUtils.new ComboPreferenceChangeListener(field, key, composite);
+ nodes[i].addPreferenceChangeListener(listener);
+ currentListeners.add(listener);
+ currentListenerNodes.add(nodes[i]);
+ } else {
+ //System.err.println("ProjectPreferencesTab.addPropertyChangeListeners(..): no listener added at level = " + i + "; node at that level is null");
+ }
+ }
+ }
+
+
+ protected void addProjectPreferenceChangeListeners(RadioGroupFieldEditor field, String key, Composite composite)
+ {
+ IEclipsePreferences[] nodes = fPrefService.getNodesForLevels();
+ for (int i = IPreferencesService.PROJECT_INDEX; i < nodes.length; i++) {
+ if (nodes[i] != null) {
+ PreferencesUtilities.RadioGroupPreferenceChangeListener listener =
+ fPrefUtils.new RadioGroupPreferenceChangeListener(field, key, composite);
+ nodes[i].addPreferenceChangeListener(listener);
+ currentListeners.add(listener);
+ currentListenerNodes.add(nodes[i]);
+ } else {
+ //System.err.println("ProjectPreferencesTab.addPropertyChangeListeners(..): no listener added at level = " + i + "; node at that level is null");
+ }
+ }
+ }
+
+ protected void addProjectPreferenceChangeListeners(StringFieldEditor field, String key, Composite composite)
+ {
+ IEclipsePreferences[] nodes = fPrefService.getNodesForLevels();
+ for (int i = IPreferencesService.PROJECT_INDEX; i < nodes.length; i++) {
+ if (nodes[i] != null) {
+ // SMS 31 Oct 2006
+ //ProjectPreferenceChangeListener listener = new ProjectPreferenceChangeListener(field, key, composite);
+ PreferencesUtilities.StringPreferenceChangeListener listener =
+ fPrefUtils.new StringPreferenceChangeListener(field, key, composite);
+ nodes[i].addPreferenceChangeListener(listener);
+ currentListeners.add(listener);
+ currentListenerNodes.add(nodes[i]);
+ } else {
+ //System.err.println("ProjectPreferencesTab.addPropertyChangeListeners(..): no listener added at level = " + i + "; node at that level is null");
+ }
+ }
+ }
+
+
+
+ protected void removeProjectPreferenceChangeListeners()
+ {
+ // Remove all listeners from their respective nodes
+ for (int i = 0; i < currentListeners.size(); i++) {
+ ((IEclipsePreferences) currentListenerNodes.get(i)).removePreferenceChangeListener(
+ ((IEclipsePreferences.IPreferenceChangeListener)currentListeners.get(i)));
+ }
+ // Clear the lists
+ currentListeners = new ArrayList<PreferenceChangeListener>();
+ currentListenerNodes = new ArrayList<IEclipsePreferences>();
+ }
+
+
+ // SMS 20 Nov 2007:
+ protected void setProjectSelectionValidator(
+ ContainerSelectionDialog dialog, boolean validateForPluginProject, boolean validateForIDEProject)
+ {
+// dialog.setValidator(new ValidationUtils.ProjectSelectionValidator());
+ }
+
+
+ public void performApply()
+ {
+ if (fPrefService.getProject() == null) {
+ // No preferences node into which to store anything
+ clearModifiedMarksOnLabels(); // just in case fields still show modified
+ return;
+ }
+ for (int i = 0; i < fFields.length; i++) {
+ fFields[i].store();
+ fFields[i].clearModifiedMarkOnLabel();
+ }
+ }
+
+
+ public boolean performCancel() {
+ // Nullify the project in any case
+ fPrefService.setProject(null);
+ return true;
+ }
+
+
+ public void performDefaults() {
+ if (fPrefService.getProject() == null) {
+ // If no project set then there's no preferences
+ // file from which to load anything
+ return;
+ }
+
+ // Clear all preferences for this page at this level;
+ // "default" values will be set by inheritance from a higher level
+ PreferencesInitializer initializer = fPrefPage.getPreferenceInitializer();
+ initializer.clearPreferencesOnLevel(IPreferencesService.PROJECT_LEVEL);
+
+ for (int i = 0; i < fFields.length; i++) {
+ fFields[i].loadWithInheritance();
+ }
+ }
+
+
+ public boolean performOk()
+ {
+ if (fPrefService.getProject() != null) {
+ // Store each field
+ for (int i = 0; i < fFields.length; i++) {
+ fFields[i].store();
+ }
+ } else {
+ // Clear preferences because we're closing up dialog;
+ // note that a project preferences node will exist, if only
+ // in a leftover state, even when no project is selected
+ fPrefService.clearPreferencesAtLevel(IPreferencesService.PROJECT_LEVEL);
+ //return true;
+ }
+
+ // Nullify the project in any case
+ fPrefService.setProject(null);
+
+ return true;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/TabbedPreferencesPage.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/TabbedPreferencesPage.java
new file mode 100644
index 000000000..7c65b9137
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/TabbedPreferencesPage.java
@@ -0,0 +1,309 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences;
+
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+
+/**
+ * A multi-tab preferences page for IMP-supported languages.
+ * The various tabs nominally represent the same sets of preferences
+ * as set on different levels (default, workspace configuration,
+ * workspace instance, and project).
+ *
+ * @author suttons@us.ibm.com
+ */
+public abstract class TabbedPreferencesPage extends PreferencePage implements IWorkbenchPreferencePage {
+
+ // To hold tabs created by specializations of this class;
+ // used below in methods that respond to buttons
+ PreferencesTab[] tabs = new PreferencesTab[4];
+
+ // To be provided by a language-specific preferences page
+ // that is specialized from this one
+ protected IPreferencesService prefService = null;
+
+
+ public TabbedPreferencesPage() {
+ this.noDefaultAndApplyButton();
+ }
+
+ protected Control createContents(Composite parent) {
+
+ // Create a tab folder to put onto the page
+ final TabFolder tabFolder = new TabFolder(parent, SWT.NONE);
+ final GridData gd= new GridData(SWT.FILL, SWT.CENTER, true, false);
+ gd.widthHint= 0;
+ gd.heightHint= SWT.DEFAULT;
+ gd.horizontalSpan= 1;
+ tabFolder.setLayoutData(gd);
+
+ // Create the tabs that go into the tab folder
+ tabs = createTabs(prefService, this, tabFolder);
+ setInitialStateForTabs();
+
+ // The validity of the page depends on the validity of its tabs,
+ // so refresh the valid state of the page now that all of the
+ // tabs have been created
+ notifyState(true);
+
+ // Set the font on the page
+ Dialog.applyDialogFont(parent);
+
+ // If there's more than 1 tab, start out by selecting the 2nd tab
+ // (usually the "Workspace" tab), rather than the "Project" tab,
+ // which doesn't even show values until the user selects a project.
+ if (tabs.length > 1) {
+ int idx= -1;
+ for(int i= 0; i < tabs.length; i++) {
+ if (tabs[i].getLevel().equals(IPreferencesService.INSTANCE_LEVEL)) {
+ idx= i;
+ }
+ }
+ if (idx > 0) {
+ tabFolder.setSelection(idx);
+ }
+ }
+ return tabFolder;
+ }
+
+
+ /**
+ * Assure that the enabled state of conditionally enabled
+ * tabs is set appropriately.
+ *
+ * When a tab is newly created with some fields that are supposed to
+ * be enabled depending on the value of other (boolean) fields, it
+ * seems that the enabled state of the conditional fields does not
+ * get set properly. This happens despite explicit attempts to set
+ * the appropriate enabled state (perhaps due to race conditions?).
+ * Toggling of the condition fields once the tab has been created
+ * does cause the enabled state of conditional fields to be set
+ * correctly. This method automates that activity, which can be
+ * emulated on the default tab by restoring and applying the default
+ * field values. However, changes on the default tab can affect
+ * lower levels in the preferences hierarchy--values inherited from
+ * the default level do not change, but the fact that the default
+ * values have been restored causes inherited values to be marked as
+ * modified. To clear the modified marks from lower levels of the
+ * preferences hierarchy, the tabs for those levels are also applied,
+ * in a top-down order. On the project level default values are
+ * restored before being applied; this assures that the fields are
+ * empty, as they should be, because there should be no project
+ * selected at this point.
+ *
+ */
+ protected void setInitialStateForTabs() {
+ // Assure that all tabs are initialized properly
+ // and reflect an unmodified state
+ for (int i = 0; i < tabs.length; i++) {
+ if (tabs[i] instanceof DefaultPreferencesTab) {
+ tabs[i].performDefaults();
+ tabs[i].performApply();
+ break;
+ }
+ }
+ for (int i = 0; i < tabs.length; i++) {
+ if (tabs[i] instanceof ConfigurationPreferencesTab) {
+ tabs[i].performApply();
+ break;
+ }
+ }
+ for (int i = 0; i < tabs.length; i++) {
+ if (tabs[i] instanceof InstancePreferencesTab) {
+ tabs[i].performApply();
+ break;
+ }
+ }
+ for (int i = 0; i < tabs.length; i++) {
+ if (tabs[i] instanceof ProjectPreferencesTab) {
+ tabs[i].performDefaults();
+ tabs[i].performApply();
+ break;
+ }
+ }
+ }
+
+ /**
+ * Create the tabs that represent the different levels of preferences
+ * shown on this page. Nominally these are the default, workspace configuraiton,
+ * workspace instance, and project levels.
+ *
+ * @param prefService The service that manages the preferences by level
+ * @param page The page on which the tabs are to be created (that is, this page)
+ * @param tabFolder The tab folder, on this page, that will contain the created tabs
+ * @return An array containing the created tabs
+ */
+ protected abstract PreferencesTab[] createTabs(
+ IPreferencesService prefService, TabbedPreferencesPage page, TabFolder tabFolder);
+
+
+
+ /**
+ *
+ */
+ public boolean notifyState(boolean state) {
+ boolean allValid = true;
+ for (int i = 0; i < tabs.length && allValid; i++) {
+ allValid = allValid && tabs[i] != null && tabs[i].isValid();
+ }
+ setValid(allValid);
+ return allValid;
+ }
+
+
+ /*
+ * The following four operations provide a page-level response to the pressing of
+ * buttons on the page. Note, though, that a preference page may not have all of
+ * these buttons--buttons not present on the page may instead be present on individual
+ * tabs on the page.
+ */
+
+
+ /**
+ * Respond to pressing of the Apply button by saving the prevailing preferences.
+ *
+ * Note: In a system of multiple preference levels with preference-value
+ * inheritance, this may only save values on the levels on which they
+ * are stored, i.e., not on levels where they apply through inheritance only.
+ *
+ * @see org.eclipse.jface.preference.PreferencePage#performApply()
+ */
+ public void performApply()
+ {
+ for (int i = 0; i < tabs.length; i++) {
+ tabs[i].performApply();
+ }
+ }
+
+
+ /**
+ * Respond to pressing of Cancel button by cancelling in-progress
+ * preference updates on each level.
+ *
+ * @see org.eclipse.jface.preference.IPreferencePage#performCancel()
+ */
+ public boolean performCancel()
+ {
+ // SMS 4 Dec 2006
+ // Previously just used to return true; now trying to
+ // allow for a negative return
+ boolean result = true;
+ for (int i = 0; i < tabs.length; i++) {
+ // If there was a problem initializing the tabs, one or more might be null now.
+ if (tabs[i] != null) {
+ result = result && tabs[i].performCancel();
+ }
+ }
+
+ return result;
+ }
+
+
+ /**
+ * Respond to pressing of Restore Defaults button by restoring default
+ * values on each level.
+ *
+ * Note: In a system of multiple preference levels with preference-value
+ * inheritance, the default value on levels other than the default level
+ * may be considered to be the level inherited from the next higher level,
+ * so this may entail removing the preferences stored on each level other
+ * than the default level. On the default level, the programmed default
+ * values should be restored.
+ *
+ * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
+ */
+ public void performDefaults()
+ {
+ // SMS 4 Dec 2006
+ // Need to check visibility of a composite that contains the tab;
+ // be sure that the right one is checked here ...
+ for (int i = 0; i < tabs.length; i++) {
+ if (tabs[i].getTabItem().getControl().isVisible())
+ tabs[i].performDefaults();
+ }
+
+ }
+
+
+ /**
+ * Respond to pressing of the Save button by saving the prevailing preferences.
+ *
+ * Note: In a system of multiple preference levels with preference-value
+ * inheritance, this may only save values on the levels on which they
+ * are stored, i.e., not on levels where they apply through inheritance only.
+ *
+ * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
+ */
+ public boolean performOk()
+ {
+ // SMS 4 Dec 2006
+ // Not sure of the effect of returning false, but
+ // should probably allow for that
+ boolean result = true;
+ for (int i = tabs.length-1; i >= 0; i--) {
+ result = result && tabs[i].performOk();
+ }
+
+ return result;
+ }
+
+
+
+ /**
+ * For IWorkbenchPreferencePage
+ *
+ * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+ */
+ public void init(IWorkbench workbench) {
+ }
+
+
+ /**
+ * Get the tabs used on this preference page
+ *
+ * @return The tabs used on this preference page
+ */
+ protected PreferencesTab[] getTabs() {
+ return tabs;
+ }
+
+
+
+ /**
+ * Should be overridden in language-specific tabbed preferences page
+ * to make use of language-specific preference initializer.
+ *
+ * @return The preference initializer to be used to initialize
+ * preferences in this tab
+ */
+ // TODO: Probably should make this an abstract method
+ public PreferencesInitializer getPreferenceInitializer() {
+ // TODO: Override in subclass where the language-specific
+ // initializer should be known
+ System.out.println("TabbedPreferencesPage.getPreferenceInitializar(): unimplemented; should be overridden with language-specific implementation");
+ return null;
+ }
+
+
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/BooleanFieldEditor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/BooleanFieldEditor.java
new file mode 100644
index 000000000..770fa95d3
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/BooleanFieldEditor.java
@@ -0,0 +1,630 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.preferences.fields;
+
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesTab;
+import org.eclipse.imp.preferences.PreferencesUtilities;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.PlatformUI;
+import org.osgi.service.prefs.BackingStoreException;
+
+/**
+ * FieldEditor implementation for boolean preferences that support the 4-level
+ * presentation (default, installation, workspace, and project) and "details links".
+ * Based on the org.eclipse.jface.preference class of the same name.
+ * @author sutton
+ * @author rfuhrer
+ */
+public class BooleanFieldEditor extends ChangeButtonFieldEditor {
+ /*
+ * Fields copied from jface's BooleanFieldEditor
+ */
+
+ /**
+ * Style constant (value <code>0</code>) indicating the default
+ * layout where the field editor's check box appears to the left
+ * of the label.
+ */
+ public static final int DEFAULT = 0;
+
+ /**
+ * Style constant (value <code>1</code>) indicating a layout
+ * where the field editor's label appears on the left
+ * with a check box on the right.
+ */
+ public static final int SEPARATE_LABEL = 1;
+
+ /**
+ * Style bits. Either <code>DEFAULT</code> or
+ * <code>SEPARATE_LABEL</code>.
+ */
+ private int style;
+
+
+ /**
+ * The checkbox control, or <code>null</code> if none.
+ */
+ private Button checkBox = null;
+
+
+ /**
+ * Creates a boolean field editor in the given style.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param style the style, either <code>DEFAULT</code> or
+ * <code>SEPARATE_LABEL</code>
+ * @param parent the parent of the field editor's control
+ * @see #DEFAULT
+ * @see #SEPARATE_LABEL
+ */
+ public BooleanFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level,
+ String name, String labelText, int style, final Composite parent)
+ {
+ super(page, tab, service, level, name, labelText, parent);
+ this.style = style;
+ createControl(parent);
+ }
+
+
+ /**
+ * Creates a boolean field editor.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param parent the parent of the field editor's control
+ */
+ public BooleanFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level, String name, String labelText, Composite parent)
+ {
+ this(page, tab, service, level, name, labelText, DEFAULT, parent);
+ }
+
+ @Override
+ public Composite getHolder() {
+ return (getChangeControl() != null) ? getChangeControl().getParent() : null;
+ }
+
+ /*
+ * Methods related to loading values from the preferences service
+ * into the preferences store.
+ *
+ * All of the "doLoad..." methods should
+ * - Set isInherited, presentsDefaultValue, and levelFromWhichLoaded
+ * since these are know directly here and vary from load method to
+ * load method
+ * - Call setStringValue(..), which will set previousValue and
+ * fieldModified (which can be set generally given the old and
+ * new values), and which will also call valueChanged(), which
+ */
+
+
+
+ /* (non-Javadoc)
+ * Method declared on FieldEditor.
+ */
+ protected void doLoad()
+ {
+ if (getChangeControl() != null) {
+ boolean value;
+ if (preferencesLevel != null) {
+ // The "normal" case, in which field corresponds to a preferences level
+ value = preferencesService.getBooleanPreference(preferencesLevel, getPreferenceName());
+ levelFromWhichLoaded = preferencesLevel;
+ setInherited(false);
+ }
+ else {
+ // Not normal, exactly, but possible if loading is being done into a
+ // field that is not associated with a specific level
+ value = preferencesService.getBooleanPreference(getPreferenceName());
+ levelFromWhichLoaded = preferencesService.getApplicableLevel(getPreferenceName(), preferencesLevel);
+ setInherited(true);
+ }
+ setPresentsDefaultValue(IPreferencesService.DEFAULT_LEVEL.equals(levelFromWhichLoaded));
+ setBooleanValue(value);
+ }
+
+ }
+
+
+
+ /* (non-Javadoc)
+ * Method declared on FieldEditor.
+ */
+ protected void doLoadDefault() {
+ if (getChangeControl() != null) {
+ boolean value = preferencesService.getBooleanPreference(IPreferencesService.DEFAULT_LEVEL, getPreferenceName());
+ levelFromWhichLoaded = IPreferencesService.DEFAULT_LEVEL;
+ setInherited(false); // We're putting the default value here directly, not inheriting it
+ setPresentsDefaultValue(true);
+ setBooleanValue(value); // calls valueChanged();
+ }
+ }
+
+
+ /* (non-Javadoc)
+ *
+ */
+ protected void doLoadLevel(String level) {
+ if (getChangeControl() != null) {
+ boolean value;
+ if (preferencesLevel != null) {
+ value = preferencesService.getBooleanPreference(level, getPreferenceName());
+ } else {
+ value = preferencesService.getBooleanPreference(getPreferenceName());
+ }
+ // We're putting the level's value here directly, not inheriting it, so ...
+ levelFromWhichLoaded = level;
+ setInherited(false);
+ setPresentsDefaultValue(IPreferencesService.DEFAULT_LEVEL.equals(level));
+ setBooleanValue(value); // calls valueChanged();
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * Method declared on FieldEditor.
+ */
+ protected void refreshValidState() {
+ notifyState(true);
+ }
+
+
+
+ /*
+ * Load into the boolean field the value for this preference that is either
+ * the value defined on this preferences level, if any, or the value inherited
+ * from the next applicable level, if any. Return the level at which the
+ * value loaded was found. Load nothing and return null if no value is found.
+ */
+ protected String doLoadWithInheritance()
+ {
+ String levelLoaded = null;
+
+ String[] levels = IPreferencesService.levels;
+ int fieldLevelIndex = preferencesService.getIndexForLevel(preferencesLevel);
+
+ boolean value = false;
+ int levelAtWhichFound = -1;
+
+ IEclipsePreferences[] nodes = preferencesService.getNodesForLevels();
+
+ for (int level = fieldLevelIndex; level < levels.length; level++) {
+ // Must have a node from which to get a value
+ if (nodes[level] == null) continue;
+
+ // Get the value from the node, not the service, because we can
+ // check the node to see whether there is a value there for this
+ // preference
+ String result = nodes[level].get(getPreferenceName(), null);
+ if (result != null) {
+ // We have a value at the node; get it as a boolean
+ // (presumably we could also convert the result to a boolean)
+ value = nodes[level].getBoolean(getPreferenceName(), false);
+
+ levelAtWhichFound = level;
+ levelLoaded = levels[levelAtWhichFound];
+ break;
+ }
+ }
+
+ String previousLevelFromWhichLoaded = levelFromWhichLoaded;
+
+ // Ok, now have all necessary information to set everything that needs to be set
+ levelFromWhichLoaded = levelLoaded;
+ setInherited(fieldLevelIndex != levelAtWhichFound);
+ setPresentsDefaultValue(IPreferencesService.DEFAULT_LEVEL.equals(levelFromWhichLoaded));
+ setPreviousBooleanValue(getBooleanValue());
+ boolean valueChanged = previousValue==null || ((Boolean)previousValue).booleanValue()!=value;
+ boolean levelChanged = previousLevelFromWhichLoaded==null && levelFromWhichLoaded!=null || previousLevelFromWhichLoaded!=null && levelFromWhichLoaded==null || previousLevelFromWhichLoaded != null && !previousLevelFromWhichLoaded.equals(levelFromWhichLoaded);
+ if (levelChanged || valueChanged) {
+ setBooleanValue(value); // sets fieldModified and previousValue
+ }
+
+ if (!isInherited())
+ getChangeControl().setBackground(PreferencesUtilities.colorWhite);
+ else
+ getChangeControl().setBackground(PreferencesUtilities.colorBluish);
+ setPresentsDefaultValue(levelAtWhichFound == IPreferencesService.DEFAULT_INDEX);
+
+ return levelLoaded;
+ }
+
+
+
+ protected void doStore()
+ {
+ boolean value = getBooleanValue();
+
+ // Not inherited, and modified: field must have been set on this level, so store it.
+ // Storing here should trigger preference-change listeners at each level below this.
+ preferencesService.setBooleanPreference(preferencesLevel, getPreferenceName(), value);
+
+ // If we've just stored the field, we've addressed any modifications
+ //System.out.println("SBFE.doStore: setting fieldModified to FALSE");
+ fieldModified = false;
+ // If we've stored the field then it's not inherited, so be sure it's
+ // color indicates that.
+ // Note that for the checkbox wiget (which is the only one used so far)
+ // the background color is the color behind the label (not the checkbox
+ // itself), so it should be light gray like the background in the rest
+ // of the tab.
+ // TODO: figure out how to determine the actual prevailing background
+ // color and use that here
+ getChangeControl().setBackground(PreferencesUtilities.colorWhite);
+
+
+ // Now write out the node
+ IEclipsePreferences node = preferencesService.getNodeForLevel(preferencesLevel);
+
+ try {
+ if (node != null) node.flush();
+ } catch (BackingStoreException e) {
+ System.err.println("SBFE.doStore(): BackingStoreException ; node may not have been flushed:" +
+ "\n\tnode path = " + node.absolutePath() + ", preferences level = " + preferencesLevel);
+ }
+ }
+
+
+ /*
+ * Preferences are stored by level, so we need to provide some
+ * way to represent and set the applicable level. Note that
+ * preferences can be reset at the default level during exeuction
+ * but default level preferences are never stored between
+ * executions.
+ */
+
+
+ public void setPreferencesLevel(String level) {
+ if (!preferencesService.isaPreferencesLevel(level)) {
+ throw new IllegalArgumentException("SafairBooleanFieldEditor.setPreferencesLevel: given level = " + level + " is invalid");
+ }
+ if (level.equals(IPreferencesService.PROJECT_LEVEL) && preferencesService.getProject() == null) {
+ throw new IllegalStateException("SafairBooleanFieldEditor.setPreferenceLevel: given level is '" + IPreferencesService.PROJECT_LEVEL +
+ "' but project is not defined for preferences service");
+ }
+ preferencesLevel = level;
+ }
+
+
+ public String getPreferencesLevel() {
+ return preferencesLevel;
+ }
+
+
+
+ /**
+ * Returns the field editor's value.
+ *
+ * @return the current value
+ */
+ public boolean getBooleanValue() {
+ //return getChangeControl(parent).getSelection();
+ return getChangeControl().getSelection();
+ }
+
+
+ /**
+ * Set the previous value for this field
+ * @param value The value to be set
+ */
+
+ protected void setPreviousBooleanValue(boolean value) {
+ previousValue = value ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ /**
+ * Get the previous value for this field
+ * @return The previous value
+ */
+ protected boolean getPreviousBooleanValue() {
+ return ((Boolean)previousValue).booleanValue();
+ }
+
+
+
+ /**
+ * Set the value of this field directly, from outside of
+ * the field, without loading a value from the preferences
+ * service.
+ *
+ * Intended for use by external clients of the field.
+ *
+ * In addition to setting the value of the field this method
+ * also sets several attributes to appropriately characterize
+ * a field that has been set in this way.
+ *
+ * @param newValue
+ */
+ public void setFieldValueFromOutside(boolean newValue) {
+ setPreviousBooleanValue(getBooleanValue());
+ setInherited(false);
+ setPresentsDefaultValue(false);
+ levelFromWhichLoaded = null;
+ setBooleanValue(newValue);
+ }
+
+
+
+ /**
+ * Sets this field editor's value through the supertype.
+ * Sets previous value and field modified.
+ * Also calls valueChanged(..) to signal the change in
+ * value.
+ *
+ * @param value the new value
+ */
+ protected void setBooleanValue(boolean newValue) {
+ Button button = getChangeControl();
+ if (button != null && !button.isDisposed()) {
+ boolean currentValue = getBooleanValue();
+ if (previousValue == null)
+ setPreviousBooleanValue(!currentValue);
+ button.setSelection(newValue);
+ fieldModified = true;
+// setModifiedMarkOnLabel();
+ valueChanged();
+ } else if (button.isDisposed()) {
+ throw new IllegalStateException("BooleanFieldEditor.setBooleanValue: button is disposed");
+ } else if (button == null) {
+ throw new IllegalStateException("BooleanFieldEditor.setBooleanValue: button is null");
+ }
+ }
+
+
+
+
+ /**
+ * Should be called whenever there is an update to the field,
+ * regardless of whether the value has changed or not.
+ *
+ * Informs this field editor's listener, if it has one, about a change
+ * to the value (<code>VALUE</code> property) provided that the old and
+ * new values are different.
+ *
+ * Sets the "modified" mark on the fields label regardless of
+ * whether the value has changed (on the assumption that the
+ * field has, or may have, changed in some significant way.
+ *
+ * @param oldValue the old value
+ * @param newValue the new value
+ */
+ protected boolean valueChanged() {
+ boolean changed = false;
+
+ boolean oldValue = getPreviousBooleanValue();
+ boolean newValue = getBooleanValue();
+
+ if (oldValue != newValue) {
+ fireStateChanged(VALUE, oldValue, newValue);
+ changed = true;
+ }
+ // Set modify mark in any case because field may
+ // have changed, e.g., going from inherited to not
+ // or vice versa, without the value changing
+ setModifiedMarkOnLabel();
+ return changed;
+ }
+
+// public static final org.eclipse.swt.graphics.FontData changedFontData = new org.eclipse.swt.graphics.FontData("Monaco", 11, 2);
+ private static final FontData[] arialFonts = PlatformUI.getWorkbench().getDisplay().getFontList("Arial", true);
+ private static FontData[] labelFonts;
+
+ /**
+ * Initialize fonts for use in checkbox labels
+ * @return true if appropriate fonts available on system; false if not.
+ */
+ private boolean getLabelFonts() {
+ if (labelFonts==null) {
+ labelFonts = new FontData[2];
+
+ for (FontData fd: arialFonts) {
+ if (fd.getHeight() <=10) {
+ switch (fd.getStyle()) {
+ case SWT.NORMAL:
+ labelFonts[0] = fd;
+ break;
+ case SWT.ITALIC:
+ labelFonts[1] = fd;
+ break;
+ }
+ }
+ }
+ }
+ if (labelFonts[0]==null || labelFonts[1] == null) { // only vary font if reasonable fonts exist for both modified/unmodified
+ return false;
+ }
+ return true;
+
+ }
+
+ /*
+ * For boolean fields we override the following two methods because
+ * the means of accessing the text to be modified is different.
+ * @see org.eclipse.imp.preferences.fields.FieldEditor#setModifyMarkOnLabel()
+ * @see org.eclipse.imp.preferences.fields.FieldEditor#clearModifyMarkOnLabel()
+ */
+
+
+ public void setModifiedMarkOnLabel() {
+ // SMS 27 Nov 2006
+ // Don't presume here to deal with inheritance. If called then set mark.
+ // Let caller worry about whether field is inherited and how that affects
+ // the marking
+ // if (isInherited) return;
+ if (checkBox != null) {
+// String labelText = checkBox.getText();
+// if (!labelText.startsWith(Markings.MODIFIED_MARK)) {
+// labelText = Markings.MODIFIED_MARK + labelText;
+// checkBox.setText(labelText);
+// }
+ // replace changed mark by color to eliminate text-box overflow bug
+ checkBox.setForeground(PreferencesUtilities.colorRed); // this doesn't work on MacOSX: use font if possible
+ if (getLabelFonts()==false) return;
+ checkBox.setFont(new Font(getPage().getShell().getDisplay(), labelFonts[1]));
+ }
+ }
+
+
+ public void clearModifiedMarkOnLabel() {
+ if (getLabelFonts()==false) return;
+ if (checkBox != null) {
+// String labelText = checkBox.getText();
+// if (labelText.startsWith(Markings.MODIFIED_MARK))
+// labelText = labelText.substring(1);
+// checkBox.setText(labelText);
+ // replace changed mark by color to eliminate text-box overflow bug
+ checkBox.setForeground(PreferencesUtilities.colorBlack); // this doesn't work on MacOSX: use font if possible
+ if (getLabelFonts()==false) return;
+ checkBox.setFont(new Font(getPage().getShell().getDisplay(), labelFonts[0]));
+
+ }
+ }
+
+
+
+ /*
+ * Returns the change button for this field editor.
+ * This overrides the corresponding superclass method so that we can set
+ * a listener on the control for our purposes.
+ *
+ */
+ public Button getChangeControl() {
+ if (!parent.isDisposed()) {
+ if (checkBox == null) {
+ // Should actually create checkbox if it doesn't exist
+ // so should really never be null
+ //checkBox = getChangeControl(parent);
+ checkBox = new Button(parent, SWT.CHECK | SWT.LEFT);
+ checkBox.setFont(parent.getFont());
+ checkBox.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ // Whenever a new value is set, we have to record the previous value.
+ // If we're here, that means that the current value has been changed
+ // using the GUI. Since the value in the GUI has changed, we can't
+ // use that to retrieve the previous value. But, since this is a
+ // boolean field, we know that the previous value must have been the
+ // negation of the current value, so we can set the previous value
+ // from that. It's important to set the previous value here before
+ // calling valueChanged(), because valueChanged() can't assume that
+ // a change has occurred--since a value loaded from the preferences
+ // service may match the current value of the field--so valueChanged()
+ // has to compare the new and previous values. To make that comparison
+ // work, we need to assure that the previous value is set properly here.
+ setPreviousBooleanValue(!getBooleanValue());
+ fieldModified = true;
+ // Should call setInherited(..) before calling valueChanged() because
+ // valueChanged() will mark the field as modified, but only if isInherited
+ // is false, which it now should be
+ setInherited(false);
+ levelFromWhichLoaded = preferencesLevel;
+ setBooleanValue(getBooleanValue());
+ // Set presentsDefaultValue to false on the basis that
+ // we've set it independently of the encoded default value
+ // even if we're on the default level.
+ setPresentsDefaultValue(false);
+ //valueChanged();
+ //setPreviousBooleanValue(getBooleanValue());
+ }
+ });
+ checkBox.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent event) {
+ //System.out.println("SBFE.button dispose listener (from getChangeControl): checkBoxNull set to true");
+ checkBox = null;
+ }
+ });
+ } else {
+ checkParent(checkBox, parent);
+ }
+ return checkBox; //getChangeControl(parent);
+ }
+ return null;
+ }
+
+
+
+ /*
+ * Additional methods copied from BooleanFieldEditor
+ */
+
+ /* (non-Javadoc)
+ * Method declared on FieldEditor.
+ */
+ protected void adjustForNumColumns(int numColumns) {
+ if (style == SEPARATE_LABEL)
+ numColumns--;
+ ((GridData) checkBox.getLayoutData()).horizontalSpan = numColumns;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on FieldEditor.
+ */
+ protected void doFillIntoGrid(Composite parent, int numColumns) {
+ String text = getLabelText();
+ String toolTipText = getToolTipText();
+ switch (style) {
+ case SEPARATE_LABEL:
+ getLabelControl(parent);
+ numColumns--;
+ text = null;
+ default:
+ checkBox = getChangeControl();
+ GridData gd = new GridData();
+ gd.horizontalSpan = numColumns;
+ checkBox.setLayoutData(gd);
+ if (text != null) {
+ checkBox.setText(text);
+ if (toolTipText != null) {
+ checkBox.setToolTipText(toolTipText);
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void doSetToolTip() {
+ if (toolTipText != null) {
+ getChangeControl().setToolTipText(toolTipText);
+ }
+ }
+
+ /* (non-Javadoc)
+ * Method declared on FieldEditor.
+ */
+ public int getNumberOfControls() {
+ switch (style) {
+ case SEPARATE_LABEL:
+ return 2;
+ default:
+ return 1;
+ }
+ }
+
+
+
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/ChangeButtonFieldEditor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/ChangeButtonFieldEditor.java
new file mode 100644
index 000000000..2e267c78a
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/ChangeButtonFieldEditor.java
@@ -0,0 +1,23 @@
+package org.eclipse.imp.preferences.fields;
+
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesTab;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+public abstract class ChangeButtonFieldEditor extends FieldEditor {
+
+ public ChangeButtonFieldEditor() { }
+
+ public ChangeButtonFieldEditor(PreferencePage page, PreferencesTab tab, IPreferencesService service, String level) {
+ super(page, tab, service, level);
+ }
+
+ public ChangeButtonFieldEditor(PreferencePage page, PreferencesTab tab, IPreferencesService service, String level,
+ String name, String labelText, Composite parent) {
+ super(page, tab, service, level, name, labelText, parent);
+ }
+
+ public abstract Button getChangeControl();
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/ColorFieldEditor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/ColorFieldEditor.java
new file mode 100644
index 000000000..d8489bb78
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/ColorFieldEditor.java
@@ -0,0 +1,313 @@
+package org.eclipse.imp.preferences.fields;
+
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesTab;
+import org.eclipse.imp.preferences.PreferencesUtilities;
+import org.eclipse.jface.preference.ColorSelector;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.resource.StringConverter;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+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.osgi.service.prefs.BackingStoreException;
+
+public class ColorFieldEditor extends ChangeButtonFieldEditor {
+ public static final RGB COLOR_DEFAULT= new RGB(0,0,0);
+
+ public static final String COLOR_DEFAULT_SPEC= StringConverter.asString(COLOR_DEFAULT);
+
+ /**
+ * The color selector, or <code>null</code> if none.
+ */
+ private ColorSelector colorSelector;
+
+ public ColorFieldEditor(PreferencePage page, PreferencesTab tab, IPreferencesService service, String level, String name, String labelText, Composite parent) {
+ super(page, tab, service, level, name, labelText, parent);
+ createControl(parent);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on FieldEditor.
+ */
+ protected void adjustForNumColumns(int numColumns) {
+ ((GridData) colorSelector.getButton().getLayoutData()).horizontalSpan= numColumns - 1;
+ }
+
+ /**
+ * Computes the size of the color image displayed on the button.
+ * <p>
+ * This is an internal method and should not be called by clients.
+ * </p>
+ *
+ * @param window
+ * the window to create a GC on for calculation.
+ * @return Point The image size
+ *
+ */
+ protected Point computeImageSize(Control window) {
+ // Make the image height as high as a corresponding character. This
+ // makes sure that the button has the same size as a "normal" text
+ // button.
+ GC gc= new GC(window);
+ Font f= JFaceResources.getFontRegistry().get(JFaceResources.DEFAULT_FONT);
+ gc.setFont(f);
+ int height= gc.getFontMetrics().getHeight();
+ gc.dispose();
+ Point p= new Point(height * 3 - 6, height);
+ return p;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.FieldEditor#doFillIntoGrid(org.eclipse.swt.widgets.Composite, int)
+ */
+ protected void doFillIntoGrid(Composite parent, int numColumns) {
+ Control control= getLabelControl(parent);
+ GridData gd= new GridData();
+ gd.horizontalSpan= numColumns - 1;
+ control.setLayoutData(gd);
+
+ Button colorButton= getChangeControl(parent);
+ colorButton.setLayoutData(new GridData());
+ }
+
+ /*
+ * (non-Javadoc) Method declared on FieldEditor.
+ */
+ public int getNumberOfControls() {
+ return 2;
+ }
+
+ /**
+ * Get the color selector used by the receiver.
+ *
+ * @return ColorSelector/
+ */
+ public ColorSelector getColorSelector() {
+ return colorSelector;
+ }
+
+ @Override
+ public Button getChangeControl() {
+ if (colorSelector == null)
+ return null;
+ return colorSelector.getButton();
+ }
+
+ @Override
+ public Composite getHolder() {
+ return getChangeControl().getParent();
+ }
+
+ /**
+ * Returns the change button for this field editor.
+ *
+ * @param parent
+ * The control to create the button in if required.
+ * @return the change button
+ */
+ protected Button getChangeControl(Composite parent) {
+ if (colorSelector == null) {
+ colorSelector= new ColorSelector(parent);
+ colorSelector.addListener(new IPropertyChangeListener() {
+ // forward the property change of the color selector
+ public void propertyChange(PropertyChangeEvent event) {
+ ColorFieldEditor.this.fireValueChanged(event.getProperty(), event.getOldValue(), event.getNewValue());
+ setPresentsDefaultValue(false);
+ setInherited(false);
+ fieldModified= true;
+ }
+ });
+
+ } else {
+ checkParent(colorSelector.getButton(), parent);
+ }
+ return colorSelector.getButton();
+ }
+
+ @Override
+ protected void doSetToolTip() {
+ getLabelControl().setToolTipText(toolTipText);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.FieldEditor#setEnabled(boolean, org.eclipse.swt.widgets.Composite)
+ */
+ public void setEnabled(boolean enabled, Composite parent) {
+ super.setEnabled(enabled, parent);
+ getChangeControl(parent).setEnabled(enabled);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.FieldEditor#doLoad()
+ */
+ protected void doLoad() {
+ if (colorSelector == null) {
+ return;
+ }
+ updateColor(preferencesService.getStringPreference(getPreferenceName()));
+ }
+
+ /*
+ * (non-Javadoc) Method declared on FieldEditor.
+ */
+ protected void doLoadDefault() {
+ if (colorSelector == null) {
+ return;
+ }
+ updateColor(preferencesService.getStringPreference(IPreferencesService.DEFAULT_LEVEL, getPreferenceName()));
+ }
+
+ @Override
+ protected void doLoadLevel(String level) {
+ String colorValue = preferencesService.getStringPreference(level, getPreferenceName());
+
+ updateColor(colorValue);
+ }
+
+ private void updateColor(String colorSpec) {
+ RGB color = StringConverter.asRGB(colorSpec, null);
+
+ if (color == null) {
+ color= COLOR_DEFAULT;
+ }
+ colorSelector.setColorValue(color);
+ }
+
+ @Override
+ protected String doLoadWithInheritance() {
+ String levelLoaded = null;
+ String[] levels = IPreferencesService.levels;
+
+ // If we're loading with inheritance for some field that is
+ // not attached to a preferences level then assume that we
+ // should just search from the bottom up
+ int startingLevelIdx = (preferencesLevel == null) ? 0 : PREFS_LEVELS_AS_LIST.indexOf(preferencesLevel);
+ int levelAtWhichFound = -1;
+
+ String encodedColorValue = null;
+ // Search up levels starting from the level of this field
+ for (int level = startingLevelIdx; level < levels.length; level++) {
+ encodedColorValue = preferencesService.getRawStringPreference(levels[level], getPreferenceName());
+ if (encodedColorValue != null) {
+ levelAtWhichFound = level;
+ levelLoaded = levels[levelAtWhichFound];
+ break;
+ }
+ }
+ if (encodedColorValue == null) {
+ encodedColorValue= COLOR_DEFAULT_SPEC;
+ }
+
+ // TODO should this be calling updateColor() instead of the following?
+ levelFromWhichLoaded = levelLoaded;
+ setInherited(startingLevelIdx != levelAtWhichFound);
+ setPresentsDefaultValue(IPreferencesService.DEFAULT_LEVEL.equals(levelFromWhichLoaded));
+ fieldModified = true;
+// valueChanged(); // should not be called when field set from preference store
+
+ previousValue= colorSelector.getColorValue(); // not clear whether this needs to be done on initial load from store
+ colorSelector.setColorValue(StringConverter.asRGB(encodedColorValue));
+
+ updateColor(encodedColorValue);
+ return levelLoaded;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on FieldEditor.
+ */
+ protected void doStore() {
+ RGB value = colorSelector.getColorValue();
+
+ // Not inherited, and modified: field must have been set on this level, so store it.
+ // Storing here should trigger preference-change listeners at each level below this.
+ preferencesService.setStringPreference(preferencesLevel, getPreferenceName(), StringConverter.asString(value));
+
+ // If we've just stored the field, we've addressed any modifications
+ //System.out.println("SBFE.doStore: setting fieldModified to FALSE");
+ fieldModified = false;
+ // If we've stored the field then it's not inherited, so be sure it's
+ // color indicates that.
+ // Note that for the checkbox wiget (which is the only one used so far)
+ // the background color is the color behind the label (not the checkbox
+ // itself), so it should be light gray like the background in the rest
+ // of the tab.
+ // TODO: figure out how to determine the actual prevailing background
+ // color and use that here
+ getLabelControl().setBackground(PreferencesUtilities.colorWhite);
+
+ // Now write out the node
+ IEclipsePreferences node = preferencesService.getNodeForLevel(preferencesLevel);
+
+ try {
+ if (node != null) node.flush();
+ } catch (BackingStoreException e) {
+ System.err.println("SCFE.doStore(): BackingStoreException; node may not have been flushed:" +
+ "\n\tnode path = " + node.absolutePath() + ", preferences level = " + preferencesLevel);
+ }
+ }
+
+ /**
+ * Set the value of this field directly, from outside of
+ * the field, without loading a value from the preferences
+ * service.
+ *
+ * Intended for use by external clients of the field.
+ *
+ * In addition to setting the value of the field this method
+ * also sets several attributes to appropriately characterize
+ * a field that has been set in this way.
+ *
+ * @param newValue
+ */
+ public void setFieldValueFromOutside(String newValue) {
+ previousValue = colorSelector.getColorValue();
+ setInherited(false);
+ setPresentsDefaultValue(false);
+ levelFromWhichLoaded = null;
+ updateColor(newValue);
+ }
+
+ @Override
+ protected boolean valueChanged() {
+ // Check for change in value
+ boolean valueChanged = inheritanceChanged();
+ RGB chosenColor= colorSelector.getColorValue();
+
+ if (!valueChanged) {
+ if ((chosenColor != null && previousValue == null) ||
+ (chosenColor == null && previousValue != null))
+ {
+ valueChanged = true;
+ }
+
+ if (chosenColor != null && previousValue != null) {
+ if (!chosenColor.equals(previousValue)) {
+ valueChanged = true;
+ }
+ }
+ }
+
+ if (valueChanged) {
+ fireValueChanged(VALUE, previousValue, chosenColor);
+ fieldModified = true;
+ previousValue = chosenColor;
+ setModifiedMarkOnLabel();
+ }
+ return valueChanged;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/ComboFieldEditor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/ComboFieldEditor.java
new file mode 100644
index 000000000..01297aab0
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/ComboFieldEditor.java
@@ -0,0 +1,495 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences.fields;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesTab;
+import org.eclipse.imp.preferences.PreferencesUtilities;
+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.graphics.Color;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.osgi.service.prefs.BackingStoreException;
+
+/**
+ * A field editor for a combo box that allows the drop-down selection of one of a list of items.
+ *
+ * SMS: This is a copy of ComboFieldEditor, found in org.eclipse.imp.preferences.fields,
+ * which itself is a copy from org.eclipse.search.internal.ui.util, as indicated by the
+ * following comment (copied from the "original"):
+ *
+ * XXX: Note this is a copy from org.eclipse.search.internal.ui.util<br>
+ * This class can be removed once a published (non-internal, visible) version is available.
+ */
+public class ComboFieldEditor extends FieldEditor {
+ /**
+ * The <code>Combo</code> widget.
+ */
+ private Combo fCombo = null;
+
+ /**
+ * The value (not the name) of the currently selected item in the Combo widget.
+ */
+ private String fValue = null;
+
+ /**
+ * The previous value (not the previous name) of the currently selected item in the Combo widget.
+ */
+ //private String fPreviousValue = null;
+
+
+ /**
+ * The names (labels) and underlying values to populate the combo widget.
+ */
+ private List<String> fEntryLabels;
+
+ private List<String> fEntryValues;
+
+ private int fNumColumns;
+
+ /*
+ * Note: The specialValue may be one that is used as a default or
+ * one that signifies no meaningful value selected. It is assumed
+ * here NOT to occur in entryNamesAndValues, and it is added to
+ * the head of the array of names and values used here to create
+ * the combo box entries.
+ */
+ public ComboFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level,
+ String name, String labelText, String[] values, String[] labels, int numColumns,
+ Composite parent, boolean isEnabled, boolean isRemovable)
+ {
+ Assert.isTrue(values.length == labels.length);
+ init(name, labelText);
+
+ preferencesService = service;
+ preferencesLevel = level;
+ this.parent = parent;
+ prefPage = page;
+ setPage(prefPage);
+ prefTab = tab;
+
+ fEntryLabels= new ArrayList<String>(labels.length);
+ fEntryValues= new ArrayList<String>(values.length);
+ for(int i=0; i < labels.length; i++) {
+ fEntryLabels.add(labels[i]);
+ fEntryValues.add(values[i]);
+ }
+ fNumColumns= numColumns;
+
+ // Create control after setting fEntryNamesAndValues
+ // because that is referenced in creating the control
+ createControl(parent);
+
+ this.isRemovable = isRemovable;
+ }
+
+
+ /*
+ * @see FieldEditor#adjustForNumColumns(int)
+ */
+ protected void adjustForNumColumns(int numColumns) {
+ Control control= getLabelControl();
+ if (control != null) {
+ ((GridData) control.getLayoutData()).horizontalSpan= numColumns;
+ }
+ ((GridData) fCombo.getLayoutData()).horizontalSpan= numColumns;
+ }
+
+ /*
+ * @see FieldEditor#(Composite, int)
+ */
+ protected void doFillIntoGrid(Composite parent, int numColumns) {
+ Control control= getLabelControl(parent);
+ GridData gd= new GridData();
+ gd.horizontalSpan= 1;
+ control.setLayoutData(gd);
+ control= getComboBoxControl();
+ gd= new GridData();
+ gd.horizontalSpan= 1;
+ control.setLayoutData(gd);
+ }
+
+ @Override
+ protected void doSetToolTip() {
+ if (toolTipText != null) {
+ getComboBoxControl().setToolTipText(toolTipText);
+ }
+ }
+
+
+ /**
+ * Overrides method defined in FieldEditor.
+ *
+ * Initializes this field editor with the preference value from
+ * the preference store.
+ */
+// public void load() {
+// if (preferencesService != null) {
+// //isDefaultPresented = false;
+// doLoad();
+// refreshValidState();
+// }
+// }
+
+
+ /*
+ * @see FieldEditor#doLoad()
+ */
+ protected void doLoad() {
+ //if (getTextControl() != null) {
+ if (fCombo != null) {
+ String value = null;
+ if (preferencesLevel != null) {
+ // The "normal" case, in which field corresponds to a preferences level
+ value = preferencesService.getStringPreference(preferencesLevel, getPreferenceName());
+ levelFromWhichLoaded = preferencesLevel;
+ setInherited(false);
+ } else {
+ // Not normal, exactly, but possible if loading is being done into a
+ // field that is not associated with a specific level
+ value = preferencesService.getStringPreference(getPreferenceName());
+ levelFromWhichLoaded = preferencesService.getApplicableLevel(getPreferenceName(), preferencesLevel);
+ setInherited(true);
+ }
+ if (IPreferencesService.DEFAULT_LEVEL.equals(levelFromWhichLoaded))
+ setPresentsDefaultValue(true);
+
+ previousValue = value;
+
+ updateComboForValue(value);
+ }
+ }
+
+
+ /*
+ * SMS 23 Dec 2006:
+ * Probably want to eliminate loadDefault(..) and loadLevel(..) unless a need can be
+ * demonstrated and their semantics reasonably defined.
+ */
+
+
+ /*
+ * @see FieldEditor#doLoadDefault()
+ */
+ protected void doLoadDefault() {
+ //updateComboForValue(getPreferenceStore().getDefaultString(getPreferenceName()));
+
+ if (fCombo != null) {
+ String value = preferencesService.getStringPreference(IPreferencesService.DEFAULT_LEVEL, getPreferenceName());
+ updateComboForValue(value);
+ }
+ }
+
+ /**
+ * Do the work of loading the value for the given level into the field.
+ */
+ protected void doLoadLevel(String level) {
+ if (fCombo != null) {
+ String value = preferencesService.getStringPreference(level, getPreferenceName());
+ updateComboForValue(value);
+ }
+ }
+
+
+
+
+ /*
+ * Load into the button field the value for this preference that is either
+ * the value defined on this preferences level, if any, or the value inherited
+ * from the next applicable level, if any. Return the level at which the
+ * value loaded was found. Load nothing and return null if no value is found.
+ */
+ protected String doLoadWithInheritance()
+ {
+ String levelLoaded = null;
+
+ String[] levels = IPreferencesService.levels;
+ int fieldLevelIndex = 0;
+
+ // If we're loading with inheritance for some field that is
+ // not attached to a preferences level then assume that we
+ // should just search from the bottom up
+ String tmpPreferencesLevel = (preferencesLevel == null) ? levels[0] : preferencesLevel;
+
+ // Find the index of the level to which this field belongs
+ for (int i = 0; i < levels.length; i++) {
+ if (tmpPreferencesLevel.equals(levels[i])) {
+ fieldLevelIndex = i;
+ break;
+ }
+ }
+
+ String value = null;
+ int levelAtWhichFound = -1;
+
+ // Search up levels starting from the level of this field
+ for (int level = fieldLevelIndex; level < levels.length; level++) {
+ value = preferencesService.getStringPreference(levels[level], getPreferenceName());
+ if (value == null) continue;
+ levelAtWhichFound = level;
+ levelLoaded = levels[levelAtWhichFound];
+ break;
+ }
+
+ levelFromWhichLoaded = levelLoaded;
+ setInherited(fieldLevelIndex != levelAtWhichFound);
+ setPresentsDefaultValue(IPreferencesService.DEFAULT_LEVEL.equals(levelFromWhichLoaded));
+
+ // Set the field to the value we found
+ updateComboForValue(value);
+
+ fieldModified = false; // Since we just loaded some new value, it won't be modified yet
+ previousValue = value; // TODO: Check on use of previous value
+
+ // Set the background color of the field according to where found
+ setFieldColors();
+
+ return levelLoaded;
+ }
+
+
+ protected void setFieldColors() {
+ Control comboBox = getComboBoxControl();
+ Color color = isInherited() ? PreferencesUtilities.colorBluish : PreferencesUtilities.colorWhite;
+ comboBox.setBackground(color);
+ }
+
+
+ /**
+ * Overrides method implemented in RadioGroupFieldEditor.
+ *
+ * Abstract method declared on FieldEditor.
+ */
+ protected void doStore() {
+ String value = getStringValue();
+
+ // We have a value (possibly empty, if that is allowed) that has changed
+ // from the previous value, so store it
+ preferencesService.setStringPreference(preferencesLevel, getPreferenceName(), value);
+
+ // If we've just stored the field, we've addressed any modifications
+ //System.out.println("STFE.doStore: setting fieldModified to FALSE");
+ fieldModified = false;
+ // "Level from which loaded" (or set, as the case may be) is now this level
+ levelFromWhichLoaded = preferencesLevel;
+ // If we've stored the field then it's not inherited, so be sure it's
+ // color indicates that.
+ setFieldColors();
+ //getComboBoxControl(parent).setBackground(PreferencesUtilities.colorWhite);
+
+ IEclipsePreferences node = preferencesService.getNodeForLevel(preferencesLevel);
+ try {
+ if (node != null) node.flush();
+ } catch (BackingStoreException e) {
+ System.err.println("ComboFieldEditor.doStore(): BackingStoreException flushing node; node may not have been flushed:" +
+ "\n\tnode path = " + node.absolutePath() + ", preferences level = " + preferencesLevel);
+ }
+ }
+
+
+ /*
+ * @see FieldEditor#getNumberOfControls()
+ */
+ public int getNumberOfControls() {
+ return fNumColumns;
+ }
+
+ /*
+ * Lazily create and return the Combo control.
+ */
+ public Combo getComboBoxControl() {
+ if (fCombo == null) {
+ fCombo= new Combo(parent, SWT.READ_ONLY);
+ for(String entryName: fEntryLabels) {
+ fCombo.add(entryName);
+ }
+ fCombo.setFont(parent.getFont());
+ fCombo.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ String name= fCombo.getText();
+ fValue= getValueForName(name);
+ setPresentsDefaultValue(false);
+ // SMS 23 Dec 2006
+ fieldModified = true;
+ setInherited(false);
+ valueChanged();
+ }
+ });
+ }
+ return fCombo;
+ }
+
+ @Override
+ public Composite getHolder() {
+ return getComboBoxControl().getParent();
+ }
+
+ /*
+ * Given the name (label) of an entry, return the corresponding value.
+ */
+ protected String getValueForName(String name) {
+ int idx= fEntryLabels.indexOf(name);
+ return (idx >= 0) ? fEntryValues.get(idx) : "";
+ }
+
+ /*
+ * Set the name in the combo widget to match the specified value.
+ */
+ protected void updateComboForValue(String value) {
+ if (value == null)
+ value = "";
+ previousValue = getStringValue();
+ setPreviousStringValue(getStringValue());
+
+ int idx= fEntryValues.indexOf(value);
+
+ if (idx < 0) { idx = 0; }
+ fValue = fEntryValues.get(idx);
+ fCombo.setText(fEntryLabels.get(idx));
+
+ valueChanged();
+ }
+
+
+ /**
+ * Informs this field editor's listener, if it has one, about a change
+ * to the value (<code>VALUE</code> property) provided that the old and
+ * new values are different. Also informs the listener (if there is one)
+ * of a change in the validity of the field (<code>IS_VALID</code> property).
+ *
+ * This hook is <em>not</em> called when the text is initialized
+ * (or reset to the default value) from the preference store.
+ * (That comment is taken from the original implementation of this
+ * method. I've tried to follow it consistently for IMP preferences,
+ * but I'm not sure if the original intention translates into the
+ * multi-level model. Still, so far there seems to be no problem
+ * with it. SMS 16 Nov 2006)
+ *
+ * Copied from StringFieldEditor and adapted to use in IMP.
+ * Added return of a boolean value. Not intended to set any attributes
+ * of the field editor, just to signal changes to listeners.
+ */
+ protected boolean valueChanged() {
+ return valueChanged(false);
+ }
+
+ protected boolean valueChanged(boolean assertChanged) {
+ // Check for change in value
+ boolean valueChanged = assertChanged || inheritanceChanged();
+ String prevValue = getPreviousStringValue();
+ if (!valueChanged) {
+ if ((fValue != null && prevValue == null) ||
+ (fValue == null && prevValue != null))
+ {
+ valueChanged = true;
+ }
+
+ if (fValue != null && prevValue != null) {
+ if (!fValue.equals(prevValue)) {
+ valueChanged = true;
+ }
+ }
+ }
+
+ if (valueChanged) {
+ fireValueChanged(VALUE, prevValue, fValue);
+ fieldModified = true;
+ setPreviousStringValue(fValue);
+ setModifiedMarkOnLabel();
+ }
+
+ return valueChanged;
+ }
+
+
+ /**
+ *
+ */
+ protected String getPreviousStringValue() {
+ return (String) previousValue;
+ }
+
+
+ protected void setPreviousStringValue(String value) {
+ previousValue = value;
+ }
+
+
+
+ /**
+ * Set the value of this field directly, from outside of
+ * the field, without loading a value from the preferences
+ * service.
+ *
+ * Intended for use by external clients of the field.
+ *
+ * In addition to setting the value of the field this method
+ * also sets several attributes to appropriately characterize
+ * a field that has been set in this way.
+ *
+ * @param newValue
+ */
+ public void setFieldValueFromOutside(String newValue) {
+ setPreviousStringValue(getStringValue());
+ setInherited(false);
+ setPresentsDefaultValue(false);
+ levelFromWhichLoaded = null;
+ updateComboForValue(newValue);
+ }
+
+
+ /**
+ * Gets the current String value of the field, corresponding
+ * to the currently selected item.
+ *
+ * @return The current String value of the field, corresponding
+ * to the currently selected item.
+ */
+ public String getStringValue() {
+ return fValue;
+ }
+
+
+ public String getSpecialStringValue() {
+ if (!hasSpecialValue) {
+ throw new IllegalStateException("ComboFieldEditor.getSpecialValue(): field does not have a special value");
+ }
+ return (String) specialValue;
+ }
+
+
+ /**
+ * Set the special value associated with this field to be the given string.
+ * Overrides the method in the supertype to check that the given value is
+ * a String.
+ *
+ * @param specialValue The special value to associate with this field
+ * @throws IllegalStateException if the field has no special value
+ * @throws IllegalArgumentException if the given value is null or empty
+ */
+ public void setSpecialValue(String specialValue) {
+ throw new IllegalStateException("ComboField.setSpecialValue(String): field has no special value");
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/DirectoryFieldEditor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/DirectoryFieldEditor.java
new file mode 100644
index 000000000..58a532260
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/DirectoryFieldEditor.java
@@ -0,0 +1,75 @@
+package org.eclipse.imp.preferences.fields;
+
+import java.io.File;
+
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesTab;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DirectoryDialog;
+
+public class DirectoryFieldEditor extends FileFieldEditor {
+ public DirectoryFieldEditor(PreferencePage page, PreferencesTab tab, IPreferencesService service, String level,
+ String name, String labelText, int width, int strategy, Composite parent) {
+ super(page, tab, service, level, name, labelText, width, strategy, parent);
+ }
+
+ public DirectoryFieldEditor(PreferencePage page, PreferencesTab tab, IPreferencesService service, String level,
+ String name, String labelText, int width, Composite parent) {
+ super(page, tab, service, level, name, labelText, width, parent);
+ }
+
+ public DirectoryFieldEditor(PreferencePage page, PreferencesTab tab, IPreferencesService service, String level,
+ String name, String labelText, Composite parent) {
+ super(page, tab, service, level, name, labelText, parent);
+ }
+
+ /**
+ * Helper to open the directory chooser dialog.
+ * @param startingDirectory the directory to open the dialog on.
+ * @return File The directory the user selected or <code>null</code> if they
+ * do not.
+ */
+ @Override
+ protected File getFile(File startingDirectory) {
+ DirectoryDialog dialog = new DirectoryDialog(getShell(), SWT.OPEN);
+ if (startingDirectory != null)
+ dialog.setFilterPath(startingDirectory.getPath());
+ String dir = dialog.open();
+ if (dir != null) {
+ dir = dir.trim();
+ if (dir.length() > 0)
+ return new File(dir);
+ }
+ return null;
+ }
+
+ @Override
+ protected boolean doCheckState(String path) {
+ String msg = null;
+ if (emptyStringAllowed && path == null || path.length() == 0) {
+ clearErrorMessage();
+ return true;
+ }
+ File file = new File(path);
+ boolean result = true;
+
+ if (file.isDirectory()) {
+ if (getEnforceAbsolute() && !file.isAbsolute())
+ msg = JFaceResources.getString("FileFieldEditor.errorMessage2");//$NON-NLS-1$
+ } else {
+ msg = "Path does not designate a valid directory";
+ }
+
+ if (msg != null) {
+ setErrorMessage(getFieldMessagePrefix() + msg);
+ result = false;
+ } else {
+ clearErrorMessage();
+ result = true;
+ }
+ return result;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/DirectoryListFieldEditor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/DirectoryListFieldEditor.java
new file mode 100644
index 000000000..b180b1766
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/DirectoryListFieldEditor.java
@@ -0,0 +1,243 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences.fields;
+
+import java.io.File;
+import java.util.Stack;
+
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesTab;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.preference.StringFieldEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.Text;
+
+public class DirectoryListFieldEditor extends StringButtonFieldEditor {
+
+
+ protected PreferencePage prefPage = null;
+ protected PreferencesTab prefTab = null;
+
+ public DirectoryListFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level, String name, String labelText,
+ int width, int strategy, Composite parent)
+ {
+ super(page, tab, service, level, name, labelText, width, strategy, parent);
+ prefPage = page;
+ prefTab = tab;
+ this.getChangeControl(parent).setText(PreferenceDialogConstants.BROWSE_LABEL);
+ }
+
+
+ /**
+ * Creates an IMP directory-list field editor.
+ * Use the method <code>setTextLimit</code> to limit the text.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param width the width of the text input field in characters,
+ * or <code>UNLIMITED</code> for no limit
+ * @param parent the parent of the field editor's control
+ */
+ public DirectoryListFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level, String name, String labelText,
+ int width, Composite parent)
+ {
+ super(page, tab, service, level, name, labelText, width, StringFieldEditor.VALIDATE_ON_KEY_STROKE, parent);
+ prefPage = page;
+ prefTab = tab;
+ this.getChangeControl(parent).setText(PreferenceDialogConstants.BROWSE_LABEL);
+ }
+
+
+ /**
+ * Creates an IMP directory-list field editor.
+ * Use the method <code>setTextLimit</code> to limit the text.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param parent the parent of the field editor's control
+ */
+ public DirectoryListFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level, String name, String labelText, Composite parent)
+ {
+ super(page, tab, service, level, name, labelText, parent);
+ prefPage = page;
+ prefTab = tab;
+ this.getChangeControl(parent).setText(PreferenceDialogConstants.BROWSE_LABEL);
+ }
+
+
+
+ /*
+ * Below copied from DirectoryListFieldEditor
+ */
+
+
+ protected String changePressed() {
+ Text text= getTextControl(parent);
+ String curText= text.getText();
+ Point sel= text.getSelection();
+ boolean replace= (text.getSelectionCount() > 0); // any non-empty selection?
+ boolean replaceAll= text.getSelectionCount() == text.getCharCount(); // all selected?
+ File f = new File(getTextControl(parent).getText());
+
+ if (!f.exists())
+ f = null;
+ File d = getDirectory(f);
+ if (d == null)
+ return null;
+
+ final String dirPath= d.getAbsolutePath();
+
+ if (replaceAll)
+ return dirPath;
+
+ int prevSep= curText.lastIndexOf(';', sel.x);
+
+ if (prevSep < 0)
+ prevSep= 0;
+
+ String leadingPart= (prevSep > 0) ? curText.substring(0, prevSep) + ';' : "";
+
+ if (replace) {
+ // Replace the selected entries with the browse result
+ int followSep= curText.indexOf(';', sel.y);
+
+ if (followSep < 0)
+ followSep= curText.length();
+ return leadingPart + dirPath + curText.substring(followSep);
+ }
+
+ if (sel.x == text.getCharCount()) // caret at end of field? => append new entry
+ return curText + ';' + dirPath;
+
+ // insertion point in middle of text; insert new entry before this entry
+ return leadingPart + dirPath + (prevSep > 0 ? "" : ";") + curText.substring(prevSep);
+ }
+
+
+ protected boolean doCheckState() {
+
+ //String path= getTextControl().getText();
+ //if (path.length() == 0 && isEmptyStringAllowed()) {
+ // return true;
+ //}
+
+ String msg = null;
+
+ // Here we check for empty or null strings, although
+ // this may very well be checked at a higher level
+ // (so we might not ever get here with this problem)
+ String path = getTextControl(parent).getText();
+ path= preferencesService.performSubstitutions(path);
+ if (path != null)
+ path = path.trim();
+ else
+ path = "";//$NON-NLS-1$
+ if (path.length() == 0 && !emptyStringAllowed) {
+ setErrorMessage(getFieldMessagePrefix() + "Path length is zero when empty string is not allowed");
+ return false;
+ }
+
+ // Check for balanced quotes
+ final String singleQuote = "'";
+ final String doubleQuote = "\"";
+ Stack stack = new Stack();
+ for (int i = 0; i < path.length(); i++) {
+ if (path.charAt(i) == '\'') {
+ if (!stack.empty() && singleQuote.equals(stack.peek()))
+ stack.pop();
+ else
+ stack.push(singleQuote);
+ }
+ if (path.charAt(i) == '"') {
+ if (!stack.empty() && doubleQuote.equals(stack.peek()))
+ stack.pop();
+ else
+ stack.push(doubleQuote);
+ }
+ }
+ if (stack.size() != 0) {
+ setErrorMessage(getFieldMessagePrefix() + "Path has quotes that are not balanced");
+ return false;
+ }
+
+
+ // Now validate list segments between quotes
+ path = path.replace("\"", "'");
+ String[] splits = path.split("'");
+ boolean splitsVerified = true;
+ for (int i = 0; i < splits.length; i++) {
+ splitsVerified = splitsVerified && doCheckState(splits[i]);
+ if (!splitsVerified) {
+ if (!hasErrorMessage()) {
+ setErrorMessage(getFieldMessagePrefix() + "Path segment \"splits[i]\" failed verification ");
+ }
+ return false;
+ }
+ }
+ clearErrorMessage();
+ return true;
+ }
+
+
+ protected boolean doCheckState(String path)
+ { // This is the real work of the original doCheckState()
+ if (path.length() == 0) {
+ return true;
+ }
+
+ String[] pathElems= path.split(";");
+
+ for(int i= 0; i < pathElems.length; i++) {
+ String pathElem= pathElems[i].trim();
+ File dir= new File(pathElem);
+
+ if (!dir.isDirectory()) {
+ setErrorMessage(getFieldMessagePrefix() + "Path list contains a name that is not a directory name");
+ return false;
+ }
+ }
+ // Error message cleared in doCheckState();
+ //clearErrorMessage();
+ return true;
+ }
+
+
+ /**
+ * Helper that opens the directory chooser dialog.
+ * @param startingDirectory The directory the dialog will open in.
+ * @return File File or <code>null</code>.
+ *
+ */
+ private File getDirectory(File startingDirectory) {
+ DirectoryDialog fileDialog = new DirectoryDialog(getShell(), SWT.OPEN);
+ if (startingDirectory != null)
+ fileDialog.setFilterPath(startingDirectory.getPath());
+ String dir = fileDialog.open();
+ if (dir != null) {
+ dir = dir.trim();
+ if (dir.length() > 0)
+ return new File(dir);
+ }
+ return null;
+ }
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/DoubleFieldEditor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/DoubleFieldEditor.java
new file mode 100644
index 000000000..3d9c188c7
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/DoubleFieldEditor.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences.fields;
+
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesTab;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+
+public class DoubleFieldEditor extends StringFieldEditor {
+
+ // From DoubleFieldEditor
+ protected double minValidValue = Double.MIN_VALUE;
+ protected double maxValidValue = Double.MAX_VALUE;
+ protected static final int DEFAULT_TEXT_LIMIT = 15;
+
+ protected String errorMessage =
+ "Value must be a double-precision floating-point number between " + minValidValue + " and " + maxValidValue;
+
+ /**
+ * Creates a double field editor
+ * Use the method <code>setTextLimit</code> to limit the text.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param width the width of the text input field in characters,
+ * or <code>UNLIMITED</code> for no limit
+ * @param strategy either <code>VALIDATE_ON_KEY_STROKE</code> to perform
+ * on the fly checking (the default), or <code>VALIDATE_ON_FOCUS_LOST</code> to
+ * perform validation only after the text has been typed in
+ * @param parent the parent of the field editor's control
+ * @since 2.0
+ */
+ public DoubleFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level, String name, String labelText,
+ int width, int strategy, Composite parent)
+ {
+ super(page, tab, service, level, name, labelText, width, strategy, parent);
+ }
+
+
+ /**
+ * Creates a string field editor.
+ * Use the method <code>setTextLimit</code> to limit the text.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param width the width of the text input field in characters,
+ * or <code>UNLIMITED</code> for no limit
+ * @param parent the parent of the field editor's control
+ */
+ public DoubleFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level, String name, String labelText,
+ int width, Composite parent)
+ {
+ super(page, tab, service, level, name, labelText, width, org.eclipse.jface.preference.StringFieldEditor.VALIDATE_ON_KEY_STROKE, parent);
+ }
+
+
+ /**
+ * Creates a string field editor of unlimited width.
+ * Use the method <code>setTextLimit</code> to limit the text.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param parent the parent of the field editor's control
+ */
+ public DoubleFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level, String name, String labelText,
+ Composite parent)
+ {
+ // Replaced UNLIMITED text width in the following with default
+ super(page, tab, service, level, name, labelText, DEFAULT_TEXT_LIMIT, parent);
+ }
+
+
+ /**
+ * Copied from IntegerFieldEditor.
+ *
+ * Sets the range of valid values for this field.
+ *
+ * @param min the minimum allowed value (inclusive)
+ * @param max the maximum allowed value (inclusive)
+ */
+ public void setValidRange(double min, double max) {
+ minValidValue = min;
+ maxValidValue = max;
+ }
+
+
+
+ /**
+ * Copied from IntegerFieldEditor.
+ *
+ * Returns this field editor's current value as an integer.
+ *
+ * @return the value
+ * @exception NumberFormatException if the <code>String</code> does not
+ * contain a parsable integer
+ */
+ public double getDoubleValue() throws NumberFormatException {
+ return Double.parseDouble(getStringValue());
+ }
+
+
+ /* (non-Javadoc)
+ * Copied from IntegerFieldEditor (with minor adaptations).
+ * Method declared on StringFieldEditor.
+ * Checks whether the entered String is a valid integer or not.
+ */
+ protected boolean checkState() {
+
+ Text text = getTextControl(parent);
+
+ if (text == null)
+ return false;
+
+
+ String numberString = text.getText();
+ if (numberString==null || numberString.equals("")) numberString="0";
+ try {
+ double number = Double.valueOf(numberString);
+ if (number >= minValidValue && number <= maxValidValue) {
+ clearErrorMessage();
+ return true;
+ } else {
+ setErrorMessage(getLevelName() + ": " + getLabelText() + " " + errorMessage);
+ return false;
+ }
+ } catch (NumberFormatException e1) {
+ setErrorMessage(getLevelName() + ": " + getLabelText() + " " + "Number format exception");
+ }
+
+ return false;
+ }
+
+
+ public String getLevelName() {
+ if (preferencesLevel.equals(IPreferencesService.DEFAULT_LEVEL)) return "Default";
+ if (preferencesLevel.equals(IPreferencesService.CONFIGURATION_LEVEL)) return "Configuration";
+ if (preferencesLevel.equals(IPreferencesService.INSTANCE_LEVEL)) return "Workspace";
+ if (preferencesLevel.equals(IPreferencesService.PROJECT_LEVEL)) return "Project";
+ return "";
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/FieldEditor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/FieldEditor.java
new file mode 100644
index 000000000..a815c1f11
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/FieldEditor.java
@@ -0,0 +1,957 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.preferences.fields;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesTab;
+import org.eclipse.imp.preferences.PreferencesUtilities;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+
+/**
+ * Points to note:
+ * - Preferences service instead of a preference store
+ * - Preferences have a level
+ * - Four fixed levels
+ * - Named by strings because ...
+ * - Makes some provision for loading, etc. into fields
+ * on pages that are *not* associated with a level (just in case)
+ * - Preferences are displayed on a tab on a page
+ * - Preference values may be inherited
+ *
+ * @author sutton
+ *
+ */
+
+
+
+public abstract class FieldEditor extends org.eclipse.jface.preference.FieldEditor
+{
+ protected static final List<String> PREFS_LEVELS_AS_LIST= Arrays.asList(IPreferencesService.levels);
+
+ /**
+ * The preferences page on which the tab that contains this
+ * field is displayed
+ */
+ // Relationship to dialogPage in FieldEditor?
+ protected PreferencePage prefPage = null;
+
+ /**
+ * The preferences tab on which the field is displayed
+ */
+ protected PreferencesTab prefTab = null;
+
+
+ /**
+ * The preferences service in which the values for this
+ * field are stored
+ */
+ protected IPreferencesService preferencesService = null;
+
+ /**
+ * The preferences level with which this field is associated
+ */
+ protected String preferencesLevel = null;
+
+ /**
+ * The Composite control that contains the field
+ */
+ protected Composite parent = null;
+
+ /**
+ * Whether the value shown for this field is stored on
+ * the level for this field or inherited from a higher level
+ */
+ protected boolean isInherited = false;
+
+ /**
+ * Whether the value shown for this field was previously stored on
+ * the level for this field or inherited from a higher level
+ */
+ protected boolean wasInherited = false;
+
+ /**
+ * Whether the value stored for this field (if any) can be
+ * removed. (Removal of a value on a lower level will
+ * generally result in the inheritance of a value from a
+ * higher level. The effects of removal of values at the
+ * top ("default") are not defined and this should generally
+ * not be allowed.)
+ */
+ protected boolean isRemovable = false;
+
+ /**
+ * Flags whether the field has an associated "special"
+ * (distinguished) value (the purpose of which is
+ * generally field specific)
+ */
+ protected boolean hasSpecialValue = false;
+
+ /**
+ * A general placeholder for a special (distinguished) value
+ * that may be associated with this field (the purpose of
+ * which is generally field specific)
+ */
+ // Not sure whether such a general representation will be
+ // useful, but it conveys the idea
+ protected Object specialValue = null;
+
+
+ /**
+ * Name of the preferences level from which the value
+ * displayed by this field was loaded. If non-null then
+ * will generally be one of the four standard level names.
+ */
+ protected String levelFromWhichLoaded = null;
+
+
+ /**
+ * Whether the value held by the field is the same as the
+ * value stored in the corresponding preferences node (that
+ * is, the node from which it was most recently loaded or
+ * the node into which it was most recently stored)
+ */
+ protected boolean fieldModified = false;
+
+
+ protected Object previousValue = null;
+
+ protected String toolTipText = null;
+
+ //
+ // Fields in FieldEditor:
+ //
+
+ // private String preferenceName has public get and set methods
+
+ // private *** preferenceStore is deprecated (along with any associated methods)
+
+ // private boolean field isDefaultPresented has public read and write methods
+
+ // private String labelText has public (or protected) get and set methods;
+ // also settable through init (called by constructors but protected and not
+ // apparently limited to use at construction time)
+
+ // private Label label has public and protected get methods; public
+ // one creates when first called; no other set methods (makes sense)
+
+ // private field IPropertyChangeListener propertyChangeListener has a public
+ // set method but no get method (needed here?)
+
+ // private field DialogPage page has public get and set methods
+
+ // Note: there is no parent field
+
+
+
+
+ /**
+ * Parameterless constructor that mimics the one in FieldEditor
+ */
+ protected FieldEditor() {
+ super();
+ }
+
+
+ /**
+ * Creates a field editor, taking the information that is
+ * specific to IMP field editors but not that used by
+ * field editors in general. Calls the empty constructor for
+ * a field editor.
+ *
+ * @param page The preferences page on which the tab is shown
+ * @param tab The tab on which field editor is shown
+ * @param service The preferences service in which the preference
+ * values are stored
+ * @param level The level at which this preference is assigned
+ */
+ // Able to do anything useful without a parent?
+ public FieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level)
+ {
+ super();
+ preferencesService = service;
+ preferencesLevel = level;
+ prefPage = page;
+ setPage(prefPage);
+ prefTab = tab;
+ }
+
+
+ /**
+ * Creates a field editor, taking all of the relevant information
+ * (IMP specific and field-editor generic). Calls the non-empty
+ * constructor for a field editor.
+ *
+ * @param page The preferences page on which the tab is shown
+ * @param tab The tab on which field editor is shown
+ * @param service The preferences service in which the preference
+ * values are stored
+ * @param level The level at which this preference is assigned
+ * @param name The name of this preference
+ * @param labelText The text used to label the field on the page
+ * @param parent The composite control that contains this editor
+ */
+ public FieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level,
+ String name, String labelText, Composite parent)
+ {
+ //super(name, labelText, parent);
+ super();
+ init(name, labelText);
+ preferencesService = service;
+ preferencesLevel = level;
+ this.parent = parent;
+ prefPage = page;
+ setPage(prefPage);
+ prefTab = tab;
+ }
+
+
+
+ /*
+ * Methods to get and set the preferences level from which the value
+ * of this field was loaded (or set)
+ */
+
+
+
+ /**
+ * Get the preferences level from which the value of this field
+ * was set. Should be the name of a preferences level if the
+ * value was set from a preferences node, or null if the value
+ * was set directly into the field.
+ *
+ * @return The preferencesl level from which the current value
+ * for this field was loaded, or null if the current value
+ * was set directly
+ */
+ public String getLevelFromWhichLoaded() {
+ return levelFromWhichLoaded;
+ }
+
+
+
+
+ /*
+ * Methods to get and set the isInherited field for this editor
+ */
+
+ /**
+ * @return Whether the value displayed for this field is
+ * stored at the level of this field or inherited from
+ * a higher level
+ */
+ public boolean isInherited() { return isInherited; }
+
+
+ /**
+ * Sets the field that indicates whether the value displayed for
+ * this field is stored on the level for this field or inherited from
+ * a higher level.
+ *
+ * @param inherited Whether the value is stored or inherited
+ */
+ protected void setInherited(boolean inherited) {
+ wasInherited = isInherited;
+ isInherited = inherited;
+ }
+
+
+ /**
+ * @return Whether the inheritance state of this field has changed
+ * from its previous value
+ */
+ protected boolean inheritanceChanged() {
+ return wasInherited != isInherited;
+ }
+
+
+ /*
+ * Methods relating to a special value for this field.
+ *
+ * The value is an Object, which is not very specific
+ * (but is very general).
+ *
+ * Fields that are intended to represent value types
+ * (which does not seem to be a common practice) can
+ * convert values to objects if necessary to use these.
+ */
+
+
+ /**
+ * @return Whether there is a special (distinguished) value
+ * associated with this field
+ */
+ public boolean hasSpecialValue() { return hasSpecialValue; }
+
+
+ /**
+ * Sets the flag hasSpecialValue to false and nullifies
+ * the specialValue field.
+ *
+ */
+ public void setNoSpecialValue() {
+ hasSpecialValue = false;
+ specialValue = null;
+ }
+
+ /**
+ * @return The special value associated with this field,
+ * if any
+ * @throws IllegalStateException if this field has no
+ * associated special value
+ */
+ public Object getSpecialValue() {
+ if (hasSpecialValue) return specialValue;
+ throw new IllegalStateException("FieldEditor.getSpecialValue(): called when field does not have a special value");
+ }
+
+
+ /**
+ * Assigns the given object to the special value for this
+ * field and sets the hasSpecialValue flag to true.
+ *
+ * @param specialValue The special value associated with this field.
+ */
+ public void setSpecialValue(Object specialValue) {
+ hasSpecialValue = true;
+ this.specialValue = specialValue;
+ }
+
+
+// Empty is a sting-related concept, not for fields in general
+//
+// public boolean isEmptyValueAllowed() {
+// return isEmptyStringAllowed();
+// }
+//
+// public void setEmptyValueAllowed(boolean allowed) {
+// setEmptyStringAllowed(allowed);
+// }
+//
+//
+// public String getEmptyValue() {
+// if (isEmptyStringAllowed())
+// return emptyValue;
+// throw new IllegalStateException("StringFieldEditor.getEmptyValue: called when field does not allow an empty value");
+// }
+
+
+ /*
+ * Methods relating to the removal of field values
+ */
+
+
+ /**
+ * @return Whether the value stored for this field (if any)
+ * can be removed
+ */
+ public boolean isRemovable() { return isRemovable; }
+
+
+ /**
+ * Sets whether the value stored for this field (if any)
+ * can be removed
+ *
+ * @param isRemovable Whether ...
+ */
+ public void setRemovable(boolean isRemovable) {
+ this.isRemovable = isRemovable;
+ }
+
+
+ ////////////////////////////////////////////////////////////////////////////
+
+
+ /*
+ * Methods related to loading a value for the field. "Loading" a value for
+ * a field means setting the value that the field is to display.
+ * Because of multiple preference levels and inheritance of preference values
+ * this is a more varied and complicated concern than with FieldEditor.
+ */
+
+
+ /**
+ * Initializes this field editor with a preference value from
+ * the preference service.
+ *
+ * If the field is associated with a specific preference level (the
+ * usual case) then the value from that level, if any, is loaded.
+ *
+ * If the field is not associated with a specific preference level,
+ * then a value obtained from some applicable level may be loaded.
+ * (This is a feature that supports preferences pages that are not
+ * strictly aligned with preferences levels, unlike the "usual"
+ * approach assumed here.)
+ *
+ * Because it cannot be guaranteed here that the value that is loaded
+ * is not inherited, the flag isDefaultPresented cannot be set to
+ * false here (as it can in FieldEditor).
+ */
+ public void load() {
+ if (preferencesService != null) {
+ //isDefaultPresented = false;
+ doLoad();
+ refreshValidState();
+ }
+ }
+
+
+
+
+
+ /**
+ * Do the work of loading
+ */
+ abstract protected void doLoad();
+
+// // This is an example implementation from the IMP String field editor
+// // with level-specific and level-independent branches:
+// {
+// if (getTextControl() != null) {
+// String value = null;
+// if (preferencesLevel != null) {
+// // The "normal" case, in which field corresponds to a preferences level
+// value = preferencesService.getStringPreference(preferencesLevel, getPreferenceName());
+// levelFromWhichLoaded = preferencesLevel;
+// setInherited(false);
+// }
+// else {
+// // Not normal, exactly, but possible if loading is being done into a
+// // field that is not associated with a specific level
+// value = preferencesService.getStringPreference(getPreferenceName());
+// levelFromWhichLoaded = preferencesService.getApplicableLevel(getPreferenceName(), preferencesLevel);
+// setInherited(true);
+// }
+// if (IPreferencesService.DEFAULT_LEVEL.equals(levelFromWhichLoaded))
+// setPresentsDefaultValue(true);
+// previousValue = value;
+// setStringValue(value);
+// }
+// }
+
+
+
+ /**
+ * Initializes this field editor with the value associated with the
+ * default level of the preference store.
+ */
+ public void loadDefault() {
+ if (preferencesService != null) {
+ setPresentsDefaultValue(true);
+ doLoadDefault();
+ refreshValidState();
+ }
+ }
+
+ /**
+ * Do the work of loading the default value into the field.
+ * Generally depends on the type of the field.
+ */
+ abstract protected void doLoadDefault();
+
+// // This is an example implementation from the IMP String field editor:
+// {
+// if (getTextControl() != null) {
+// String value = preferencesService.getStringPreference(IPreferencesService.DEFAULT_LEVEL, getPreferenceName());
+// setStringValue(value);
+// }
+// // empty in FieldEditor:
+// refreshValidState();
+// // Comments on valueChanged() says it is not called when
+// // a value is initialized or restored from default so
+// // don't call that here
+// }
+
+
+
+ /**
+ * Set this field with the preference value associated with
+ * the given level. Sets presentsDefaultValue to true if the
+ * given level is "default".
+ */
+ public void loadLevel(String level) {
+ if (preferencesService != null &&
+ preferencesService.isaPreferencesLevel(level))
+ {
+ doLoadLevel(level);
+ if (IPreferencesService.DEFAULT_LEVEL.equals(level))
+ setPresentsDefaultValue(true);
+ // SMS 25 Nov 2006
+ // still need to signal valueChanged on default level?
+// else
+ // SMS 15 Nov 2006: try this if not default level
+ valueChanged();
+ refreshValidState();
+ }
+ }
+
+ /**
+ * Do the work of loading the value for the given level into the field.
+ * Generally depends on the type of the field.
+ */
+ abstract protected void doLoadLevel(String level);
+
+// // This is an example implementation from the IMP String field editor:
+// {
+// if (getTextControl() != null) {
+// String value = null;
+// if (preferencesLevel != null) {
+// value = preferencesService.getStringPreference(level, getPreferenceName());
+// } else {
+// value = preferencesService.getStringPreference(getPreferenceName());
+// }
+// setStringValue(value);
+// }
+// //valueChanged();
+// }
+
+
+
+ /**
+ * Set this field with the currently applicable preference value,
+ * inheriting the value from a higher level if the value is not
+ * stored on the level associated with the field. (The "default"
+ * level should always have a value.)
+ *
+ * @return The level from which the value was loaded
+ */
+ public String loadWithInheritance() {
+ if (preferencesService != null) {
+ levelFromWhichLoaded = doLoadWithInheritance();
+ if (IPreferencesService.DEFAULT_LEVEL.equals(levelFromWhichLoaded))
+ setPresentsDefaultValue(true);
+ refreshValidState();
+ }
+ return levelFromWhichLoaded;
+ }
+
+
+ /**
+ * Do the work of setting the currently applicable value for this field,
+ * inheriting the value from a higher level if the value is not stored
+ * on the level associated with the field. (The "default" level should
+ * always have a value.) Load nothing and return null if no value is found.
+ *
+ * Should set varous fields such as levelFromWhichLoaded, previousValue,
+ * isInherited, and fieldModified. Should also adjust the appearance of
+ * the field on the preferences page to reflect inherited state.
+ *
+ * @return The level from which the applicable value was loaded or
+ * null if no value found.
+ */
+ abstract protected String doLoadWithInheritance();
+
+// // This is an example implementation from the IMP String field editor:
+// {
+// String levelLoaded = null;
+//
+// String[] levels = IPreferencesService.levels;
+// int fieldLevelIndex = 0;
+//
+// // If we're loading with inheritance for some field that is
+// // not attached to a preferences level (such as the "applicable"
+// // field, which inherits values from all of the real fields)
+// // then assume that we should just search from the bottom up
+// String tmpPreferencesLevel =
+// (preferencesLevel == null)?
+// levels[0]:
+// preferencesLevel;
+//
+// // Find the index of the level to which this field belongs
+// for (int i = 0; i < levels.length; i++) {
+// if (tmpPreferencesLevel.equals(levels[i])) {
+// fieldLevelIndex = i;
+// break;
+// }
+// }
+//
+// String value = null;
+// int levelAtWhichFound = -1;
+//
+// for (int level = fieldLevelIndex; level < levels.length; level++) {
+// value = preferencesService.getStringPreference(levels[level], getPreferenceName());
+// if (value == null) continue;
+// if (value.equals("") && !isEmptyStringAllowed()) continue;
+// levelAtWhichFound = level;
+// levelLoaded = levels[levelAtWhichFound];
+// break;
+// }
+//
+// // Set the field to the value we found
+// setStringValue(value);
+//
+// // We loaded it at this level or inherited it from some other level
+// setInherited(fieldLevelIndex != levelAtWhichFound);
+//
+// // Since we just loaded some new text, it won't be modified yet
+// fieldModified = false;
+//
+// // TODO: Check on use of previous value
+// previousValue = value;
+//
+// // Set the background color of the field according to where found
+// Text text = getTextControl();
+// if (isInherited())
+// text.setBackground(PreferencesUtilities.colorBluish);
+// else
+// text.setBackground(PreferencesUtilities.colorWhite);
+//
+// //System.out.println("doLoadWithInheritance: preferencesName = " + getPreferenceName() + "; preferenceLevel = " + preferencesLevel + "; levelLoaded = " + levelLoaded);
+//
+// return levelLoaded;
+// }
+
+
+
+
+ /*
+ * Methods relating to storing the value of a field.
+ */
+
+
+ /**
+ * Store the value in this field, using the preferences service,
+ * at the level associated with this field.
+ *
+ * Checks many preconditions. Throws an exception if the preferences
+ * service or preferences level is null or if the associated level is
+ * the project level but no project is set. Returns without effect if
+ * the value is inherited, if the value is the default value, or if the
+ * field is not modified.
+ *
+ * Why not store inherited values? Inherited values are shown for a
+ * field when the field has no value of its own. They are shown because
+ * they apply on the field's level but they are not actually set (or stored)
+ * on that level. Since there is no value actually set for the field,
+ * there is no value to store for it. Note that separate controls on
+ * a preferene page may make it possible to adopt an inherited value for
+ * a field (that is, to copy it into the field), after which it can be stored.
+ *
+ * Also sets fieldModified to false (since it was just stored and hasn't
+ * been changed yet) and levelFromWhichLoaded to the level associated with
+ * the current field.
+ *
+ * @throws IllegalStateException
+ * if the preferences service is null, if the preferences
+ * level is null, or if the associated level is the project
+ * level but no project is set
+ *
+ */
+ public void store() {
+
+ // Don't store if the preferences service is null, since that may
+ // represent an illegal state and anyway we need to refer to it below
+ if (preferencesService == null) {
+ throw new IllegalStateException("FieldEditor.store(): attempt to store when preferences service is null");
+ }
+
+ // Can't store the value If there is no valid level (not having a preferences level
+ // isn't necessarily an error, but it does prevent storing)
+ //if (preferencesLevel == null) return;
+ if (preferencesService == null) {
+ throw new IllegalStateException("FieldEditor.store(): attempt to store when preferences level is null");
+ }
+
+ // Don't store a value that comes from some other level
+ if (isInherited) return;
+ //if (presentsDefaultValue()) return;
+
+ // Don't bother storing if the field hasn't been modified
+ if (!fieldModified) return;
+
+ // Don't store the value if the field's level is the project level
+ // but no project is selected
+ if (IPreferencesService.PROJECT_LEVEL.equals(preferencesLevel) &&
+ preferencesService.getProject() == null)
+ {
+ throw new IllegalStateException("FieldEditor.store(): attempt to store project preference when project is not set");
+ }
+
+ // If the level is the default level, go ahead and store it even
+ // though preferences on the default level aren't persistent:
+ // the preference still needs to be stored into the default preference
+ // node (since that is needed to put the new value into effect, and
+ // why provide a new value if you don't want it to go into effect?)
+ // and the flushing of that node doesn't have any effect in any case.
+ // In other words, do not return if the level is the default level
+
+ // Store the value
+ doStore();
+
+ // If we've just stored the field, we've addressed any modifications
+ //System.out.println("STFE.store: setting fieldModified to FALSE");
+ fieldModified = false;
+ levelFromWhichLoaded = preferencesLevel;
+ }
+
+
+ /**
+ * Do the work of actually storing the value.
+ * Generally depends on the specific type of the field.
+ * May also need to check field-specific conditions (e.g., whether
+ * empty values are allowed).
+ * If necessary also adjust appearance of field on the preference
+ * page to reflect the non-inherited state.
+ */
+ abstract protected void doStore();
+
+// // This is an example implementation from the IMP String field editor:
+// {
+// String value = getTextControl().getText();
+// boolean isEmpty = value.equals(emptyValue); // Want empty value, but can't call method to retrieve it
+// // with fields where empty is not allowed
+// // getText() will return an empty string if the field is empty,
+// // and empty strings can be stored in the preferences service,
+// // but an empty string is recognized by the preferences service
+// // as a valid value--when usually it is not. Once it is recognized
+// // as a valid value, it precludes the searching of subsequent
+// // levels that might contain a non-empty (and actually valid) value.
+// // We would like to be able to store a null value with the preferences
+// // service so as to not short-circuit the search process, but we can't
+// // do that. So, if the field value is empty, we have to eliminate the
+// // preference entirely. (Will that work in general???)
+// if (isEmpty && !isEmptyStringAllowed()) {
+// // We have an empty value where that isn't allowed, so clear the
+// // preference. Expect that clearing the preferences at a level will
+// // trigger a loading with inheritance at that level
+// preferencesService.clearPreferenceAtLevel(preferencesLevel, getPreferenceName());
+// // If the preference value was previously empty (e.g., if previously inherited)
+// // then clearing the preference node now doesn't cause a change event, so
+// // doesn't trigger reloading with inheritance. So we should just load the
+// // field again to make sure any inheritance occurs if needed
+// loadWithInheritance();
+// return;
+// }
+// // Shouldn't need this check here now
+// if (isInherited() && !fieldModified) {
+// // We have a value but it's inherited
+// // (left over from after the last time we cleared the field)
+// // so don't need (or want) to store it
+// return;
+// }
+// // We have a value (possibly empty, if that is allowed) that has changed
+// // from the previous value, so store it
+// preferencesService.setStringPreference(preferencesLevel, getPreferenceName(), value);
+//
+// // If we've just stored the field, we've addressed any modifications
+// // Shouldn't need these here now
+// fieldModified = false;
+// levelFromWhichLoaded = preferencesLevel;
+// // If we've stored the field then it's not inherited, so be sure it's
+// // color indicates that.
+// // For text fields, the background color is the backgroud color within
+// // the field, so don't have to worry about matching anything else
+// getTextControl().setBackground(PreferencesUtilities.colorWhite);
+//
+// IEclipsePreferences node = preferencesService.getNodeForLevel(preferencesLevel);
+// try {
+// if (node != null) node.flush();
+// } catch (BackingStoreException e) {
+// System.err.println("StringFieldEditor. (): BackingStoreException flushing node; node may not have been flushed:" +
+// "\n\tnode path = " + node.absolutePath() + ", preferences level = " + preferencesLevel);
+// }
+// }
+
+
+ /*
+ * Methods relating the preferences level associated with this field
+ */
+
+
+ /**
+ * Set the preference level associated with this field to the given level.
+ *
+ * @param The string name of a preference level
+ * @throws IllegalArgumentException
+ * if the given value does not denote a preference level
+ */
+ public void setPreferencesLevel(String level) {
+ if (!preferencesService.isaPreferencesLevel(level)) {
+ throw new IllegalArgumentException("FieldEditor.setPreferencesLevel(): given level = " + level + " is invalid");
+ }
+ preferencesLevel = level;
+ }
+
+
+ /**
+ * @return The string name of the preference level associated with
+ * this field
+ */
+ public String getPreferencesLevel() {
+ return preferencesLevel;
+ }
+
+
+ /*
+ * Subtypes will require methods to get and set the value of the field; these
+ * will depend on the type of the value.
+ *
+ * The method to set the value should set previousValue to the value
+ * in effect at the time of the call, set fieldModified to true, set
+ * levelFromWhichLoaded to the level associated with the field, and
+ * call valueChanged(). It should also set presentsDefaultValue
+ * according to whether the value set is the same as the value that
+ * is set on the "default" level (regardless of whether the value has
+ * been set from that level).
+ */
+
+ /*
+ * Subtypes will also require methods to get the applicable UI Control.
+ * These methods will be dependent on the type of the field, which will
+ * determine the type of control (e.g., TextControl, ChangeControl).
+ *
+ * The typical pattern for such methods is to check whether the control
+ * exists and, if not, to create it, adding a ModifyListener and a
+ * DisposeListener.
+ *
+ * If the parent control (a Composite) is needed for obtaining the field's
+ * control, then it is also advisable to check whether the paretn is disposed
+ * (as attempts to get controls from a disposed parent typically fail).
+ *
+ * A null value can be returned if no real control is found.
+ */
+
+
+ /**
+ * @return The parent control of this field
+ */
+ public Composite getParent() {
+ return parent;
+ }
+
+ /**
+ * @return the "holder" of this field, which can be enabled/disabled as a group
+ * (usually different from the parent)
+ */
+ public abstract Composite getHolder();
+
+ /**
+ * Should call the supertype method fireValueChanged() to inform this
+ * field editor's listener, if it has one, about a change to the value
+ * (<code>VALUE</code> property), provided that the old and new values
+ * are different.
+ *
+ * This hook is <em>not</em> called when the text is initialized
+ * (or reset to the default value) from the preference store.
+ *
+ * The means of obtaining the current value (for comparison with the
+ * old) will probably depend on the type of the field and its control.
+ *
+ * This method should probably not adjust any of the fields associated
+ * with the field editor, as those should have been set appropriately
+ * at the point where valueChanged() was called.
+ */
+ abstract protected boolean valueChanged();
+
+
+ /*
+ * FieldEditor contains a method refreshValidState() that has an
+ * empty implementation. That method can be overridden in subtypes
+ * to update the validity status of a value.
+ */
+
+
+ /**
+ * A utility method to trigger the reevaluation of the
+ * validity state of the preferences tab.
+ * (Started out doing more; may not be as useful now as
+ * it was once expected to be.)
+ * Need to promote notification of preference page
+ * from field to tab.
+ */
+ protected boolean notifyState(boolean state)
+ {
+// if (prefPage != null)
+// prefPage.setValid(state);
+ if (prefTab != null)
+ prefTab.setValid(state);
+
+ return state;
+ }
+
+
+ /*
+ * Methods related to marking modified fields
+ */
+
+
+ public void setModifiedMarkOnLabel() {
+// SMS 27 Nov 2006: needed here? should be up to caller
+// if (isInherited) return;
+ Label label = getLabelControl(parent);
+ if (label != null) {
+// String labelText = label.getText();
+// if (!labelText.startsWith(Markings.MODIFIED_MARK)) {
+// labelText = Markings.MODIFIED_MARK + labelText;
+// label.setText(labelText);
+// }
+ // replace changed mark by color to eliminate text-box overflow bug
+ label.setForeground(PreferencesUtilities.colorRed);
+ }
+ }
+
+
+ public void clearModifiedMarkOnLabel() {
+ Label label = getLabelControl(parent);
+ if (label != null) {
+// String labelText = label.getText();
+// if (labelText.startsWith(Markings.MODIFIED_MARK))
+// labelText = labelText.substring(Markings.MODIFIED_MARK.length());
+// label.setText(labelText);
+ label.setForeground(PreferencesUtilities.colorBlack);
+ }
+ }
+
+
+
+ /*
+ * Methods related to error messages
+ */
+
+ protected void clearErrorMessage() {
+ prefTab.clearErrorMessages(this);
+ }
+
+ protected void setErrorMessage(String msg) {
+ prefTab.setErrorMessage(this, msg);
+ }
+
+ public boolean hasErrorMessage() {
+ return prefTab.errorMessages.containsKey(this);
+ }
+
+
+ public String getFieldMessagePrefix() {
+ return /*prefTab.getTabItem().getText() + " Tab: " +*/ getLabelText() + ": ";
+ }
+
+
+ protected abstract void doSetToolTip();
+
+ public void setToolTipText(String toolTipText) {
+ this.toolTipText= toolTipText;
+ doSetToolTip();
+ }
+
+ public String getToolTipText() {
+ return toolTipText;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/FileFieldEditor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/FileFieldEditor.java
new file mode 100644
index 000000000..329b4a116
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/FileFieldEditor.java
@@ -0,0 +1,241 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences.fields;
+
+import java.io.File;
+import java.util.Stack;
+
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesTab;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.preference.StringFieldEditor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.FileDialog;
+
+public class FileFieldEditor extends StringButtonFieldEditor
+{
+
+ public FileFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level, String name, String labelText,
+ int width, int strategy, Composite parent)
+ {
+ super(page, tab, service, level, name, labelText, width, strategy, parent);
+ this.getChangeControl(parent).setText(PreferenceDialogConstants.BROWSE_LABEL);
+ }
+
+
+ /**
+ * Creates an IMP file field editor.
+ * Use the method <code>setTextLimit</code> to limit the text.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param width the width of the text input field in characters,
+ * or <code>UNLIMITED</code> for no limit
+ * @param parent the parent of the field editor's control
+ */
+ public FileFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level, String name, String labelText,
+ int width, Composite parent)
+ {
+ super(page, tab, service, level, name, labelText, width, StringFieldEditor.VALIDATE_ON_KEY_STROKE, parent);
+ this.getChangeControl(parent).setText(PreferenceDialogConstants.BROWSE_LABEL);
+ }
+
+
+ /**
+ * Creates an IMP string button field editor.
+ * Use the method <code>setTextLimit</code> to limit the text.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param parent the parent of the field editor's control
+ */
+ public FileFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level, String name, String labelText, Composite parent)
+ {
+ super(page, tab, service, level, name, labelText, parent);
+ this.getChangeControl(parent).setText(PreferenceDialogConstants.BROWSE_LABEL);
+ }
+
+
+
+ /*
+ * Below copied from org.eclipse.jface.preference.FileFieldEditor
+ */
+
+
+ /**
+ * List of legal file extension suffixes, or <code>null</code>
+ * for system defaults.
+ */
+ private String[] extensions = null;
+
+ /**
+ * Indicates whether the path must be absolute;
+ * <code>false</code> by default.
+ */
+ private boolean enforceAbsolute = false;
+
+
+ /* (non-Javadoc)
+ * Method declared on StringButtonFieldEditor.
+ * Opens the file chooser dialog and returns the selected file.
+ */
+ protected String changePressed() {
+ File f = new File(getTextControl(parent).getText());
+ if (!f.exists())
+ f = null;
+ File d = getFile(f);
+ if (d == null)
+ return null;
+
+ return d.getAbsolutePath();
+ }
+
+ public boolean getEnforceAbsolute() {
+ return enforceAbsolute;
+ }
+
+
+ public void setEnforceAbsolute(boolean enforceAbsolute) {
+ this.enforceAbsolute = enforceAbsolute;
+ }
+
+ /**
+ * Helper to open the file chooser dialog.
+ * @param startingDirectory the directory to open the dialog on.
+ * @return File The File the user selected or <code>null</code> if they
+ * do not.
+ */
+ protected File getFile(File startingDirectory) {
+ FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);
+ if (startingDirectory != null)
+ dialog.setFileName(startingDirectory.getPath());
+ if (extensions != null)
+ dialog.setFilterExtensions(extensions);
+ String file = dialog.open();
+ if (file != null) {
+ file = file.trim();
+ if (file.length() > 0)
+ return new File(file);
+ }
+ return null;
+ }
+
+ /**
+ * Sets this file field editor's file extension filter.
+ *
+ * @param extensions a list of file extension, or <code>null</code>
+ * to set the filter to the system's default value
+ */
+ public void setFileExtensions(String[] extensions) {
+ this.extensions = extensions;
+ }
+
+
+
+
+
+ // getErrorMessage() is defined on StringFieldEditor,
+ // and can be set with setErrorMessage(String);
+
+
+ protected boolean doCheckState()
+ {
+
+ String msg = null;
+
+ // Here we check for empty or null strings, although
+ // this may very well be checked at a higher level
+ // (so we might not ever get here with this problem)
+ String path = getTextControl(parent).getText();
+ path= preferencesService.performSubstitutions(path);
+ if (path != null)
+ path = path.trim();
+ else
+ path = "";//$NON-NLS-1$
+ if (path.length() == 0 && !emptyStringAllowed) {
+ setErrorMessage(getFieldMessagePrefix() + "Path length is zero when empty string is not allowed");
+ return false;
+ }
+
+ // Check for balanced quotes
+ final String singleQuote = "'";
+ final String doubleQuote = "\"";
+ Stack stack = new Stack();
+ for (int i = 0; i < path.length(); i++) {
+ if (path.charAt(i) == '\'') {
+ if (!stack.empty() && singleQuote.equals(stack.peek()))
+ stack.pop();
+ else
+ stack.push(singleQuote);
+ }
+ if (path.charAt(i) == '"') {
+ if (!stack.empty() && doubleQuote.equals(stack.peek()))
+ stack.pop();
+ else
+ stack.push(doubleQuote);
+ }
+ }
+ if (stack.size() != 0)
+ return false;
+
+ // Now validate list segments between quotes
+ path = path.replace("\"", "'");
+ String[] splits = path.split("'");
+ boolean splitsVerified = true;
+ int start = path.startsWith("'") ? 1 : 0;
+ for (int i = start; i < splits.length; i++) {
+ splitsVerified = splitsVerified && doCheckState(splits[i]);
+ if (!splitsVerified) {
+ if (!hasErrorMessage()) {
+ setErrorMessage(getFieldMessagePrefix() + "Path segment \"splits[i]\" failed verification");
+ }
+ return false;
+ }
+ }
+ clearErrorMessage();
+ return true;
+
+ }
+
+
+ protected boolean doCheckState(String path)
+ { // This is the real work of the original doCheckState()
+ String msg = null;
+ File file = new File(path);
+ if (file.isFile()) {
+ if (enforceAbsolute && !file.isAbsolute())
+ msg = JFaceResources.getString("FileFieldEditor.errorMessage2");//$NON-NLS-1$
+ } else {
+ msg = "Path does not designate a valid file";
+ }
+
+ boolean result = true;
+ if (msg != null) {
+ setErrorMessage(getFieldMessagePrefix() + msg);
+ result = false;
+ } else {
+ clearErrorMessage();
+ result = true;
+ }
+
+ return result;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/FontFieldEditor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/FontFieldEditor.java
new file mode 100644
index 000000000..7cc282bb5
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/FontFieldEditor.java
@@ -0,0 +1,574 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Matthew Kaplan (mmk@us.ibm.com) - initial API and implementation
+*******************************************************************************/
+package org.eclipse.imp.preferences.fields;
+
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesTab;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.resource.StringConverter;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+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.FontDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * A field editor for font selection.
+ * Based on ComboFieldEditor with accommodations made for font Control
+ * @author rfuhrer@watson.ibm.com
+ */
+public class FontFieldEditor extends ChangeButtonFieldEditor {
+ private static final String DEFAULT_FONT_DESCRIPTOR= new FontData("courier", 12, SWT.NORMAL).toString();
+
+ /**
+ * The change font button, or <code>null</code> if none
+ * (before creation and after disposal).
+ */
+ private Button changeFontButton = null;
+
+ /**
+ * The text for the change font button, or <code>null</code>
+ * if missing.
+ */
+ private String changeButtonText;
+
+ /**
+ * The text for the preview, or <code>null</code> if no preview is desired
+ */
+ private String previewText;
+
+ /**
+ * Font data for the chosen font button, or <code>null</code> if none.
+ */
+ private FontData[] chosenFont;
+
+ /**
+ * The label that displays the selected font, or <code>null</code> if none.
+ */
+ private Label valueControl;
+
+ /**
+ * The previewer, or <code>null</code> if none.
+ */
+ private DefaultPreviewer previewer;
+
+ /**
+ * Internal font previewer implementation.
+ */
+ private static class DefaultPreviewer {
+ private Text text;
+
+ private String string;
+
+ private Font font;
+
+ /**
+ * Constructor for the previewer.
+ * @param s
+ * @param parent
+ */
+ public DefaultPreviewer(String s, Composite parent) {
+ string = s;
+ text = new Text(parent, SWT.READ_ONLY | SWT.BORDER);
+ text.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ if (font != null) {
+ font.dispose();
+ }
+ }
+ });
+ if (string != null) {
+ text.setText(string);
+ }
+ }
+
+ /**
+ * @return the control the previewer is using
+ */
+ public Control getControl() {
+ return text;
+ }
+
+ /**
+ * Set the font to display with
+ * @param fontData
+ */
+ public void setFont(FontData[] fontData) {
+ if (font != null) {
+ font.dispose();
+ }
+ font = new Font(text.getDisplay(), fontData);
+ text.setFont(font);
+ }
+
+ /**
+ * @return the preferred size of the previewer.
+ */
+ public int getPreferredExtent() {
+ return 40;
+ }
+ }
+
+ /**
+ * Creates a new font field editor
+ */
+ protected FontFieldEditor() {
+ }
+
+ /**
+ * Creates a font field editor with an optional preview area.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param previewAreaText the text used for the preview window. If it is
+ * <code>null</code> there will be no preview area,
+ * @param parent the parent of the field editor's control
+ */
+ public FontFieldEditor(String name, String labelText, String previewAreaText, Composite parent) {
+ init(name, labelText);
+ previewText = previewAreaText;
+ changeButtonText = JFaceResources.getString("openChange"); //$NON-NLS-1$
+ createControl(parent);
+ }
+
+ /**
+ * Creates a font field editor without a preview.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param parent the parent of the field editor's control
+ */
+ public FontFieldEditor(String name, String labelText, Composite parent) {
+ this(name, labelText, null, parent);
+ }
+
+ /* (non-Javadoc)
+ * Method declared on FieldEditor.
+ */
+ protected void adjustForNumColumns(int numColumns) {
+ GridData data = new GridData();
+ if (valueControl.getLayoutData() != null) {
+ data = (GridData) valueControl.getLayoutData();
+ }
+
+ data.horizontalSpan = numColumns - getNumberOfControls() + 1;
+ valueControl.setLayoutData(data);
+ }
+
+ /* (non-Javadoc)
+ * Method declared on FieldEditor.
+ */
+ protected void applyFont() {
+ if (chosenFont != null && previewer != null) {
+ previewer.setFont(chosenFont);
+ }
+ }
+
+ /* (non-Javadoc)
+ * Method declared on FieldEditor.
+ */
+ protected void doFillIntoGrid(Composite parent, int numColumns) {
+ getLabelControl(parent);
+
+ valueControl = getValueControl(parent);
+
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL
+ | GridData.GRAB_HORIZONTAL);
+ gd.horizontalSpan = numColumns - getNumberOfControls() + 1;
+ valueControl.setLayoutData(gd);
+ if (previewText != null) {
+ previewer = new DefaultPreviewer(previewText, parent);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.heightHint = previewer.getPreferredExtent();
+ gd.widthHint = previewer.getPreferredExtent();
+ previewer.getControl().setLayoutData(gd);
+ }
+
+ changeFontButton = getChangeControl();
+ gd = new GridData();
+ int widthHint = convertHorizontalDLUsToPixels(changeFontButton,
+ IDialogConstants.BUTTON_WIDTH);
+ gd.widthHint = Math.max(widthHint, changeFontButton.computeSize(
+ SWT.DEFAULT, SWT.DEFAULT, true).x);
+ changeFontButton.setLayoutData(gd);
+
+ }
+
+ @Override
+ protected void doSetToolTip() {
+ if (toolTipText != null) {
+ getValueControl(parent).setToolTipText(toolTipText);
+ }
+ }
+
+ /* (non-Javadoc)
+ * Method declared on FieldEditor.
+ */
+ protected void doLoad() {
+ if (changeFontButton == null) {
+ return;
+ }
+ updateFont(PreferenceConverter.basicGetFontData(preferencesService.getStringPreference(getPreferenceName())));
+ }
+
+ /* (non-Javadoc)
+ * Method declared on FieldEditor.
+ */
+ protected void doLoadDefault() {
+ if (changeFontButton == null) {
+ return;
+ }
+ String fontPref= preferencesService.getStringPreference(IPreferencesService.DEFAULT_LEVEL, getPreferenceName());
+ updateFont(PreferenceConverter.basicGetFontData(fontPref));
+ }
+
+ /* (non-Javadoc)
+ * Method declared on FieldEditor.
+ */
+ protected void doStore() {
+ if (chosenFont != null) {
+ fieldModified = false;
+ levelFromWhichLoaded = preferencesLevel;
+ setInherited(false);
+ String encodedFont= PreferenceConverter.getStoredRepresentation(chosenFont);
+ preferencesService.setStringPreference("instance", getPreferenceName(), encodedFont);
+ }
+ }
+
+ @Override
+ public Composite getHolder() {
+ return getChangeControl().getParent();
+ }
+
+ /**
+ * Returns the change button for this field editor.
+ *
+ * @param parent The Composite to create the button in if required.
+ * @return the change button
+ */
+ public Button getChangeControl() {
+ if (changeFontButton == null) {
+ changeFontButton = new Button(parent, SWT.PUSH);
+ if (changeButtonText != null) {
+ changeFontButton.setText(changeButtonText);
+ }
+ changeFontButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent event) {
+ FontDialog fontDialog = new FontDialog(changeFontButton
+ .getShell());
+ if (chosenFont != null) {
+ fontDialog.setFontList(chosenFont);
+ }
+ FontData font = fontDialog.open();
+ if (font != null) {
+ FontData[] oldFont = chosenFont;
+ if (oldFont == null) {
+ oldFont = JFaceResources.getDefaultFont().getFontData();
+ }
+ setPresentsDefaultValue(false);
+ FontData[] newData = new FontData[1];
+ newData[0] = font;
+ updateFont(newData);
+ fireValueChanged(VALUE, oldFont[0], font);
+ }
+ }
+ });
+ changeFontButton.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent event) {
+ changeFontButton = null;
+ }
+ });
+ changeFontButton.setFont(parent.getFont());
+ setButtonLayoutData(changeFontButton);
+ } else {
+ checkParent(changeFontButton, parent);
+ }
+ return changeFontButton;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on FieldEditor.
+ */
+ public int getNumberOfControls() {
+ if (previewer == null) {
+ return 3;
+ }
+
+ return 4;
+ }
+
+ /**
+ * Returns the preferred preview height.
+ *
+ * @return the height, or <code>-1</code> if no previewer
+ * is installed
+ */
+ public int getPreferredPreviewHeight() {
+ if (previewer == null) {
+ return -1;
+ }
+ return previewer.getPreferredExtent();
+ }
+
+ /**
+ * Returns the preview control for this field editor.
+ *
+ * @return the preview control
+ */
+ public Control getPreviewControl() {
+ if (previewer == null) {
+ return null;
+ }
+
+ return previewer.getControl();
+ }
+
+ /**
+ * Returns the value control for this field editor. The value control
+ * displays the currently selected font name.
+ * @param parent The Composite to create the viewer in if required
+ * @return the value control
+ */
+ protected Label getValueControl(Composite parent) {
+ if (valueControl == null) {
+ valueControl = new Label(parent, SWT.LEFT);
+ valueControl.setFont(parent.getFont());
+ valueControl.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent event) {
+ valueControl = null;
+ }
+ });
+ } else {
+ checkParent(valueControl, parent);
+ }
+ return valueControl;
+ }
+
+ /**
+ * Sets the text of the change button.
+ *
+ * @param text the new text
+ */
+ public void setChangeButtonText(String text) {
+ Assert.isNotNull(text);
+ changeButtonText = text;
+ if (changeFontButton != null) {
+ changeFontButton.setText(text);
+ }
+ }
+
+ /**
+ * Updates the change font button and the previewer to reflect the
+ * newly selected font.
+ * @param font The FontData[] to update with.
+ */
+ private void updateFont(FontData font[]) {
+ FontData[] bestFont = JFaceResources.getFontRegistry().filterData(
+ font, valueControl.getDisplay());
+
+ //if we have nothing valid do as best we can
+ if (bestFont == null) {
+ bestFont = getDefaultFontData();
+ }
+
+ //Now cache this value in the receiver
+ this.chosenFont = bestFont;
+
+ if (valueControl != null) {
+ valueControl.setText(StringConverter.asString(chosenFont[0]));
+ }
+ if (previewer != null) {
+ previewer.setFont(bestFont);
+ }
+ setInherited(false);
+ valueChanged();
+ }
+
+ /**
+ * Store the default preference for the field
+ * being edited
+ */
+ protected void setToDefault() {
+ String defaultFontStr= PreferenceConverter.getStoredRepresentation(getDefaultFontData());
+ preferencesService.setStringPreference(IPreferencesService.DEFAULT_LEVEL, getPreferenceName(), defaultFontStr);
+ }
+
+ /**
+ * Get the system default font data.
+ * @return FontData[]
+ */
+ private FontData[] getDefaultFontData() {
+ return valueControl.getDisplay().getSystemFont().getFontData();
+ }
+
+ public FontData[] getSelectedFont() {
+ return chosenFont;
+ }
+
+ /*
+ * @see FieldEditor.setEnabled(boolean,Composite).
+ */
+ public void setEnabled(boolean enabled, Composite parent) {
+ super.setEnabled(enabled, parent);
+ getChangeControl().setEnabled(enabled);
+ getValueControl(parent).setEnabled(enabled);
+ }
+
+ /*
+ * Note: The specialValue may be one that is used as a default or
+ * one that signifies no meaningful value selected. It is assumed
+ * here NOT to occur in entryNamesAndValues, and it is added to
+ * the head of the array of names and values used here to create
+ * the combo box entries.
+ */
+ public FontFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level,
+ String name, String labelText, Composite parent)
+ {
+ init(name, labelText);
+// Assert.isTrue(checkArray(entryNamesAndValues));
+
+ previewText = "splat splat" /*"Quick brown fox?\nOver the moon!"*/;
+ changeButtonText = JFaceResources.getString("openChange"); //$NON-NLS-1$
+
+ preferencesService = service;
+ preferencesLevel = level;
+ this.parent = parent;
+ prefPage = page;
+ setPage(prefPage);
+ prefTab = tab;
+
+ createControl(parent);
+ }
+
+
+ @Override
+ protected void doLoadLevel(String level) {
+ if (valueControl != null) {
+ String value = preferencesService.getStringPreference(level, getPreferenceName());
+ updateFont(PreferenceConverter.basicGetFontData(value));
+ }
+ }
+
+ @Override
+ protected String doLoadWithInheritance() {
+ String levelLoaded = null;
+ String[] levels = IPreferencesService.levels;
+
+ // If we're loading with inheritance for some field that is
+ // not attached to a preferences level then assume that we
+ // should just search from the bottom up
+ int startingLevelIdx = (preferencesLevel == null) ? 0 : PREFS_LEVELS_AS_LIST.indexOf(preferencesLevel);
+ int levelAtWhichFound = -1;
+
+ String encodedFontValue = null;
+ // Search up levels starting from the level of this field
+ for (int level = startingLevelIdx; level < levels.length; level++) {
+ encodedFontValue = preferencesService.getRawStringPreference(levels[level], getPreferenceName());
+ if (encodedFontValue != null) {
+ levelAtWhichFound = level;
+ levelLoaded = levels[levelAtWhichFound];
+ break;
+ }
+ }
+ if (encodedFontValue == null) {
+ encodedFontValue= DEFAULT_FONT_DESCRIPTOR;
+ }
+
+ // TODO should this be calling updateFont() instead of the following?
+ levelFromWhichLoaded = levelLoaded;
+ setInherited(startingLevelIdx != levelAtWhichFound);
+ setPresentsDefaultValue(IPreferencesService.DEFAULT_LEVEL.equals(levelFromWhichLoaded));
+ fieldModified = true;
+// valueChanged(); // should not be called when field set from preference store
+
+ previousValue = chosenFont; // not clear whether this needs to be done on initial load from store
+ chosenFont = PreferenceConverter.basicGetFontData(encodedFontValue);
+
+ if (valueControl != null) {
+ valueControl.setText(StringConverter.asString(chosenFont[0]));
+ }
+ if (previewer != null) {
+ previewer.setFont(chosenFont);
+ }
+ return levelLoaded;
+ }
+
+ @Override
+ protected boolean valueChanged() {
+ // copied from ComboFieldEditor
+ return valueChanged(false);
+ }
+
+ protected boolean valueChanged(boolean assertChanged)
+ {
+ // Check for change in value
+ boolean valueChanged = assertChanged || inheritanceChanged();
+ if (!valueChanged) {
+ if ((chosenFont != null && previousValue == null) ||
+ (chosenFont == null && previousValue != null))
+ {
+ valueChanged = true;
+ }
+
+ if (chosenFont != null && previousValue != null) {
+ if (!chosenFont.equals(previousValue)) {
+ valueChanged = true;
+ }
+ }
+ }
+
+ if (valueChanged) {
+ fireValueChanged(VALUE, previousValue, chosenFont);
+ fieldModified = true;
+ previousValue = chosenFont;
+ setModifiedMarkOnLabel();
+ }
+
+ return valueChanged;
+ }
+
+
+ /**
+ * Set the value of this field directly, from outside of
+ * the field, without loading a value from the preferences
+ * service.
+ *
+ * Intended for use by external clients of the field.
+ *
+ * In addition to setting the value of the field this method
+ * also sets several attributes to appropriately characterize
+ * a field that has been set in this way.
+ *
+ * @param newValue
+ */
+ public void setFieldValueFromOutside(FontData[] newValue) {
+ previousValue = chosenFont;
+ setInherited(false);
+ setPresentsDefaultValue(false);
+ levelFromWhichLoaded = null;
+ updateFont(newValue);
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/IEnumValueProvider.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/IEnumValueProvider.java
new file mode 100644
index 000000000..907aef5c6
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/IEnumValueProvider.java
@@ -0,0 +1,16 @@
+package org.eclipse.imp.preferences.fields;
+
+
+/**
+ * An interface for classes that provide a set of enum label/value pairs.
+ * Possible sources include a static set of label/value pairs,
+ * or a class that dynamically computes them at run-time.
+ * @author rfuhrer@watson.ibm.com
+ */
+public interface IEnumValueProvider {
+ String[] getLabels();
+
+ String[] getValues();
+
+ String getDefaultLabel();
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/IntegerFieldEditor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/IntegerFieldEditor.java
new file mode 100644
index 000000000..df33ae932
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/IntegerFieldEditor.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences.fields;
+
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesTab;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+
+public class IntegerFieldEditor extends StringFieldEditor {
+
+ // From IntegerFieldEditor
+ protected int minValidValue = 0;
+ protected int maxValidValue = Integer.MAX_VALUE;
+ protected static final int DEFAULT_TEXT_LIMIT = 10;
+
+ protected String errorMessage =
+ "Value must be an integer between " + minValidValue + " and " + maxValidValue;
+
+ /**
+ * Creates an integer field editor
+ * Use the method <code>setTextLimit</code> to limit the text.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param width the width of the text input field in characters,
+ * or <code>UNLIMITED</code> for no limit
+ * @param strategy either <code>VALIDATE_ON_KEY_STROKE</code> to perform
+ * on the fly checking (the default), or <code>VALIDATE_ON_FOCUS_LOST</code> to
+ * perform validation only after the text has been typed in
+ * @param parent the parent of the field editor's control
+ * @since 2.0
+ */
+ public IntegerFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level, String name, String labelText,
+ int width, int strategy, Composite parent)
+ {
+ super(page, tab, service, level, name, labelText, width, strategy, parent);
+ }
+
+
+ /**
+ * Creates a string field editor.
+ * Use the method <code>setTextLimit</code> to limit the text.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param width the width of the text input field in characters,
+ * or <code>UNLIMITED</code> for no limit
+ * @param parent the parent of the field editor's control
+ */
+ public IntegerFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level, String name, String labelText,
+ int width, Composite parent)
+ {
+ super(page, tab, service, level, name, labelText, width, org.eclipse.jface.preference.StringFieldEditor.VALIDATE_ON_KEY_STROKE, parent);
+ }
+
+
+ /**
+ * Creates a string field editor of unlimited width.
+ * Use the method <code>setTextLimit</code> to limit the text.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param parent the parent of the field editor's control
+ */
+ public IntegerFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level, String name, String labelText,
+ Composite parent)
+ {
+ // Replaced UNLIMITED text width in the following with default
+ super(page, tab, service, level, name, labelText, DEFAULT_TEXT_LIMIT, parent);
+ }
+
+
+ /**
+ * Copied from IntegerFieldEditor.
+ *
+ * Sets the range of valid values for this field.
+ *
+ * @param min the minimum allowed value (inclusive)
+ * @param max the maximum allowed value (inclusive)
+ */
+ public void setValidRange(int min, int max) {
+ minValidValue = min;
+ maxValidValue = max;
+ }
+
+
+
+ /**
+ * Copied from IntegerFieldEditor.
+ *
+ * Returns this field editor's current value as an integer.
+ *
+ * @return the value
+ * @exception NumberFormatException if the <code>String</code> does not
+ * contain a parsable integer
+ */
+ public int getIntValue() throws NumberFormatException {
+ return Integer.parseInt(getStringValue());
+ }
+
+
+ /* (non-Javadoc)
+ * Copied from IntegerFieldEditor (with minor adaptations).
+ * Method declared on StringFieldEditor.
+ * Checks whether the entered String is a valid integer or not.
+ */
+ protected boolean checkState() {
+
+ Text text = getTextControl(parent);
+
+ if (text == null)
+ return false;
+
+
+ String numberString = text.getText();
+ if (numberString==null || numberString.equals("")) numberString="0";
+ try {
+ int number = Integer.valueOf(numberString).intValue();
+ if (number >= minValidValue && number <= maxValidValue) {
+ clearErrorMessage();
+ return true;
+ } else {
+ setErrorMessage(getLevelName() + ": " + getLabelText() + " " + errorMessage);
+ return false;
+ }
+ } catch (NumberFormatException e1) {
+ setErrorMessage(getLevelName() + ": " + getLabelText() + " " + "Number format exception");
+ }
+
+ return false;
+ }
+
+
+ public String getLevelName() {
+ if (preferencesLevel.equals(IPreferencesService.DEFAULT_LEVEL)) return "Default";
+ if (preferencesLevel.equals(IPreferencesService.CONFIGURATION_LEVEL)) return "Configuration";
+ if (preferencesLevel.equals(IPreferencesService.INSTANCE_LEVEL)) return "Workspace";
+ if (preferencesLevel.equals(IPreferencesService.PROJECT_LEVEL)) return "Project";
+ return "";
+ }
+
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/PreferenceDialogConstants.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/PreferenceDialogConstants.java
new file mode 100644
index 000000000..8ad4583d6
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/PreferenceDialogConstants.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences.fields;
+
+import org.eclipse.imp.preferences.IPreferencesService;
+
+public class PreferenceDialogConstants {
+
+ // See also org.eclipse.jface.dialogs.IDialogConstants
+
+ // Additional button labels
+ public static final String BROWSE_LABEL = "Browse";
+ public static final String COPY_LABEL = "Copy In";
+ public static final String EMPTY_LABEL = "Set Empty";
+ public static final String REMOVE_LABEL = "Remove";
+ public static final String SPECIAL_LABEL = "Set Special";
+
+ // Statements indicating levels at which effective preferences may be reported
+ public static final String CONFIGURATION_LEVEL_STRING = "Details in effect at preferences level 'workspace configuration' ";
+ public static final String DEFAULT_LEVEL_STRING = "Details in effect at preferences level 'default' ";
+ public static final String INSTANCE_LEVEL_STRING = "Details in effect at preferences level 'workspace instance' ";
+ public static final String PROJECT_LEVEL_STRING = "Details in effect at preferences level 'project' ";
+ public static final String UNKNOWN_LEVEL_STRING = "Details in effect at preferences level ";
+
+ // Statements of preference attributes
+ public static final String EMPTY_OK = "\tEmpty value is allowed";
+ public static final String EMPTY_NOT_OK = "\tEmpty value is not allowed";
+ public static final String IS_REMOVABLE = "\tPreference is removable";
+ public static final String NOT_REMOVABLE = "\tPreference is not removable";
+ public static final String HAS_SPECIAL = "\tHas special value: ";
+ public static final String NO_SPECIAL = "\tHas no special value";
+
+
+ // Compute user-freindly string designations of preferences levels
+ // (may not correspond to internally used values)
+ public static String getLevelName(String level) {
+ if (level == null) {
+ return "unspecified";
+ } else if (level.equals(IPreferencesService.INSTANCE_LEVEL))
+ return "workspace instance";
+ else if (level.equals(IPreferencesService.CONFIGURATION_LEVEL))
+ return "workspace configuration";
+ else
+ return level;
+ }
+
+
+ private PreferenceDialogConstants() {};
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/RadioGroupFieldEditor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/RadioGroupFieldEditor.java
new file mode 100644
index 000000000..29a3e119c
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/RadioGroupFieldEditor.java
@@ -0,0 +1,755 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.preferences.fields;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesTab;
+import org.eclipse.imp.preferences.PreferencesUtilities;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.osgi.service.prefs.BackingStoreException;
+
+/**
+ * A field editor for an enumeration type preference.
+ * The choices are presented as a list of radio buttons.
+ */
+public class RadioGroupFieldEditor extends FieldEditor {
+ /**
+ * List of radio button entries of the form [label,value].
+ */
+ protected String[] values;
+
+ protected String[] labels;
+
+ /**
+ * Number of columns into which to arrange the radio buttons.
+ */
+ protected int numColumns;
+
+ /**
+ * Indent used for the first column of the radio button matrix.
+ */
+ protected int indent = HORIZONTAL_GAP;
+
+ /**
+ * The current value, or <code>null</code> if none.
+ */
+ protected String value;
+
+ /**
+ * The box of radio buttons, or <code>null</code> if none
+ * (before creation and after disposal).
+ */
+ protected Composite radioBox;
+
+ /**
+ * The radio buttons, or <code>null</code> if none
+ * (before creation and after disposal).
+ */
+ protected Button[] radioButtons;
+
+ /**
+ * Whether to use a Group control.
+ */
+ protected boolean useGroup;
+
+
+
+ /**
+ * Creates a new radio group field editor
+ */
+ protected RadioGroupFieldEditor() {
+ }
+
+ // Public constructors all adapted from RadioGroupFieldEditor.
+
+ /**
+ * Creates a radio group field editor.
+ * This constructor does not use a <code>Group</code> to contain the radio buttons.
+ * It is equivalent to using the following constructor with <code>false</code>
+ * for the <code>useGroup</code> argument.
+ * <p>
+ * Example usage:
+ * <pre>
+ * RadioGroupFieldEditor editor= new RadioGroupFieldEditor(
+ * "GeneralPage.DoubleClick", resName, 1,
+ * new String[][] {
+ * {"Open Browser", "open"},
+ * {"Expand Tree", "expand"}
+ * },
+ * parent);
+ * </pre>
+ * </p>
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param numColumns the number of columns for the radio button presentation
+ * @param labelAndValues list of radio button [label, value] entries;
+ * the value is returned when the radio button is selected
+ * @param parent the parent of the field editor's control
+ */
+ public RadioGroupFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level,
+ String name, String labelText, int numColumns,
+ String[] values, String[] labels, Composite parent,
+ boolean isEnabled, boolean isRemovable)
+ {
+ this(page, tab, service, level, name, labelText, numColumns, values, labels, parent, false);
+ }
+
+ /**
+ * Creates a radio group field editor.
+ * <p>
+ * Example usage:
+ * <pre>
+ * RadioGroupFieldEditor editor= new RadioGroupFieldEditor(
+ * "GeneralPage.DoubleClick", resName, 1,
+ * new String[][] {
+ * {"Open Browser", "open"},
+ * {"Expand Tree", "expand"}
+ * },
+ * parent,
+ * true);
+ * </pre>
+ * </p>
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param numColumns the number of columns for the radio button presentation
+ * @param labelAndValues list of radio button [label, value] entries;
+ * the value is returned when the radio button is selected
+ * @param parent the parent of the field editor's control
+ * @param useGroup whether to use a Group control to contain the radio buttons
+ */
+ public RadioGroupFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level,
+ String name, String labelText, int numColumns,
+ String[] values, String[] labels, Composite parent, boolean useGroup)
+ {
+ super(page, tab, service, level, name, labelText, parent);
+
+ // Adapted from RadioGroupFieldEditor
+ Assert.isTrue(values.length == labels.length);
+ this.values = values;
+ this.numColumns = numColumns;
+ this.useGroup = useGroup;
+ this.labels= labels;
+ createControl(parent);
+ }
+
+
+
+ /* (non-Javadoc)
+ * Method declared on FieldEditor.
+ */
+ protected void adjustForNumColumns(int numColumns) {
+ Control control = getLabelControl();
+ if (control != null) {
+ // should be true if !useGroup, and !useGroup should be true,
+ // so should not occur
+ ((GridData) control.getLayoutData()).horizontalSpan = numColumns;
+ }
+ ((GridData) radioBox.getLayoutData()).horizontalSpan = numColumns;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on FieldEditor.
+ */
+ protected void doFillIntoGrid(Composite parent, int numColumns) {
+ if (useGroup) {
+ Control control = getRadioBoxControl(parent);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ control.setLayoutData(gd);
+ } else {
+ Control control = getLabelControl(parent);
+ GridData gd = new GridData();
+ gd.horizontalSpan = numColumns;
+ control.setLayoutData(gd);
+ control = getRadioBoxControl(parent);
+ gd = new GridData();
+ gd.horizontalSpan = numColumns;
+ gd.horizontalIndent = indent;
+ control.setLayoutData(gd);
+ }
+ }
+
+ @Override
+ protected void doSetToolTip() {
+ if (toolTipText != null) {
+ getRadioBoxControl().setToolTipText(toolTipText);
+ }
+ }
+
+
+ /**
+ *
+ * Override of method from RadioGroupFieldEditor.
+ *
+ * Method declared on FieldEditor.
+ */
+ protected void doLoad() {
+ //updateValue(getPreferenceStore().getString(getPreferenceName()));
+
+ //if (getTextControl() != null) {
+ if (radioButtons != null) {
+ String value = null;
+ if (preferencesLevel != null) {
+ // The "normal" case, in which field corresponds to a preferences level
+ value = preferencesService.getStringPreference(preferencesLevel, getPreferenceName());
+ levelFromWhichLoaded = preferencesLevel;
+ setInherited(false);
+ } else {
+ // Not normal, exactly, but possible if loading is being done into a
+ // field that is not associated with a specific level
+ value = preferencesService.getStringPreference(getPreferenceName());
+ levelFromWhichLoaded = preferencesService.getApplicableLevel(getPreferenceName(), preferencesLevel);
+ setInherited(true);
+ }
+ if (IPreferencesService.DEFAULT_LEVEL.equals(levelFromWhichLoaded))
+ setPresentsDefaultValue(true);
+ setPreviousStringValue(value);
+ updateValue(value);
+ }
+ }
+
+
+ /**
+ * Method declared on FieldEditor.
+ *
+ * SMS 23 Dec 2006: This method is probably inapropriate and should probably
+ * be removed. The effect as programmed is to update the field without going
+ * through inheritance and without updating the model, and what that might mean
+ * hasn't been well defined. Also, there hasn't been a demonstrated need for
+ * this method.
+ */
+ protected void doLoadDefault() {
+ //updateValue(getPreferenceStore().getDefaultString(getPreferenceName()));
+
+ if (radioButtons != null) {
+ String value = preferencesService.getStringPreference(IPreferencesService.DEFAULT_LEVEL, getPreferenceName());
+ updateValue(value); // calls valueChanged()
+ }
+ }
+
+
+
+ /**
+ * Override of method from RadioGroupFieldEditor.
+ *
+ * SMS 23 Dec 2006: Should probably remove this method for reasons similar
+ * to those given for loadDefault
+ *
+ * Method declared on FieldEditor.
+ */
+ protected void doLoadLevel(String level) {
+ if (radioButtons != null) {
+ String value = null;
+ if (preferencesLevel != null) {
+ value = preferencesService.getStringPreference(level, getPreferenceName());
+ } else {
+ // TODO: Check whether this is right
+ value = preferencesService.getStringPreference(getPreferenceName());
+ }
+ updateValue(value); // calls valueChanged()
+ }
+ }
+
+
+
+ /**
+ * Load into the button field the value for this preference that is either
+ * the value defined on this preferences level, if any, or the value inherited
+ * from the next applicable level, if any. Return the level at which the
+ * value loaded was found. Load nothing and return null if no value is found.
+ */
+ protected String doLoadWithInheritance()
+ {
+ String levelLoaded = null;
+
+ String[] levels = IPreferencesService.levels;
+ int fieldLevelIndex = 0;
+
+ // If we're loading with inheritance for some field that is
+ // not attached to a preferences level then assume that we
+ // should just search from the bottom up
+ String tmpPreferencesLevel = (preferencesLevel == null) ? levels[0] : preferencesLevel;
+
+ // Find the index of the level to which this field belongs
+ for (int i = 0; i < levels.length; i++) {
+ if (tmpPreferencesLevel.equals(levels[i])) {
+ fieldLevelIndex = i;
+ break;
+ }
+ }
+
+ String value = null;
+ int levelAtWhichFound = -1;
+
+ // Search up levels starting from the level of this field
+ for (int level = fieldLevelIndex; level < levels.length; level++) {
+ value = preferencesService.getStringPreference(levels[level], getPreferenceName());
+ if (value == null) continue;
+ levelAtWhichFound = level;
+ levelLoaded = levels[levelAtWhichFound];
+ break;
+ }
+
+ // We loaded it at this level or inherited it from some other level
+ // (need to set before calling updateValue(..))
+ setInherited(fieldLevelIndex != levelAtWhichFound);
+
+ // Set the field to the value we found
+ updateValue(value);
+
+ // Since we just loaded some new value, it won't be modified yet
+ fieldModified = false;
+ setPreviousStringValue(value);
+
+ // Set the background color of the field according to where found
+ setFieldColors();
+
+ //System.out.println("doLoadWithInheritance: preferencesName = " + getPreferenceName() + "; preferenceLevel = " + preferencesLevel + "; levelLoaded = " + levelLoaded);
+ return levelLoaded;
+ }
+
+
+
+ protected void setFieldColors() {
+ Control buttonBox = getRadioBoxControl(parent);
+ Color color = isInherited() ? PreferencesUtilities.colorBluish : PreferencesUtilities.colorWhite;
+
+ buttonBox.setBackground(PreferencesUtilities.colorWhite);
+ if (radioButtons != null) {
+ for (int i = 0; i < radioButtons.length; i++) {
+ ((Button) radioButtons[i]).setBackground(color);
+ }
+ }
+ }
+
+
+
+ /**
+ * Overrides method implemented in RadioGroupFieldEditor.
+ *
+ * Abstract method declared on FieldEditor.
+ */
+ protected void doStore() {
+ String value = getStringValue();
+ boolean isEmpty = value.equals(""); // Want empty value, but can't call method to retrieve it
+ // with fields where empty is not allowed
+ // isEmpty shouldn't really occur with a radio group field,
+ // but address that case just in case
+ if (isEmpty) {
+ // We have an empty value where that isn't allowed, so clear the
+ // preference. Expect that clearing the preferences at a level will
+ // trigger a loading with inheritance at that level
+ preferencesService.clearPreferenceAtLevel(preferencesLevel, getPreferenceName());
+ // If the preference value was previously empty (e.g., if previously inherited)
+ // then clearing the preference node now doesn't cause a change event, so
+ // doesn't trigger reloading with inheritance. So we should just load the
+ // field again to make sure any inheritance occurs if needed
+ loadWithInheritance();
+ return;
+ }
+ if (isInherited() && !fieldModified) { // If inherited, why do we care whether it's modified?
+ // We have a value but it's inherited // shouldn't want to store in any case, should we?
+ // (left over from after the last time we cleared the field)
+ // so don't need (or want) to store it
+ return;
+ }
+ // We have a value (possibly empty, if that is allowed) that has changed
+ // from the previous value, so store it
+ preferencesService.setStringPreference(preferencesLevel, getPreferenceName(), value);
+
+ // If we've just stored the field, we've addressed any modifications
+ // and levelFromWhichLoaded is equivalent to levelOnWhichStored
+ // (which also means that the field isn't inherited)
+ fieldModified = false;
+ levelFromWhichLoaded = preferencesLevel;
+ setInherited(false);
+ setPresentsDefaultValue(
+ value.equals(preferencesService.getStringPreference(IPreferencesService.DEFAULT_LEVEL, getPreferenceName())));
+
+ // If we've stored the field then it's not inherited, so be sure it's
+ // color indicates that.
+ setFieldColors();
+
+ IEclipsePreferences node = preferencesService.getNodeForLevel(preferencesLevel);
+ try {
+ if (node != null) node.flush();
+ } catch (BackingStoreException e) {
+ System.err.println("RadioGroupFieldEditor.doStore(): BackingStoreException flushing node; node may not have been flushed:" +
+ "\n\tnode path = " + node.absolutePath() + ", preferences level = " + preferencesLevel);
+ }
+ }
+
+
+
+ /*
+ * For radio group fields we override the following two methods because
+ * the means of accessing the text to be modified is different.
+ *
+ * The representation of RadioGroups used here uses a Group to hold the buttons.
+ * The text associated with this group is used to label the field, so it is this
+ * text on which "modified" marks are set and cleared. The implementations of
+ * the methods that set and clear the marks assume the use of a group to hold
+ * the buttons. If groups are not used for this purpose, then the methods to
+ * set and clear the marks will need to be adapted accordingly.
+ *
+ * @see org.eclipse.imp.preferences.fields.FieldEditor#setModifiedMarkOnLabel()
+ * @see org.eclipse.imp.preferences.fields.FieldEditor#clearModifiedMarkOnLabel()
+ */
+
+
+ public void setModifiedMarkOnLabel() {
+ if (radioBox != null && useGroup) {
+ Group radioGroup = (Group) radioBox;
+
+ radioGroup.setForeground(PreferencesUtilities.colorRed);
+ }
+ }
+
+
+ public void clearModifiedMarkOnLabel() {
+ if (radioBox != null && useGroup) {
+ Group radioGroup = (Group) radioBox;
+
+ radioGroup.setForeground(PreferencesUtilities.colorBlack);
+ }
+ }
+
+
+
+ /**
+ * Returns this field editor's radio group control, using the
+ * locally cached reference to parent to obtain it.
+ *
+ * @return the radio group control
+ */
+ public Composite getRadioBoxControl()
+ {
+ Composite radioBox = getRadioBoxControl(parent);
+ return radioBox;
+ }
+
+ /**
+ * Returns this field editor's radio group control.
+ * @param parent The parent to create the radioBox in
+ * @return the radio group control
+ */
+ public Composite getRadioBoxControl(Composite parent) {
+ if (radioBox == null) {
+ Font font = parent.getFont();
+
+ if (useGroup) {
+ Group group = new Group(parent, SWT.NONE);
+ group.setFont(font);
+ String text = getLabelText();
+ // This puts the label in the border around the button group
+ // (but is not responsible for the field label outside the box)
+ if (text != null)
+ group.setText(text);
+ radioBox = group;
+ GridLayout layout = new GridLayout();
+ layout.horizontalSpacing = HORIZONTAL_GAP;
+ layout.numColumns = numColumns;
+ radioBox.setLayout(layout);
+ } else {
+ radioBox = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.horizontalSpacing = HORIZONTAL_GAP;
+ layout.numColumns = numColumns;
+ radioBox.setLayout(layout);
+ radioBox.setFont(font);
+ }
+
+ radioButtons = new Button[values.length];
+ for (int i = 0; i < values.length; i++) {
+ Button radio = new Button(radioBox, SWT.RADIO | SWT.LEFT);
+ radioButtons[i] = radio;
+ radio.setText(labels[i]);
+ radio.setData(values[i]);
+ radio.setFont(font);
+ radio.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent event) {
+// String oldValue = value;
+ value = (String) event.widget.getData();
+ setPresentsDefaultValue(false);
+ // SMS 12 Dec 2006
+ setInherited(false);
+// boolean valueChanged = valueChanged(true);
+ //fireValueChanged(VALUE, oldValue, value);
+ // Added:
+ //fieldModified = true;
+
+ }
+ });
+ }
+ radioBox.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent event) {
+ radioBox = null;
+ radioButtons = null;
+ }
+ });
+ } else {
+ checkParent(radioBox, parent);
+ }
+ return radioBox;
+ }
+
+ @Override
+ public Composite getHolder() {
+ return getRadioBoxControl().getParent();
+ }
+
+ /**
+ * Set the value of this field directly, from outside of
+ * the field, without loading a value from the preferences
+ * service.
+ *
+ * Intended for use by external clients of the field.
+ *
+ * In addition to setting the value of the field this method
+ * also sets several attributes to appropriately characterize
+ * a field that has been set in this way.
+ *
+ * @param newValue
+ */
+ public void setFieldValueFromOutside(String newValue) {
+ setPreviousStringValue(getStringValue());
+ setInherited(false);
+ setPresentsDefaultValue(false);
+ levelFromWhichLoaded = null;
+ updateValue(newValue);
+ }
+
+
+
+ /**
+ * Select the radio button that conforms to the given value.
+ *
+ * Note: This is (or should be) called whenever the value is
+ * updated through the API (including but not limited to the
+ * loading of the field from the preferences model). It provides
+ * a common place to address certain concerns for all of those
+ * cases (of which there are several). However, the field value
+ * can also be changed through the GUI, in which case these
+ * concerns may need to be addressed somewhere appropriate to
+ * that case. (The concerns include, for example, setting the
+ * modified mark on the field label and signaling that the
+ * value has changed.)
+ *
+ * Overrides the method from RadioGroupFieldEditor.
+ * @param selectedValue the selected value
+ */
+ protected void updateValue(String selectedValue)
+ {
+ value = selectedValue;
+ if (radioButtons == null)
+ return;
+
+ setPreviousStringValue(getStringValue());
+
+ // Check each button for a match to selectedValue
+ // and set its selection accordingly. Also note
+ // whether a button matching selectedValue was found.
+ boolean found = false;
+ if (value != null) {
+ for (int i = 0; i < radioButtons.length; i++) {
+ Button radio = radioButtons[i];
+ boolean selection = false;
+ if (((String) radio.getData()).equals(value)) {
+ selection = true;
+ found = true;
+ }
+ // Whether selection is true or false
+ radio.setSelection(selection);
+ }
+ }
+
+ // If we weren't able to find the value, select the first
+ // radio button as a default
+ if (!found && radioButtons.length > 0) {
+ radioButtons[0].setSelection(true);
+ value = (String) radioButtons[0].getData();
+ found = true; // in effect
+ }
+
+ // Should *always* have "found" some selection at this point
+ if (found) {
+ //fieldModified = true;
+ //setModifiedMarkOnLabel();
+ valueChanged();
+ }
+
+ return;
+ }
+
+
+ /**
+ * Informs this field editor's listener, if it has one, about a change
+ * to the value (<code>VALUE</code> property) provided that the old and
+ * new values are different. Not concerned with validity of values,
+ * here, on the assumption that if no valid value was entered then
+ * some valid value will be selected by default.
+ *
+ * This hook is <em>not</em> called when the text is initialized
+ * (or reset to the default value) from the preference store.
+ * (That comment is taken from the original implementation of this
+ * method. I've tried to follow it consistently for IMP preferences,
+ * but I'm not sure if the original intention translates into the
+ * multi-level model. Still, so far there seems to be no problem
+ * with it. SMS 16 Nov 2006)
+ *
+ * Copied from StringFieldEditor and adapted to use in IMP.
+ * Added return of a boolean value. Sets certain attributes of
+ * the field that do not depend on the context of the call. Does
+ * not set other attributes that do depend on the context (so those
+ * must be set separately).
+ */
+ protected boolean valueChanged() {
+ return valueChanged(false);
+ }
+
+ protected boolean valueChanged(boolean assumeChanged)
+ {
+ // Check for change in value
+ boolean valueChanged = assumeChanged || inheritanceChanged();
+ String newValue = getStringValue(); //getText();
+ if (!valueChanged) {
+ //String newValue = getStringValue(); //getText();
+ if (!newValue.equals(getPreviousStringValue())) {
+ valueChanged = true;
+ // Inform the listener
+ //fireValueChanged(VALUE, getPreviousStringValue(), newValue);
+ }
+ }
+
+ if (valueChanged) {
+ // Update the following attributes of the field,
+ // which can be done without regard to context
+ // Inform the listener
+ fireValueChanged(VALUE, getPreviousStringValue(), newValue);
+ fieldModified = true;
+ // SMS 23 Dec 2006: Don't do these here because they may
+ // (or should) have been done before valueChanged was called.
+ setPreviousStringValue(newValue);
+ setModifiedMarkOnLabel();
+ }
+ return valueChanged;
+ }
+
+
+
+ public Button[] getRadioButtons() {
+ return radioButtons;
+ }
+
+
+ protected String getPreviousStringValue() {
+ return (String) previousValue;
+ }
+
+
+ protected void setPreviousStringValue(String value) {
+ previousValue = value;
+ }
+
+
+
+ /**
+ * Gets the current String value of the field, corresponding
+ * to the currently pressed button.
+ *
+ * Note: This method, and the value of the current selection,
+ * are not available from RadioGroupFieldEditor.
+ *
+ * @return The current String value of the field, corresponding
+ * to the currently pressed button.
+ */
+ public String getStringValue() {
+ return value;
+ }
+
+
+
+
+ public String getSpecialStringValue() {
+ if (!hasSpecialValue) {
+ throw new IllegalStateException("RadioGroupFieldEditor.getSpecialValue(): field does not have a special value");
+ }
+ return (String) specialValue;
+ }
+
+
+
+ /**
+ * Set the special value associated with this field to be the given string.
+ * Overrides the method in the supertype to check that the given value is
+ * a String.
+ *
+ * @param specialValue The special value to associate with this field
+ * @ throws IllegalStateException if the field has no special value
+ * @throws IllegalArgumentException if the given value is null or empty
+ */
+ public void setSpecialValue(String specialValue) {
+ if (!hasSpecialValue()) {
+ throw new IllegalStateException("RadioGroupFieldEditor.setSpecialValue(String): field has no special value");
+ } else if (specialValue == null || specialValue == "") {
+ throw new IllegalArgumentException("RadioGroupFieldEditor.setSpecialValue(String): special value cannot be null or empty");
+ }
+ this.specialValue = specialValue;
+ }
+
+
+
+
+
+ /*
+ * Method declared on FieldEditor.
+ * Copied from RadioGroupFieldEditor.
+ */
+ public int getNumberOfControls() {
+ return 1;
+ }
+
+
+ /*
+ * @see FieldEditor.setEnabled(boolean,Composite).
+ */
+ public void setEnabled(boolean enabled, Composite parent) {
+ if (!useGroup)
+ super.setEnabled(enabled, parent);
+ for (int i = 0; i < radioButtons.length; i++) {
+ radioButtons[i].setEnabled(enabled);
+ }
+
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/StaticEnumValueProvider.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/StaticEnumValueProvider.java
new file mode 100644
index 000000000..978fe5bb7
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/StaticEnumValueProvider.java
@@ -0,0 +1,69 @@
+/**
+ *
+ */
+package org.eclipse.imp.preferences.fields;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Implementation of {@link IEnumValueProvider} that uses static sets of labels and values.
+ * Currently unused (the code generator creates entirely different code for the static case).
+ * @author rfuhrer@watson.ibm.com
+ */
+public class StaticEnumValueProvider implements IEnumValueProvider {
+ /**
+ * The default label associated with this field
+ * (used to set the value of the concrete instance of
+ * this field on the default level)
+ */
+ private final String fDefaultLabel;
+
+ /**
+ * The list of labels
+ */
+ private final List<String> fLabelList= new ArrayList<String>();
+
+ /**
+ * A list of values. If non-null and non-empty, indices correspond
+ * to those in the field <code>labelList</code>.
+ */
+ private final List<String> fValueList= new ArrayList<String>();
+
+ public StaticEnumValueProvider(List<String> keys, List<String> values, String defaultKey) {
+ fLabelList.addAll(keys);
+ fValueList.addAll(values);
+ fDefaultLabel= defaultKey;
+ }
+
+ public String[] getLabels() {
+ return fLabelList.toArray(new String[fLabelList.size()]);
+ }
+
+ public String[] getValues() {
+ return fValueList.toArray(new String[fValueList.size()]);
+ }
+
+ public String getDefaultLabel() {
+ return fDefaultLabel;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb= new StringBuilder();
+ for(int i=0; i < fLabelList.size(); i++) {
+ sb.append("slot[");
+ sb.append(i);
+ sb.append("] = ");
+ sb.append(fLabelList.get(i));
+ if (fValueList != null && fValueList.size() > 0) {
+ sb.append(": ");
+ sb.append(fValueList.get(i));
+ }
+ sb.append("\n");
+ }
+ sb.append("defaultLabel = ");
+ sb.append(fDefaultLabel);
+ return sb.toString();
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/StringButtonFieldEditor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/StringButtonFieldEditor.java
new file mode 100644
index 000000000..f04a5606b
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/StringButtonFieldEditor.java
@@ -0,0 +1,249 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences.fields;
+
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesTab;
+import org.eclipse.imp.preferences.PreferencesUtilities;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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.Shell;
+import org.eclipse.swt.widgets.Text;
+
+public abstract class StringButtonFieldEditor extends StringFieldEditor {
+
+ public StringButtonFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level, String name, String labelText,
+ int width, int strategy, Composite parent)
+ {
+ super(page, tab, service, level, name, labelText, width, strategy, parent);
+ }
+
+
+ /**
+ * Creates a IMP string button field editor.
+ * Use the method <code>setTextLimit</code> to limit the text.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param width the width of the text input field in characters,
+ * or <code>UNLIMITED</code> for no limit
+ * @param parent the parent of the field editor's control
+ */
+ public StringButtonFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level, String name, String labelText,
+ int width, Composite parent)
+ {
+ super(page, tab, service, level, name, labelText, width, org.eclipse.jface.preference.StringFieldEditor.VALIDATE_ON_KEY_STROKE, parent);
+ }
+
+
+ /**
+ * Creates a IMP string button field editor.
+ * Use the method <code>setTextLimit</code> to limit the text.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param parent the parent of the field editor's control
+ */
+ public StringButtonFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level, String name, String labelText, Composite parent)
+ {
+ super(page, tab, service, level, name, labelText, parent);
+ }
+
+
+
+
+ /**
+ * Informs this field editor's listener, if it has one, about a change
+ * to the value (<code>VALUE</code> property) provided that the old and
+ * new values are different.
+ * <p>
+ * This hook is <em>not</em> called when the text is initialized
+ * (or reset to the default value) from the preference store.
+ * </p>
+ * This extension sets converts any inherited field to a local one.
+ * This is done because we don't want to allow inehrited fields to
+ * be edited as such. This extension also maintains the local copy
+ * of the previous value.
+ */
+ protected boolean valueChanged() {
+
+ return super.valueChanged();
+ }
+
+
+
+ /*
+ * Following is all copied from org.eclipse.jface.StringButtonFieldEditor
+ */
+
+
+ /**
+ * The change button, or <code>null</code> if none
+ * (before creation and after disposal).
+ */
+ private Button changeButton;
+
+ /**
+ * The text for the change button, or <code>null</code> if missing.
+ */
+ private String changeButtonText;
+
+
+ /* (non-Javadoc)
+ * Method declared on FieldEditor.
+ */
+ protected void adjustForNumColumns(int numColumns) {
+ ((GridData) getTextControl(parent).getLayoutData()).horizontalSpan = numColumns - 2;
+ }
+
+ /**
+ * Notifies that this field editor's change button has been pressed.
+ * <p>
+ * Subclasses must implement this method to provide a corresponding
+ * new string for the text field. If the returned value is <code>null</code>,
+ * the currently displayed value remains.
+ * </p>
+ *
+ * @return the new string to display, or <code>null</code> to leave the
+ * old string showing
+ */
+ protected abstract String changePressed();
+
+ /* (non-Javadoc)
+ * Method declared on StringFieldEditor (and FieldEditor).
+ */
+ protected void doFillIntoGrid(Composite parent, int numColumns) {
+ super.doFillIntoGrid(parent, numColumns - 1);
+ changeButton = getChangeControl(parent);
+ GridData gd = new GridData();
+ gd.horizontalAlignment = GridData.FILL;
+ int widthHint = convertHorizontalDLUsToPixels(changeButton,
+ IDialogConstants.BUTTON_WIDTH);
+ gd.widthHint = Math.max(widthHint, changeButton.computeSize(
+ SWT.DEFAULT, SWT.DEFAULT, true).x);
+ changeButton.setLayoutData(gd);
+ }
+
+ /**
+ * Get the change control. Create it in parent if required.
+ * @param parent
+ * @return Button
+ */
+ public Button getChangeControl(Composite parent) {
+ if (changeButton == null) {
+ // Set enabled according to the associated text
+ // field, if defined
+ boolean enabled = false;
+ Control[] children = parent.getChildren();
+ for (int i = 0; i < children.length; i++) {
+ if (children[i] instanceof Text) {
+ enabled = children[i].isEnabled();
+ }
+ }
+
+ changeButton = new Button(parent, SWT.PUSH);
+ if (changeButtonText == null)
+ changeButtonText = JFaceResources.getString("openChange"); //$NON-NLS-1$
+ changeButton.setText(changeButtonText);
+ changeButton.setFont(parent.getFont());
+ changeButton.setEnabled(enabled); // added
+ changeButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ String newValue = changePressed();
+ if (newValue != null) {
+ // SMS 28 Nov 2006
+ // Added setting of fields where setStringValue(..) is called
+ // and (below) setting of background color
+ levelFromWhichLoaded = preferencesLevel;
+ setInherited(false);
+ setPresentsDefaultValue(false);
+
+ setStringValue(newValue);
+
+ Text text = getTextControl();
+ text.setBackground(PreferencesUtilities.colorWhite);
+ }
+ }
+ });
+ changeButton.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent event) {
+ changeButton = null;
+ }
+ });
+ } else {
+ checkParent(changeButton, parent);
+ }
+ return changeButton;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on FieldEditor.
+ */
+ public int getNumberOfControls() {
+ return 3;
+ }
+
+ /**
+ * Returns this field editor's shell.
+ *
+ * @return the shell
+ */
+ protected Shell getShell() {
+ if (changeButton == null)
+ return null;
+ return changeButton.getShell();
+ }
+
+ /**
+ * Sets the text of the change button.
+ *
+ * @param text the new text
+ */
+ public void setChangeButtonText(String text) {
+ Assert.isNotNull(text);
+ changeButtonText = text;
+ if (changeButton != null)
+ changeButton.setText(text);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.preference.FieldEditor#setEnabled(boolean, org.eclipse.swt.widgets.Composite)
+ */
+ public void setEnabled(boolean enabled, Composite parent) {
+ super.setEnabled(enabled, parent);
+ if (changeButton != null) {
+ changeButton.setEnabled(enabled);
+ }
+ }
+
+
+
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/StringFieldEditor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/StringFieldEditor.java
new file mode 100644
index 000000000..8375c7e3d
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/StringFieldEditor.java
@@ -0,0 +1,881 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences.fields;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesTab;
+import org.eclipse.imp.preferences.PreferencesUtilities;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.FocusAdapter;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+import org.osgi.service.prefs.BackingStoreException;
+
+/**
+ * @author sutton
+ */
+public class StringFieldEditor extends FieldEditor
+{
+ public interface Validator {
+ /**
+ * @param value
+ * @return a non-null error message if the value fails validation
+ */
+ String validate(String value);
+ }
+
+ /**
+ * Cached valid state.
+ */
+ private boolean isValid;
+
+ /**
+ * Old text value.
+ */
+ //private String oldValue;
+ protected String previousValue;
+
+ /**
+ * The text field, or <code>null</code> if none.
+ */
+ protected Text textField;
+
+ /**
+ * Width of text field in characters; initially unlimited.
+ */
+ protected int widthInChars = org.eclipse.jface.preference.StringFieldEditor.UNLIMITED;
+
+ /**
+ * Text limit of text field in characters; initially unlimited.
+ */
+ protected int textLimit = org.eclipse.jface.preference.StringFieldEditor.UNLIMITED;
+
+ /**
+ * The error message, or <code>null</code> if none.
+ */
+ protected String errorMessage;
+
+ /**
+ * Indicates whether the empty string is legal;
+ * <code>true</code> by default.
+ */
+ protected boolean emptyStringAllowed = true;
+
+ /**
+ * The empty string (in case you needed it)
+ */
+ protected final String emptyValue = "";
+
+ /**
+ * The validation strategy;
+ * <code>VALIDATE_ON_KEY_STROKE</code> by default.
+ */
+ protected int validateStrategy = org.eclipse.jface.preference.StringFieldEditor.VALIDATE_ON_KEY_STROKE;
+
+
+ protected Validator validator;
+
+
+ /**
+ * Creates a string field editor.
+ * Use the method <code>setTextLimit</code> to limit the text.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param width the width of the text input field in characters,
+ * or <code>UNLIMITED</code> for no limit
+ * @param strategy either <code>VALIDATE_ON_KEY_STROKE</code> to perform
+ * on the fly checking (the default), or <code>VALIDATE_ON_FOCUS_LOST</code> to
+ * perform validation only after the text has been typed in
+ * @param parent the parent of the field editor's control
+ * @since 2.0
+ */
+ public StringFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level, String name, String labelText,
+ int width, int strategy, Composite parent)
+ {
+ super(page, tab, service, level, name, labelText, parent);
+
+ // Relating to StrinfFieldEditor things
+ init(name, labelText);
+ widthInChars = width;
+ setValidateStrategy(strategy);
+ isValid = false;
+ // Why set this in a local field rather than in the page?
+ errorMessage = JFaceResources
+ .getString("StringFieldEditor.errorMessage");//$NON-NLS-1$
+ createControl(parent);
+ }
+
+
+ /**
+ * Creates a string field editor.
+ * Use the method <code>setTextLimit</code> to limit the text.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param width the width of the text input field in characters,
+ * or <code>UNLIMITED</code> for no limit
+ * @param parent the parent of the field editor's control
+ */
+ public StringFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level,
+ String name, String labelText, int width, Composite parent)
+ {
+ this(page, tab, service, level,
+ name, labelText,
+ (width == org.eclipse.jface.preference.StringFieldEditor.UNLIMITED ? 40 : width),
+ org.eclipse.jface.preference.StringFieldEditor.VALIDATE_ON_KEY_STROKE, parent);
+ }
+
+ /**
+ * Creates a string field editor of unlimited width.
+ * Use the method <code>setTextLimit</code> to limit the text.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param parent the parent of the field editor's control
+ */
+ public StringFieldEditor(
+ PreferencePage page, PreferencesTab tab,
+ IPreferencesService service, String level,
+ String name, String labelText, Composite parent)
+ {
+ this(page, tab, service, level, name, labelText, 40, parent);
+ }
+
+
+ @Override
+ public Composite getHolder() {
+ return getTextControl().getParent();
+ }
+
+ /**
+ * Sets the strategy for validating the text.
+ * <p>
+ * Calling this method has no effect after <code>createPartControl</code>
+ * is called. Thus this method is really only useful for subclasses to call
+ * in their constructor. However, it has public visibility for backward
+ * compatibility.
+ * </p>
+ *
+ * @param value either <code>VALIDATE_ON_KEY_STROKE</code> to perform
+ * on the fly checking (the default), or <code>VALIDATE_ON_FOCUS_LOST</code> to
+ * perform validation only after the text has been typed in
+ *
+ * Copied from StringFieldEditor and adapted to this location.
+ */
+ public void setValidateStrategy(int value) {
+ Assert.isTrue(value == org.eclipse.jface.preference.StringFieldEditor.VALIDATE_ON_FOCUS_LOST
+ || value == org.eclipse.jface.preference.StringFieldEditor.VALIDATE_ON_KEY_STROKE);
+ validateStrategy = value;
+ }
+
+ public void setValidator(Validator validator) {
+ this.validator = validator;
+ }
+
+ /*
+ * Methods related to a special value for this field, treated
+ * as a string (as you would expect)
+ */
+
+ /**
+ * @return The special value associated with this field, if there
+ * is such a value and it is a string
+ * @throws IllegalStateException
+ * If the field does not have a special value or
+ * if the special value is not a string
+ */
+ public String getSpecialStringValue() {
+ if (!hasSpecialValue) {
+ throw new IllegalStateException("StringField.getSpecialValue(): field does not have a special value");
+ } else if (!(specialValue instanceof String)) {
+ throw new IllegalStateException("StringField.getSpecialValue(): special value is not a String");
+ } else {
+ return (String) specialValue;
+ }
+ }
+
+
+ /**
+ * Set the special value associated with this field to be the given string.
+ * Overrides the method in the supertype to check that the given value is
+ * a String.
+ *
+ * @param specialValue The special value to associate with this field
+ * @throws IllegalStateException
+ * If the given value is not a String
+ */
+ public void setSpecialValue(String specialValue) {
+ if (!(specialValue instanceof String)) {
+ throw new IllegalStateException("StringField.setSpecialValue(): given value is not a String");
+ }
+ hasSpecialValue = true;
+ this.specialValue = specialValue;
+ }
+
+
+ /*
+ * Methods related to whether the empty string is allowed
+ * for this field.
+ *
+ * These methods mimic coresponding instance methods defined
+ * on the superclass.
+ */
+
+
+ /**
+ * @return Whether the empty string is allowed as a value
+ * for this field.
+ */
+ public boolean isEmptyValueAllowed() {
+ return emptyStringAllowed;
+ }
+
+ /**
+ * Sets whether the empty string is allowed as a value
+ * for this field.
+ *
+ * @param allowed Whether ...
+ */
+ public void setEmptyValueAllowed(boolean allowed) {
+ emptyStringAllowed = allowed;
+ }
+
+
+
+ /**
+ * @return The empty value for fields of this type,
+ * i.e., the empty string, regardless of whether
+ * that value is allowed for a particular field
+ */
+ public String getEmptyValue() {
+ return emptyValue;
+ }
+
+
+
+
+ /* (non-Javadoc)
+ * Method declared on FieldEditor.
+ */
+ public boolean isValid() {
+ return isValid;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on FieldEditor.
+ */
+ protected void refreshValidState() {
+ isValid = checkState();
+ }
+
+
+ /*
+ * Methods related to loading values from the preferences service
+ * into the preferences store.
+ *
+ * All of the "doLoad..." methods should
+ * - Set isInherited, presentsDefaultValue, and levelFromWhichLoaded
+ * since these are know directly here and vary from load method to
+ * load method
+ * - Call setStringValue(..), which will set previousValue and
+ * fieldModified (which can be set generally given the old and
+ * new values), and which will also call valueChanged(), which
+ */
+
+
+
+ /**
+ * Load the string value for this field. Load it according to
+ * the preference level associated with this field, if there is one,
+ * or load it according to an applicable level, if not.
+ */
+ protected void doLoad()
+ {
+ if (getTextControl(parent) != null) {
+ String value = null;
+ if (preferencesLevel != null) {
+ // The "normal" case, in which field corresponds to a preferences level
+ value = preferencesService.getRawStringPreference(preferencesLevel, getPreferenceName());
+ levelFromWhichLoaded = preferencesLevel;
+ setInherited(false);
+ }
+ else {
+ // Not normal, exactly, but possible if loading is being done into a
+ // field that is not associated with a specific level
+ value = preferencesService.getRawStringPreference(getPreferenceName());
+ levelFromWhichLoaded = preferencesService.getApplicableLevel(getPreferenceName(), preferencesLevel);
+ setInherited(!levelFromWhichLoaded.equals(preferencesLevel));
+ }
+ setPresentsDefaultValue(IPreferencesService.DEFAULT_LEVEL.equals(levelFromWhichLoaded));
+ setStringValue(value);
+ }
+ }
+
+
+ /**
+ * Load the default value associated with this field. That is, load
+ * the value set at the default level for this field, regardless of
+ * the actual level of this field.
+ */
+ protected void doLoadDefault() {
+ if (getTextControl(parent) != null) {
+ String value = preferencesService.getRawStringPreference(IPreferencesService.DEFAULT_LEVEL, getPreferenceName());
+ levelFromWhichLoaded = IPreferencesService.DEFAULT_LEVEL;
+ setInherited(false); // We're putting the default value here directly, not inheriting it
+ setPresentsDefaultValue(true); // Need this really?
+ setStringValue(value); // calls valueChanged();
+
+ // SMS 28 Nov 2006 added here
+ // Value is default but is not inherited
+ Text text = getTextControl(parent);
+ text.setBackground(PreferencesUtilities.colorWhite);
+ }
+ }
+
+
+
+ /**
+ * Do the work of loading the value for the given level into the field.
+ */
+ protected void doLoadLevel(String level) {
+ if (getTextControl(parent) != null) {
+ String value = null;
+ if (preferencesLevel != null) {
+ value = preferencesService.getRawStringPreference(level, getPreferenceName());
+ } else {
+ // TODO: Check whether this is right
+ value = preferencesService.getRawStringPreference(getPreferenceName());
+ }
+ // We're putting the level's value here directly, not inheriting it, so ...
+ levelFromWhichLoaded = level;
+ setInherited(false);
+ setPresentsDefaultValue(IPreferencesService.DEFAULT_LEVEL.equals(level));
+ setStringValue(value); // calls valueChanged();
+ }
+ }
+
+
+
+ /**
+ * Do the work of setting the currently applicable value for this field,
+ * inheriting the value from a higher level if the value is not stored
+ * on the level associated with the field. (The "default" level should
+ * always have a value.) Load nothing and return null if no value is found.
+ *
+ * Should set varous fields such as levelFromWhichLoaded, previousValue,
+ * isInherited, and fieldModified. Should also adjust the appearance of
+ * the field on the preferences page to reflect inherited state.
+ *
+ * @return The level from which the applicable value was loaded or
+ * null if no value found.
+ */
+ protected String doLoadWithInheritance()
+ {
+ String levelLoaded = null;
+
+ String[] levels = IPreferencesService.levels;
+ int fieldLevelIndex = 0;
+
+ // If we're loading with inheritance for some field that is
+ // not attached to a preferences level (such as the "applicable"
+ // field, which inherits values from all of the real fields)
+ // then assume that we should search from the bottom up
+ String tmpPreferencesLevel =
+ (preferencesLevel == null)?
+ levels[0]:
+ preferencesLevel;
+
+ // Find the index of the level to which this field belongs
+ for (int i = 0; i < levels.length; i++) {
+ if (tmpPreferencesLevel.equals(levels[i])) {
+ fieldLevelIndex = i;
+ break;
+ }
+ }
+
+ String value = null;
+ int levelAtWhichFound = -1;
+
+ for (int level = fieldLevelIndex; level < levels.length; level++) {
+ value = preferencesService.getRawStringPreference(levels[level], getPreferenceName());
+ if (value == null) continue;
+ if (value.equals("") && !isEmptyValueAllowed()) continue;
+ levelAtWhichFound = level;
+ levelLoaded = levels[levelAtWhichFound];
+ break;
+ }
+
+ levelFromWhichLoaded = levelLoaded;
+ setInherited(fieldLevelIndex != levelAtWhichFound);
+ setPresentsDefaultValue(IPreferencesService.DEFAULT_LEVEL.equals(levelFromWhichLoaded));
+ setStringValue(value); // sets fieldModified and previousValue
+
+ // Set the background color of the field according to where found
+ Text text = getTextControl(parent);
+ if (isInherited())
+ text.setBackground(PreferencesUtilities.colorBluish);
+ else
+ text.setBackground(PreferencesUtilities.colorWhite);
+
+ return levelLoaded;
+ }
+
+
+
+ /*
+ * Method related to storing String values for this field
+ */
+
+ protected void doStore() {
+ String value = getTextControl(parent).getText();
+ boolean isEmpty = value.equals(emptyValue);
+ // getText() will return an empty string if the field is empty,
+ // and empty strings can be stored in the preferences service,
+ // but an empty string is recognized by the preferences service
+ // as a valid value--when usually it is not. Once it is recognized
+ // as a valid value, it precludes the searching of subsequent
+ // levels that might contain a non-empty (and actually valid) value.
+ // We would like to be able to store a null value with the preferences
+ // service so as to not short-circuit the search process, but we can't
+ // do that. So, if the field value is empty, we have to eliminate the
+ // preference entirely. (Will that work in general???)
+ if (isEmpty && !isEmptyValueAllowed()) {
+ // We have an empty value where that isn't allowed, so clear the
+ // preference. Expect that clearing the preferences at a level will
+ // trigger a loading with inheritance at that level
+ preferencesService.clearPreferenceAtLevel(preferencesLevel, getPreferenceName());
+ // If the preference value was previously empty (e.g., if previously inherited)
+ // then clearing the preference node now doesn't cause a change event, so
+ // doesn't trigger reloading with inheritance. So we should just load the
+ // field again to make sure any inheritance occurs if needed
+ loadWithInheritance();
+ return;
+ }
+
+ // We have a value (possibly empty, if that is allowed) that has changed
+ // from the previous value, so store it
+ preferencesService.setStringPreference(preferencesLevel, getPreferenceName(), value);
+
+ fieldModified = false;
+ levelFromWhichLoaded = preferencesLevel;
+ isInherited = false;
+ setPresentsDefaultValue(
+ value.equals(preferencesService.getRawStringPreference(IPreferencesService.DEFAULT_LEVEL, getPreferenceName())));
+
+
+ // If we've stored the field then it's not inherited, so be sure it's
+ // color indicates that.
+ // For text fields, the background color is the backgroud color within
+ // the field, so don't have to worry about matching anything else
+ getTextControl(parent).setBackground(PreferencesUtilities.colorWhite);
+
+ IEclipsePreferences node = preferencesService.getNodeForLevel(preferencesLevel);
+ try {
+ if (node != null) node.flush();
+ } catch (BackingStoreException e) {
+ System.err.println("StringFieldEditor.doStore(): BackingStoreException flushing node; node may not have been flushed:" +
+ "\n\tnode path = " + node.absolutePath() + ", preferences level = " + preferencesLevel);
+ }
+ }
+
+
+ /*
+ * Methods related to getting and setting the String value for this field
+ */
+
+
+ /**
+ * @return the previous value held by this field
+ */
+ protected String getPreviousStringValue() {
+ return (String) previousValue;
+ }
+
+
+ /**
+ * Sets the previous value held by this field
+ */
+ protected void setPreviousStringValue(String value) {
+ previousValue = value;
+ }
+
+
+ /**
+ * Set the value of this field directly, from outside of
+ * the field, without loading a value from the preferences
+ * service.
+ *
+ * Intended for use by external clients of the field.
+ *
+ * In addition to setting the value of the field this method
+ * also sets several attributes to appropriately characterize
+ * a field that has been set in this way.
+ *
+ * @param newValue
+ */
+ public void setFieldValueFromOutside(String newValue) {
+ setPreviousStringValue(getStringValue());
+ setInherited(false);
+ setPresentsDefaultValue(false);
+ levelFromWhichLoaded = null;
+ setStringValue(newValue);
+ }
+
+
+
+ /**
+ * Returns the field editor's current value.
+ *
+ * @return the current value
+ */
+ public String getStringValue() {
+ String value = getTextControl(parent).getText();
+ return value;
+ }
+
+
+ /**
+ * Set this field editor's value.
+ * Likewise set previousValue and fieldModified flags,
+ * and call valueChanged() to signal that the value has
+ * changed.
+ *
+ *
+ * @param value the new value, or <code>null</code> meaning the empty string
+ */
+ protected void setStringValue(String value) {
+ if (getTextControl(parent) != null) {
+ if (value == null)
+ value = "";//$NON-NLS-1$
+ setPreviousStringValue(getTextControl(parent).getText());
+ getTextControl(parent).setText(value);
+ // Set fieldModified here because we know we just set it
+ // and we consider it modified even if the old and new
+ // values are the same
+ fieldModified = true;
+ // Set on this level, and so not inherited
+ // SMS 17 Nov 2006: level and inherited should be set in doLoad methods
+ // Or wherever else setStringValue is called from (e.g., listeners)
+ //levelFromWhichLoaded = preferencesLevel;
+ //isInherited = levelFromWhichLoaded == preferencesLevel;
+ valueChanged();
+ // valueChanged() takes care of setting the previous value
+ // and presents default value
+ // }
+// setPresentsDefaultValue(
+// value.equals(preferencesService.getStringPreference(IPreferencesService.DEFAULT_LEVEL, getPreferenceName())));
+ }
+ }
+
+
+
+
+
+ /**
+ * Informs this field editor's listener, if it has one, about a change
+ * to the value (<code>VALUE</code> property) provided that the old and
+ * new values are different. Also informs the listener (if there is one)
+ * of a change in the validity of the field (<code>IS_VALID</code> property).
+ *
+ * This hook is <em>not</em> called when the text is initialized
+ * (or reset to the default value) from the preference store.
+ * (That comment is taken from the original implementation of this
+ * method. I've tried to follow it consistently for IMP preferences,
+ * but I'm not sure if the original intention translates into the
+ * multi-level model. Still, so far there seems to be no problem
+ * with it. SMS 16 Nov 2006)
+ *
+ * Copied from StringFieldEditor and adapted to use in IMP.
+ * Added return of a boolean value. Not intended to set any attributes
+ * of the field editor, just to signal changes to listeners.
+ */
+ protected boolean valueChanged() {
+ return valueChanged(false);
+ }
+
+ protected boolean valueChanged(boolean assertChanged)
+ {
+ // Check for change in value
+ boolean valueChanged = assertChanged || inheritanceChanged();
+ String newValue = textField.getText();
+ if (!valueChanged) {
+ valueChanged = newValue.equals(getPreviousStringValue());
+ }
+
+ if (valueChanged) {
+ // Check for change in validity
+ fireValueChanged(VALUE, getPreviousStringValue(), newValue);
+ boolean wasValid = isValid;
+ refreshValidState();
+ if (isValid != wasValid)
+ fireStateChanged(IS_VALID, wasValid, isValid);
+
+ fieldModified = true;
+ setPreviousStringValue(newValue);
+ setModifiedMarkOnLabel();
+ // SMS 28 Nov 2006 added here
+ // Set the background color of the field according to where found
+ Text text = getTextControl(parent);
+ if (isInherited())
+ text.setBackground(PreferencesUtilities.colorBluish);
+ else
+ text.setBackground(PreferencesUtilities.colorWhite);
+ }
+
+ return valueChanged;
+ }
+
+
+
+
+ /**
+ * Checks whether the text input field contains a valid value or not.
+ *
+ * @return <code>true</code> if the field value is valid,
+ * and <code>false</code> if invalid
+ */
+ protected boolean checkState()
+ {
+ boolean result = true;
+
+ if (!emptyStringAllowed && getStringValue().length() == 0) {
+ setErrorMessage(getFieldMessagePrefix() + "String is empty when empty string is not allowed");
+ result = false;
+ }
+
+ if (result && getTextControl(parent) == null) {
+ setErrorMessage(getFieldMessagePrefix() + "Text control is null; no valid value represented");
+ result = false;
+ }
+
+ if (result && getTextControl(parent) != null) {
+ String txt = getStringValue();
+ result = (txt.trim().length() > 0) || emptyStringAllowed;
+ if (!result) {
+ setErrorMessage(getFieldMessagePrefix() + "String is blank when empty string is not allowed");
+ }
+ }
+
+ if (result)
+ result = result && doCheckState();
+
+ return notifyState(result);
+ }
+
+
+
+ /**
+ * A hook for subclasses to implement more specialized checks
+ *
+ * @return Whether the state is okay based on additional checks
+ */
+ protected boolean doCheckState() {
+ if (validator != null) {
+ String msg= validator.validate(getStringValue());
+ if (msg != null) {
+ setErrorMessage(msg);
+ return false;
+ }
+ }
+ clearErrorMessage();
+ return true;
+ }
+
+
+
+ protected boolean textNull = true;
+
+
+ public Text getTextControl() {
+ return getTextControl(parent);
+ }
+
+
+ /**
+ * Returns this field editor's text control.
+ *
+ * The control is created if it does not yet exist
+ *
+ * Copied from StringFieldEditor and adapted to this location.
+ *
+ * @param parent the parent
+ * @return the text control
+ */
+ public Text getTextControl(Composite parent) {
+ if (textField == null) {
+ textField = new Text(parent, SWT.SINGLE | SWT.BORDER);
+ textField.setFont(parent.getFont());
+ String toolTipText = getToolTipText();
+ if (toolTipText != null) {
+ textField.setToolTipText(toolTipText);
+ }
+ switch (validateStrategy) {
+ case org.eclipse.jface.preference.StringFieldEditor.VALIDATE_ON_KEY_STROKE:
+ textField.addKeyListener(new KeyAdapter() {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.KeyAdapter#keyReleased(org.eclipse.swt.events.KeyEvent)
+ */
+ public void keyReleased(KeyEvent e) {
+ // Should call setInherited(..) before calling valueChanged() because
+ // valueChanged() will mark the field as modified, but only if isInherited
+ // is false, which it now should be
+ refreshValidState();
+ setInherited(false);
+ boolean changed = valueChanged(true);
+ fieldModified = changed;
+
+ }
+ });
+
+ break;
+ case org.eclipse.jface.preference.StringFieldEditor.VALIDATE_ON_FOCUS_LOST:
+ textField.addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent e) {
+ clearErrorMessage();
+ }
+ });
+ textField.addFocusListener(new FocusAdapter() {
+ public void focusGained(FocusEvent e) {
+ refreshValidState();
+ }
+
+ public void focusLost(FocusEvent e) {
+ // Assume no change in inheritance with this event
+ valueChanged();
+ clearErrorMessage();
+ }
+ });
+ break;
+ default:
+ Assert.isTrue(false, "Unknown validate strategy");//$NON-NLS-1$
+ }
+ // SMS 16 Nov 2006
+ // The original StringFieldEditor just had a text-field modify listener,
+ // as copied below. But that would be redundant with the listeners copied
+ // from StringFieldEditor above. The use of more than one listener for the
+ // same event is problematic if they all check for changes in the text value,
+ // because only the first will see a change, and other will set fieldModified
+ // to false, in effect cancelling processing that should occur following the
+ // triggering change
+// textField.addModifyListener(
+// new ModifyListener() {
+// public void modifyText(ModifyEvent e) {
+// //System.out.println("STFE.text modify listener (from getTextControl): textModified set to true");
+// valueChanged();
+// fieldModified = true;
+// setInherited(false);
+// }
+// }
+// );
+ textField.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent event) {
+ textField = null;
+ }
+ });
+ if (textLimit > 0) {//Only set limits above 0 - see SWT spec
+ textField.setTextLimit(textLimit);
+ }
+ } else {
+ checkParent(textField, parent);
+ }
+ return textField;
+ }
+
+
+
+ /*
+ * UI-related methods copied from StringFieldEditor
+ */
+
+
+ /**
+ * Does something with the columns
+ * (but the IMP templates adjust columns separately)
+ */
+ protected void adjustForNumColumns(int numColumns) {
+ GridData gd = (GridData) textField.getLayoutData();
+ gd.horizontalSpan = numColumns - 1;
+ // We only grab excess space if we have to
+ // If another field editor has more columns then
+ // we assume it is setting the width.
+ gd.grabExcessHorizontalSpace = gd.horizontalSpan == 1;
+ }
+
+
+ /**
+ * Fills this field editor's basic controls into the given parent.
+ * <p>
+ * The string field implementation of this <code>FieldEditor</code>
+ * framework method contributes the text field. Subclasses may override
+ * but must call <code>super.doFillIntoGrid</code>.
+ * </p>
+ */
+ protected void doFillIntoGrid(Composite parent, int numColumns) {
+ getLabelControl(parent);
+
+ textField = getTextControl(parent);
+ GridData gd = new GridData();
+ gd.horizontalSpan = numColumns - 1;
+ if (widthInChars != org.eclipse.jface.preference.StringFieldEditor.UNLIMITED) {
+ GC gc = new GC(textField);
+ try {
+ Point extent = gc.textExtent("X");//$NON-NLS-1$
+ gd.widthHint = widthInChars * extent.x;
+ } finally {
+ gc.dispose();
+ }
+ } else {
+ gd.horizontalAlignment = GridData.FILL;
+ gd.grabExcessHorizontalSpace = true;
+ }
+ textField.setLayoutData(gd);
+ }
+
+ @Override
+ protected void doSetToolTip() {
+ if (toolTipText != null) {
+ getTextControl().setToolTipText(toolTipText);
+ }
+ }
+
+ /**
+ * Returns the number of controls in this editor.
+ * These are two: the text control and the label control.
+ *
+ * @return The number of controls in this editor
+ */
+ public int getNumberOfControls() {
+ return 2;
+ }
+
+
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForBooleanFields.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForBooleanFields.java
new file mode 100644
index 000000000..95cf7b2eb
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForBooleanFields.java
@@ -0,0 +1,292 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.preferences.fields.details;
+
+
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesUtilities;
+import org.eclipse.imp.preferences.fields.BooleanFieldEditor;
+import org.eclipse.imp.preferences.fields.PreferenceDialogConstants;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TrayDialog;
+import org.eclipse.jface.resource.JFaceColors;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+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.Shell;
+
+
+public class DetailsDialogForBooleanFields extends TrayDialog {
+
+ Shell parent = null;
+ BooleanFieldEditor field = null;
+ Composite fieldHolder = null;
+ IPreferencesService preferencesService = null;
+
+ private PreferencesUtilities prefUtils = null;
+
+ public DetailsDialogForBooleanFields (
+ Shell parent,
+ BooleanFieldEditor field,
+ Composite fieldHolder,
+ IPreferencesService preferencesService)
+ {
+ super(parent);
+
+ this.parent = parent;
+ this.field = field;
+ this.fieldHolder = fieldHolder;
+ this.preferencesService = preferencesService;
+ this.prefUtils = new PreferencesUtilities(this.preferencesService);
+ }
+
+
+ private final static int REMOVE_ID = IDialogConstants.CLIENT_ID + 1;
+// private final static int EMPTY_ID = IDialogConstants.CLIENT_ID + 2;
+ private final static int SPECIAL_ID = IDialogConstants.CLIENT_ID + 3;
+
+ /*
+ * Method declared on Dialog.
+ *
+ * The main result is to set the preference field in a particular way,
+ * according to the particular button pressed, but without updating the
+ * underlying preferences node. Thus the effect of this method is to
+ * change the field in the display without making the new value visible
+ * to other fields. For th e new value to take effect it must be later
+ * stored into the preferences node by some oher action (typically the
+ * pressing of an Apply or OK button).
+ *
+ */
+ protected void buttonPressed(int buttonId) {
+ switch (buttonId) {
+ case REMOVE_ID:
+ // Clear the preference if set at this level
+ if (field.getPreferencesLevel().equals(field.getLevelFromWhichLoaded()))
+ preferencesService.clearPreferenceAtLevel(field.getPreferencesLevel(), field.getPreferenceName());
+ // Set the field in a way that can find an inherited value
+ prefUtils.setField(field, fieldHolder);
+ break;
+ case SPECIAL_ID:
+ // Set the editor field directly and store it to update preferences node
+ prefUtils.setField(field, fieldHolder, ((Boolean)field.getSpecialValue()).booleanValue());
+ break;
+ // No empty value for booleans
+// case EMPTY_ID:
+// prefUtils.setField(field, fieldHolder, field.getEmptyValue());
+// break;
+ default:
+ super.buttonPressed(buttonId);
+ break;
+ }
+ close();
+ }
+
+
+ public boolean close() {
+ return super.close();
+ }
+
+
+ /*
+ * (non-Javadoc) Method declared on Window.
+ */
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ newShell.setText(NLS.bind("Details for ''" + field.getLabelText() + "''", null ));
+ //PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell,
+ // IWorkbenchHelpContextIds.ABOUT_DIALOG);
+ }
+
+ /**
+ * Add buttons to the dialog's button bar.
+ *
+ * Subclasses should override.
+ *
+ * @param parent
+ * the button bar composite
+ */
+ protected void createButtonsForButtonBar(Composite parent) {
+ parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Button specialButton = createButton(parent, SPECIAL_ID, PreferenceDialogConstants.SPECIAL_LABEL, false);
+ specialButton.setEnabled(field.getChangeControl().isEnabled() && field.hasSpecialValue() && field.getPreferencesLevel() != null);
+
+ Button removeButton = createButton(parent, REMOVE_ID, PreferenceDialogConstants.REMOVE_LABEL, false);
+ removeButton.setEnabled(field.getChangeControl().isEnabled() && (field.getPreferencesLevel() != null) && field.getPreferencesLevel().equals(field.getLevelFromWhichLoaded()) && field.isRemovable());
+
+ Label l = new Label(parent, SWT.NONE);
+ l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ GridLayout layout = (GridLayout) parent.getLayout();
+ layout.numColumns++;
+ layout.makeColumnsEqualWidth = false;
+
+ Button b = createButton(parent, IDialogConstants.OK_ID,
+ IDialogConstants.OK_LABEL, true);
+ b.setFocus();
+ }
+
+
+ protected Composite workArea = null;
+ protected Composite dialogAreaParent = null;
+
+ /**
+ * Creates and returns the contents of the upper part
+ * of the dialog (above the button bar).
+ *
+ * Subclasses should override.
+ *
+ * @param parent the parent composite to contain the dialog area
+ * @return the dialog area control
+ */
+ protected Control createDialogArea(Composite parent) {
+
+ dialogAreaParent = parent;
+
+// final Cursor hand = new Cursor(parent.getDisplay(), SWT.CURSOR_HAND);
+// final Cursor busy = new Cursor(parent.getDisplay(), SWT.CURSOR_WAIT);
+// setHandCursor(hand);
+// setBusyCursor(busy);
+// getShell().addDisposeListener(new DisposeListener() {
+// public void widgetDisposed(DisposeEvent e) {
+// setHandCursor(null);
+// hand.dispose();
+// setBusyCursor(null);
+// busy.dispose();
+// }
+// });
+
+
+ // create a composite which is the parent of the top area and the bottom
+ // button bar, this allows there to be a second child of this composite with
+ // a banner background on top but not have on the bottom
+
+ Composite workArea = new Composite(parent, SWT.NONE);
+ workArea = fillInWorkArea(workArea);
+ return workArea;
+ }
+
+
+ private Composite fillInWorkArea(Composite workArea) {
+ if (workArea.isDisposed()) System.err.println("fillInWorkArea: workArea is disposed!");
+ GridLayout workLayout = new GridLayout();
+ workLayout.marginHeight = 0;
+ workLayout.marginWidth = 0;
+ workLayout.verticalSpacing = 0;
+ workLayout.horizontalSpacing = 0;
+ workArea.setLayout(workLayout);
+ workArea.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ // page group
+ Color background = JFaceColors.getBannerBackground(parent.getDisplay());
+ Color foreground = JFaceColors.getBannerForeground(parent.getDisplay());
+ Composite top = (Composite) super.createDialogArea(workArea);
+
+ // override any layout inherited from createDialogArea
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ layout.verticalSpacing = 0;
+ layout.horizontalSpacing = 0;
+ top.setLayout(layout);
+ top.setLayoutData(new GridData(GridData.FILL_BOTH));
+ top.setBackground(background);
+ top.setForeground(foreground);
+
+ // the image & text
+ Composite topContainer = new Composite(top, SWT.NONE);
+ topContainer.setBackground(background);
+ topContainer.setForeground(foreground);
+
+ layout = new GridLayout();
+ layout.numColumns = (1);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.verticalSpacing = 0;
+ layout.horizontalSpacing = 0;
+ topContainer.setLayout(layout);
+ GridData data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.grabExcessHorizontalSpace = true;
+ topContainer.setLayoutData(data);
+
+ String levelString = null;
+ if (field.getPreferencesLevel() == null) {
+ levelString = "Details as currently applicable";
+ if (preferencesService.getProject() != null) {
+ levelString += " (including project preferences): ";
+ } else {
+ levelString += " (not including any project preferences): ";
+ }
+ }
+ else if (field.getPreferencesLevel().equals(IPreferencesService.INSTANCE_LEVEL))
+ levelString = PreferenceDialogConstants.INSTANCE_LEVEL_STRING;
+ else if (field.getPreferencesLevel().equals(IPreferencesService.CONFIGURATION_LEVEL))
+ levelString = PreferenceDialogConstants.CONFIGURATION_LEVEL_STRING;
+ else if (field.getPreferencesLevel().equals(IPreferencesService.DEFAULT_LEVEL))
+ levelString = PreferenceDialogConstants.DEFAULT_LEVEL_STRING;
+ else if (field.getPreferencesLevel().equals(IPreferencesService.PROJECT_LEVEL))
+ levelString = PreferenceDialogConstants.PROJECT_LEVEL_STRING;
+ else
+ levelString = PreferenceDialogConstants.UNKNOWN_LEVEL_STRING + field.getPreferencesLevel();
+
+ Label label = null;
+
+ label = new Label(topContainer, SWT.LEAD);
+ label.setText(levelString);
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(topContainer, SWT.LEAD);
+ label.setText("\tCurrent value: '" + field.getChangeControl().getSelection() + "'");
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(topContainer, SWT.LEAD);
+ String level = PreferenceDialogConstants.getLevelName(field.getLevelFromWhichLoaded());
+ label.setText("\tLevel at which set: " + level);
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+
+ label = new Label(topContainer, SWT.LEAD);
+ if (field.hasSpecialValue()) {
+ label.setText(PreferenceDialogConstants.HAS_SPECIAL + field.getSpecialValue());
+ } else {
+ label.setText(PreferenceDialogConstants.NO_SPECIAL);
+ }
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+
+ if ((field.getPreferencesLevel() != null) && field.getPreferencesLevel().equals(field.getLevelFromWhichLoaded())) {
+ label = new Label(topContainer, SWT.LEAD);
+ if (field.isRemovable()) {
+ label.setText(PreferenceDialogConstants.IS_REMOVABLE);
+ } else {
+ label.setText(PreferenceDialogConstants.NOT_REMOVABLE);
+ }
+ }
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(top, SWT.LEAD);
+ label.setText("~~~");
+ label.setVisible(false);
+
+
+ this.workArea = workArea;
+ return workArea;
+ }
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForColorFields.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForColorFields.java
new file mode 100644
index 000000000..a96ee0ebb
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForColorFields.java
@@ -0,0 +1,325 @@
+/*******************************************************************************
+* Copyright (c) 2009 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.preferences.fields.details;
+
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesUtilities;
+import org.eclipse.imp.preferences.fields.ColorFieldEditor;
+import org.eclipse.imp.preferences.fields.PreferenceDialogConstants;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TrayDialog;
+import org.eclipse.jface.resource.JFaceColors;
+import org.eclipse.jface.resource.StringConverter;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+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.Shell;
+
+public class DetailsDialogForColorFields extends TrayDialog {
+
+ Shell parent = null;
+ ColorFieldEditor field = null;
+ Composite fieldHolder = null;
+ IPreferencesService preferencesService = null;
+
+ private PreferencesUtilities prefUtils = null;
+
+ public DetailsDialogForColorFields (
+ Shell parent,
+ ColorFieldEditor field,
+ Composite fieldHolder,
+ IPreferencesService preferencesService)
+ {
+ super(parent);
+
+ this.parent = parent;
+ this.field = field;
+ this.fieldHolder = fieldHolder;
+ this.preferencesService = preferencesService;
+ this.prefUtils = new PreferencesUtilities(this.preferencesService);
+ }
+
+ private final static int COPY_ID = IDialogConstants.CLIENT_ID + 1;
+ private final static int REMOVE_ID = IDialogConstants.CLIENT_ID + 2;
+ private final static int SPECIAL_ID = IDialogConstants.CLIENT_ID + 3;
+ // No empty values for combo boxes
+ //private final static int EMPTY_ID = IDialogConstants.CLIENT_ID + 4;
+
+
+
+ /*
+ * Method declared on Dialog.
+ *
+ * The main result is to set the preference field in a particular way,
+ * according to the particular button pressed, but without updating the
+ * underlying preferences node. Thus the effect of this method is to
+ * change the field in the display without making the new value visible
+ * to other fields. For th e new value to take effect it must be later
+ * stored into the preferences node by some oher action (typically the
+ * pressing of an Apply or OK button).
+ *
+ */
+ protected void buttonPressed(int buttonId) {
+ switch (buttonId) {
+ case COPY_ID:
+ if (!field.isInherited()) break;
+ String color= StringConverter.asString(field.getColorSelector().getColorValue());
+ prefUtils.setField(field, fieldHolder, color);
+ break;
+ case REMOVE_ID:
+ // Can't clear a field that doesn't have a preference stored to start with;
+ // the following is one way to check that.
+ // Why would you do this if there weren't a preference stored? May want to
+ // clear a field that was edited (or otherwise set) locally but not yet stored.
+ if (field.getPreferencesLevel().equals(field.getLevelFromWhichLoaded())) {
+ preferencesService.clearPreferenceAtLevel(field.getPreferencesLevel(), field.getPreferenceName());
+ }
+ prefUtils.setField(field, fieldHolder);
+ break;
+// case SPECIAL_ID:
+// prefUtils.setField(field, fieldHolder, field.getSpecialStringValue());
+// break;
+// case EMPTY_ID:
+// prefUtils.setField(field, fieldHolder, field.getEmptyValue());
+// break;
+ default:
+ super.buttonPressed(buttonId);
+ break;
+ }
+ close();
+ }
+
+ public boolean close() {
+ return super.close();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on Window.
+ */
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ newShell.setText(NLS.bind("Details for ''" + field.getLabelText() + "''", null ));
+ //PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell,
+ // IWorkbenchHelpContextIds.ABOUT_DIALOG);
+ }
+
+ protected Button copyButton = null;
+ protected Button specialButton = null;
+ protected Button emptyButton = null;
+ Button removeButton = null;
+
+ /**
+ * Add buttons to the dialog's button bar.
+ *
+ * Subclasses should override.
+ *
+ * @param parent
+ * the button bar composite
+ */
+ protected void createButtonsForButtonBar(Composite parent) {
+ parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ if (!field.getPreferencesLevel().equals(IPreferencesService.DEFAULT_LEVEL)) {
+ copyButton = createButton(parent, COPY_ID, PreferenceDialogConstants.COPY_LABEL, false);
+ copyButton.setEnabled(field.getPreferencesLevel() != null &&
+ field.isInherited() && field.getColorSelector().getButton().isEnabled());
+ }
+
+ specialButton = createButton(parent, SPECIAL_ID, PreferenceDialogConstants.SPECIAL_LABEL, false);
+ specialButton.setEnabled(field.getPreferencesLevel() != null &&
+ field.hasSpecialValue() && field.getSpecialValue() != null &&
+ field.getColorSelector().getButton().isEnabled());
+
+// emptyButton = createButton(parent, EMPTY_ID, PreferenceDialogConstants.EMPTY_LABEL, false);
+// emptyButton.setEnabled(field.getPreferencesLevel() != null &&
+// field.isEmptyStringAllowed() && field.getComboBoxControl(parent).isEnabled());
+
+ removeButton = createButton(parent, REMOVE_ID, PreferenceDialogConstants.REMOVE_LABEL, false);
+ removeButton.setEnabled(
+ (field.getPreferencesLevel() != null) &&
+ !field.isInherited() &&
+ field.isRemovable() &&
+ field.getColorSelector().getButton().isEnabled());
+
+ Label l = new Label(parent, SWT.NONE);
+ l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ GridLayout layout = (GridLayout) parent.getLayout();
+ layout.numColumns++;
+ layout.makeColumnsEqualWidth = false;
+
+ Button b = createButton(parent, IDialogConstants.OK_ID,
+ IDialogConstants.OK_LABEL, true);
+ b.setFocus();
+ }
+
+
+ protected Composite workArea = null;
+ protected Composite dialogAreaParent = null;
+
+ /**
+ * Creates and returns the contents of the upper part
+ * of the dialog (above the button bar).
+ *
+ * Subclasses should override.
+ *
+ * @param parent the parent composite to contain the dialog area
+ * @return the dialog area control
+ */
+ protected Control createDialogArea(Composite parent) {
+
+ dialogAreaParent = parent;
+
+// final Cursor hand = new Cursor(parent.getDisplay(), SWT.CURSOR_HAND);
+// final Cursor busy = new Cursor(parent.getDisplay(), SWT.CURSOR_WAIT);
+// setHandCursor(hand);
+// setBusyCursor(busy);
+// getShell().addDisposeListener(new DisposeListener() {
+// public void widgetDisposed(DisposeEvent e) {
+// setHandCursor(null);
+// hand.dispose();
+// setBusyCursor(null);
+// busy.dispose();
+// }
+// });
+
+
+ // Create a composite which is the parent of the top area and the bottom
+ // button bar. This allows there to be a second child of the parent with
+ // a banner background on top but not on the bottom
+
+ Composite workArea = new Composite(parent, SWT.NONE);
+ workArea = fillInWorkArea(workArea);
+ return workArea;
+ }
+
+
+ private Composite fillInWorkArea(Composite workArea) {
+ if (workArea.isDisposed()) System.err.println("fillInWorkArea: workArea is disposed!!!");
+ GridLayout workLayout = new GridLayout();
+ workLayout.marginHeight = 0;
+ workLayout.marginWidth = 0;
+ workLayout.verticalSpacing = 0;
+ workLayout.horizontalSpacing = 0;
+ workArea.setLayout(workLayout);
+ workArea.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ // page group
+ Color background = JFaceColors.getBannerBackground(parent.getDisplay());
+ Color foreground = JFaceColors.getBannerForeground(parent.getDisplay());
+ Composite top = (Composite) super.createDialogArea(workArea);
+
+ // override any layout inherited from createDialogArea
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ layout.verticalSpacing = 0;
+ layout.horizontalSpacing = 0;
+ top.setLayout(layout);
+ top.setLayoutData(new GridData(GridData.FILL_BOTH));
+ top.setBackground(background);
+ top.setForeground(foreground);
+
+ // the image & text
+ Composite topContainer = new Composite(top, SWT.NONE);
+ topContainer.setBackground(background);
+ topContainer.setForeground(foreground);
+
+ layout = new GridLayout();
+ layout.numColumns = (1);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.verticalSpacing = 0;
+ layout.horizontalSpacing = 0;
+ topContainer.setLayout(layout);
+ GridData data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.grabExcessHorizontalSpace = true;
+ topContainer.setLayoutData(data);
+
+ String levelString = null;
+ if (field.getPreferencesLevel() == null) {
+ levelString = "Details as currently applicable";
+ if (preferencesService.getProject() != null) {
+ levelString += " (including project preferences): ";
+ } else {
+ levelString += " (not including any project preferences): ";
+ }
+ }
+ else if (field.getPreferencesLevel().equals(IPreferencesService.INSTANCE_LEVEL))
+ levelString = PreferenceDialogConstants.INSTANCE_LEVEL_STRING;
+ else if (field.getPreferencesLevel().equals(IPreferencesService.CONFIGURATION_LEVEL))
+ levelString = PreferenceDialogConstants.CONFIGURATION_LEVEL_STRING;
+ else if (field.getPreferencesLevel().equals(IPreferencesService.DEFAULT_LEVEL))
+ levelString = PreferenceDialogConstants.DEFAULT_LEVEL_STRING;
+ else if (field.getPreferencesLevel().equals(IPreferencesService.PROJECT_LEVEL))
+ levelString = PreferenceDialogConstants.PROJECT_LEVEL_STRING;
+ else
+ levelString = PreferenceDialogConstants.UNKNOWN_LEVEL_STRING + field.getPreferencesLevel();
+
+ Label label = null;
+
+ label = new Label(topContainer, SWT.LEAD);
+ label.setText(levelString);
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(topContainer, SWT.LEAD);
+ label.setText("\tCurrent value: '" + field.getFieldEditorFontName() + "'");
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(topContainer, SWT.LEAD);
+ String level = PreferenceDialogConstants.getLevelName(field.getLevelFromWhichLoaded());
+ label.setText("\tLevel at which set: " + level);
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+
+ label = new Label(topContainer, SWT.LEAD);
+// if (field.isEmptyStringAllowed()) {
+// label.setText(PreferenceDialogConstants.EMPTY_OK );
+// } else {
+// label.setText(PreferenceDialogConstants.EMPTY_NOT_OK);
+// }
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(topContainer, SWT.LEAD);
+ if (field.hasSpecialValue()) {
+ label.setText(PreferenceDialogConstants.HAS_SPECIAL + field.getSpecialValue());
+ } else {
+ label.setText(PreferenceDialogConstants.NO_SPECIAL);
+ }
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ if ((field.getPreferencesLevel() != null) && field.getPreferencesLevel().equals(field.getLevelFromWhichLoaded())) {
+ label = new Label(topContainer, SWT.LEAD);
+ if (field.isRemovable()) {
+ label.setText(PreferenceDialogConstants.IS_REMOVABLE);
+ } else {
+ label.setText(PreferenceDialogConstants.NOT_REMOVABLE);
+ }
+ }
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(top, SWT.LEAD);
+ label.setText("~~~");
+ label.setVisible(false);
+
+
+ this.workArea = workArea;
+ return workArea;
+ }
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForComboFields.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForComboFields.java
new file mode 100644
index 000000000..c54ed7ae8
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForComboFields.java
@@ -0,0 +1,323 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.preferences.fields.details;
+
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesUtilities;
+import org.eclipse.imp.preferences.fields.ComboFieldEditor;
+import org.eclipse.imp.preferences.fields.PreferenceDialogConstants;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TrayDialog;
+import org.eclipse.jface.resource.JFaceColors;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+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.Shell;
+
+public class DetailsDialogForComboFields extends TrayDialog {
+
+ Shell parent = null;
+ ComboFieldEditor field = null;
+ Composite fieldHolder = null;
+ IPreferencesService preferencesService = null;
+
+ private PreferencesUtilities prefUtils = null;
+
+ public DetailsDialogForComboFields (
+ Shell parent,
+ ComboFieldEditor field,
+ Composite fieldHolder,
+ IPreferencesService preferencesService)
+ {
+ super(parent);
+
+ this.parent = parent;
+ this.field = field;
+ this.fieldHolder = fieldHolder;
+ this.preferencesService = preferencesService;
+ this.prefUtils = new PreferencesUtilities(this.preferencesService);
+ }
+
+ private final static int COPY_ID = IDialogConstants.CLIENT_ID + 1;
+ private final static int REMOVE_ID = IDialogConstants.CLIENT_ID + 2;
+ private final static int SPECIAL_ID = IDialogConstants.CLIENT_ID + 3;
+ // No empty values for combo boxes
+ //private final static int EMPTY_ID = IDialogConstants.CLIENT_ID + 4;
+
+
+
+ /*
+ * Method declared on Dialog.
+ *
+ * The main result is to set the preference field in a particular way,
+ * according to the particular button pressed, but without updating the
+ * underlying preferences node. Thus the effect of this method is to
+ * change the field in the display without making the new value visible
+ * to other fields. For th e new value to take effect it must be later
+ * stored into the preferences node by some oher action (typically the
+ * pressing of an Apply or OK button).
+ *
+ */
+ protected void buttonPressed(int buttonId) {
+ switch (buttonId) {
+ case COPY_ID:
+ if (!field.isInherited()) break;
+ String value = field.getComboBoxControl().getText();
+ prefUtils.setField(field, fieldHolder, value);
+ break;
+ case REMOVE_ID:
+ // Can't clear a field that doesn't have a preference stored to start with;
+ // the following is one way to check that.
+ // Why would you do this if there weren't a preference stored? May want to
+ // clear a field that was edited (or otherwise set) locally but not yet stored.
+ if (field.getPreferencesLevel().equals(field.getLevelFromWhichLoaded())) {
+ preferencesService.clearPreferenceAtLevel(field.getPreferencesLevel(), field.getPreferenceName());
+ }
+ prefUtils.setField(field, fieldHolder);
+ break;
+ case SPECIAL_ID:
+ prefUtils.setField(field, fieldHolder, field.getSpecialStringValue());
+ break;
+// case EMPTY_ID:
+// prefUtils.setField(field, fieldHolder, field.getEmptyValue());
+// break;
+ default:
+ super.buttonPressed(buttonId);
+ break;
+ }
+ close();
+ }
+
+ public boolean close() {
+ return super.close();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on Window.
+ */
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ newShell.setText(NLS.bind("Details for ''" + field.getLabelText() + "''", null ));
+ //PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell,
+ // IWorkbenchHelpContextIds.ABOUT_DIALOG);
+ }
+
+ protected Button copyButton = null;
+ protected Button specialButton = null;
+ protected Button emptyButton = null;
+ Button removeButton = null;
+
+ /**
+ * Add buttons to the dialog's button bar.
+ *
+ * Subclasses should override.
+ *
+ * @param parent
+ * the button bar composite
+ */
+ protected void createButtonsForButtonBar(Composite parent) {
+ parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ if (!field.getPreferencesLevel().equals(IPreferencesService.DEFAULT_LEVEL)) {
+ copyButton = createButton(parent, COPY_ID, PreferenceDialogConstants.COPY_LABEL, false);
+ copyButton.setEnabled(field.getPreferencesLevel() != null &&
+ field.isInherited() && field.getComboBoxControl().isEnabled());
+ }
+
+ specialButton = createButton(parent, SPECIAL_ID, PreferenceDialogConstants.SPECIAL_LABEL, false);
+ specialButton.setEnabled(field.getPreferencesLevel() != null &&
+ field.hasSpecialValue() && field.getSpecialValue() != null &&
+ field.getComboBoxControl().isEnabled());
+
+// emptyButton = createButton(parent, EMPTY_ID, PreferenceDialogConstants.EMPTY_LABEL, false);
+// emptyButton.setEnabled(field.getPreferencesLevel() != null &&
+// field.isEmptyStringAllowed() && field.getComboBoxControl(parent).isEnabled());
+
+ removeButton = createButton(parent, REMOVE_ID, PreferenceDialogConstants.REMOVE_LABEL, false);
+ removeButton.setEnabled(
+ (field.getPreferencesLevel() != null) &&
+ !field.isInherited() &&
+ field.isRemovable() &&
+ field.getComboBoxControl().isEnabled());
+
+ Label l = new Label(parent, SWT.NONE);
+ l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ GridLayout layout = (GridLayout) parent.getLayout();
+ layout.numColumns++;
+ layout.makeColumnsEqualWidth = false;
+
+ Button b = createButton(parent, IDialogConstants.OK_ID,
+ IDialogConstants.OK_LABEL, true);
+ b.setFocus();
+ }
+
+
+ protected Composite workArea = null;
+ protected Composite dialogAreaParent = null;
+
+ /**
+ * Creates and returns the contents of the upper part
+ * of the dialog (above the button bar).
+ *
+ * Subclasses should override.
+ *
+ * @param parent the parent composite to contain the dialog area
+ * @return the dialog area control
+ */
+ protected Control createDialogArea(Composite parent) {
+
+ dialogAreaParent = parent;
+
+// final Cursor hand = new Cursor(parent.getDisplay(), SWT.CURSOR_HAND);
+// final Cursor busy = new Cursor(parent.getDisplay(), SWT.CURSOR_WAIT);
+// setHandCursor(hand);
+// setBusyCursor(busy);
+// getShell().addDisposeListener(new DisposeListener() {
+// public void widgetDisposed(DisposeEvent e) {
+// setHandCursor(null);
+// hand.dispose();
+// setBusyCursor(null);
+// busy.dispose();
+// }
+// });
+
+ // Create a composite which is the parent of the top area and the bottom
+ // button bar. This allows there to be a second child of the parent with
+ // a banner background on top but not on the bottom
+
+ Composite workArea = new Composite(parent, SWT.NONE);
+ workArea = fillInWorkArea(workArea);
+ return workArea;
+ }
+
+
+ private Composite fillInWorkArea(Composite workArea) {
+ if (workArea.isDisposed()) System.err.println("fillInWorkArea: workArea is disposed!!!");
+ GridLayout workLayout = new GridLayout();
+ workLayout.marginHeight = 0;
+ workLayout.marginWidth = 0;
+ workLayout.verticalSpacing = 0;
+ workLayout.horizontalSpacing = 0;
+ workArea.setLayout(workLayout);
+ workArea.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ // page group
+ Color background = JFaceColors.getBannerBackground(parent.getDisplay());
+ Color foreground = JFaceColors.getBannerForeground(parent.getDisplay());
+ Composite top = (Composite) super.createDialogArea(workArea);
+
+ // override any layout inherited from createDialogArea
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ layout.verticalSpacing = 0;
+ layout.horizontalSpacing = 0;
+ top.setLayout(layout);
+ top.setLayoutData(new GridData(GridData.FILL_BOTH));
+ top.setBackground(background);
+ top.setForeground(foreground);
+
+ // the image & text
+ Composite topContainer = new Composite(top, SWT.NONE);
+ topContainer.setBackground(background);
+ topContainer.setForeground(foreground);
+
+ layout = new GridLayout();
+ layout.numColumns = (1);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.verticalSpacing = 0;
+ layout.horizontalSpacing = 0;
+ topContainer.setLayout(layout);
+ GridData data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.grabExcessHorizontalSpace = true;
+ topContainer.setLayoutData(data);
+
+ String levelString = null;
+ if (field.getPreferencesLevel() == null) {
+ levelString = "Details as currently applicable";
+ if (preferencesService.getProject() != null) {
+ levelString += " (including project preferences): ";
+ } else {
+ levelString += " (not including any project preferences): ";
+ }
+ }
+ else if (field.getPreferencesLevel().equals(IPreferencesService.INSTANCE_LEVEL))
+ levelString = PreferenceDialogConstants.INSTANCE_LEVEL_STRING;
+ else if (field.getPreferencesLevel().equals(IPreferencesService.CONFIGURATION_LEVEL))
+ levelString = PreferenceDialogConstants.CONFIGURATION_LEVEL_STRING;
+ else if (field.getPreferencesLevel().equals(IPreferencesService.DEFAULT_LEVEL))
+ levelString = PreferenceDialogConstants.DEFAULT_LEVEL_STRING;
+ else if (field.getPreferencesLevel().equals(IPreferencesService.PROJECT_LEVEL))
+ levelString = PreferenceDialogConstants.PROJECT_LEVEL_STRING;
+ else
+ levelString = PreferenceDialogConstants.UNKNOWN_LEVEL_STRING + field.getPreferencesLevel();
+
+ Label label = null;
+
+ label = new Label(topContainer, SWT.LEAD);
+ label.setText(levelString);
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(topContainer, SWT.LEAD);
+ label.setText("\tCurrent value: '" + field.getStringValue() + "'");
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(topContainer, SWT.LEAD);
+ String level = PreferenceDialogConstants.getLevelName(field.getLevelFromWhichLoaded());
+ label.setText("\tLevel at which set: " + level);
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+
+ label = new Label(topContainer, SWT.LEAD);
+// if (field.isEmptyStringAllowed()) {
+// label.setText(PreferenceDialogConstants.EMPTY_OK );
+// } else {
+// label.setText(PreferenceDialogConstants.EMPTY_NOT_OK);
+// }
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(topContainer, SWT.LEAD);
+ if (field.hasSpecialValue()) {
+ label.setText(PreferenceDialogConstants.HAS_SPECIAL + field.getSpecialValue());
+ } else {
+ label.setText(PreferenceDialogConstants.NO_SPECIAL);
+ }
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ if ((field.getPreferencesLevel() != null) && field.getPreferencesLevel().equals(field.getLevelFromWhichLoaded())) {
+ label = new Label(topContainer, SWT.LEAD);
+ if (field.isRemovable()) {
+ label.setText(PreferenceDialogConstants.IS_REMOVABLE);
+ } else {
+ label.setText(PreferenceDialogConstants.NOT_REMOVABLE);
+ }
+ }
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(top, SWT.LEAD);
+ label.setText("~~~");
+ label.setVisible(false);
+
+
+ this.workArea = workArea;
+ return workArea;
+ }
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForFontFields.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForFontFields.java
new file mode 100644
index 000000000..92ded1b99
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForFontFields.java
@@ -0,0 +1,324 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.preferences.fields.details;
+
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesUtilities;
+import org.eclipse.imp.preferences.fields.FontFieldEditor;
+import org.eclipse.imp.preferences.fields.PreferenceDialogConstants;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TrayDialog;
+import org.eclipse.jface.resource.JFaceColors;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+public class DetailsDialogForFontFields extends TrayDialog {
+
+ Shell parent = null;
+ FontFieldEditor field = null;
+ Composite fieldHolder = null;
+ IPreferencesService preferencesService = null;
+
+ private PreferencesUtilities prefUtils = null;
+
+ public DetailsDialogForFontFields (
+ Shell parent,
+ FontFieldEditor field,
+ Composite fieldHolder,
+ IPreferencesService preferencesService)
+ {
+ super(parent);
+
+ this.parent = parent;
+ this.field = field;
+ this.fieldHolder = fieldHolder;
+ this.preferencesService = preferencesService;
+ this.prefUtils = new PreferencesUtilities(this.preferencesService);
+ }
+
+ private final static int COPY_ID = IDialogConstants.CLIENT_ID + 1;
+ private final static int REMOVE_ID = IDialogConstants.CLIENT_ID + 2;
+ private final static int SPECIAL_ID = IDialogConstants.CLIENT_ID + 3;
+ // No empty values for combo boxes
+ //private final static int EMPTY_ID = IDialogConstants.CLIENT_ID + 4;
+
+
+
+ /*
+ * Method declared on Dialog.
+ *
+ * The main result is to set the preference field in a particular way,
+ * according to the particular button pressed, but without updating the
+ * underlying preferences node. Thus the effect of this method is to
+ * change the field in the display without making the new value visible
+ * to other fields. For th e new value to take effect it must be later
+ * stored into the preferences node by some oher action (typically the
+ * pressing of an Apply or OK button).
+ *
+ */
+ protected void buttonPressed(int buttonId) {
+ switch (buttonId) {
+ case COPY_ID:
+ if (!field.isInherited()) break;
+ FontData[] fontData = field.getSelectedFont();
+ prefUtils.setField(field, fieldHolder, fontData);
+ break;
+ case REMOVE_ID:
+ // Can't clear a field that doesn't have a preference stored to start with;
+ // the following is one way to check that.
+ // Why would you do this if there weren't a preference stored? May want to
+ // clear a field that was edited (or otherwise set) locally but not yet stored.
+ if (field.getPreferencesLevel().equals(field.getLevelFromWhichLoaded())) {
+ preferencesService.clearPreferenceAtLevel(field.getPreferencesLevel(), field.getPreferenceName());
+ }
+ prefUtils.setField(field, fieldHolder);
+ break;
+// case SPECIAL_ID:
+// prefUtils.setField(field, fieldHolder, field.getSpecialStringValue());
+// break;
+// case EMPTY_ID:
+// prefUtils.setField(field, fieldHolder, field.getEmptyValue());
+// break;
+ default:
+ super.buttonPressed(buttonId);
+ break;
+ }
+ close();
+ }
+
+ public boolean close() {
+ return super.close();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on Window.
+ */
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ newShell.setText(NLS.bind("Details for ''" + field.getLabelText() + "''", null ));
+ //PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell,
+ // IWorkbenchHelpContextIds.ABOUT_DIALOG);
+ }
+
+ protected Button copyButton = null;
+ protected Button specialButton = null;
+ protected Button emptyButton = null;
+ Button removeButton = null;
+
+ /**
+ * Add buttons to the dialog's button bar.
+ *
+ * Subclasses should override.
+ *
+ * @param parent
+ * the button bar composite
+ */
+ protected void createButtonsForButtonBar(Composite parent) {
+ parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ if (!field.getPreferencesLevel().equals(IPreferencesService.DEFAULT_LEVEL)) {
+ copyButton = createButton(parent, COPY_ID, PreferenceDialogConstants.COPY_LABEL, false);
+ copyButton.setEnabled(field.getPreferencesLevel() != null &&
+ field.isInherited() && field.getChangeControl().isEnabled());
+ }
+
+ specialButton = createButton(parent, SPECIAL_ID, PreferenceDialogConstants.SPECIAL_LABEL, false);
+ specialButton.setEnabled(field.getPreferencesLevel() != null &&
+ field.hasSpecialValue() && field.getSpecialValue() != null &&
+ field.getChangeControl().isEnabled());
+
+// emptyButton = createButton(parent, EMPTY_ID, PreferenceDialogConstants.EMPTY_LABEL, false);
+// emptyButton.setEnabled(field.getPreferencesLevel() != null &&
+// field.isEmptyStringAllowed() && field.getComboBoxControl(parent).isEnabled());
+
+ removeButton = createButton(parent, REMOVE_ID, PreferenceDialogConstants.REMOVE_LABEL, false);
+ removeButton.setEnabled(
+ (field.getPreferencesLevel() != null) &&
+ !field.isInherited() &&
+ field.isRemovable() &&
+ field.getChangeControl().isEnabled());
+
+ Label l = new Label(parent, SWT.NONE);
+ l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ GridLayout layout = (GridLayout) parent.getLayout();
+ layout.numColumns++;
+ layout.makeColumnsEqualWidth = false;
+
+ Button b = createButton(parent, IDialogConstants.OK_ID,
+ IDialogConstants.OK_LABEL, true);
+ b.setFocus();
+ }
+
+
+ protected Composite workArea = null;
+ protected Composite dialogAreaParent = null;
+
+ /**
+ * Creates and returns the contents of the upper part
+ * of the dialog (above the button bar).
+ *
+ * Subclasses should override.
+ *
+ * @param parent the parent composite to contain the dialog area
+ * @return the dialog area control
+ */
+ protected Control createDialogArea(Composite parent) {
+
+ dialogAreaParent = parent;
+
+// final Cursor hand = new Cursor(parent.getDisplay(), SWT.CURSOR_HAND);
+// final Cursor busy = new Cursor(parent.getDisplay(), SWT.CURSOR_WAIT);
+// setHandCursor(hand);
+// setBusyCursor(busy);
+// getShell().addDisposeListener(new DisposeListener() {
+// public void widgetDisposed(DisposeEvent e) {
+// setHandCursor(null);
+// hand.dispose();
+// setBusyCursor(null);
+// busy.dispose();
+// }
+// });
+
+ // Create a composite which is the parent of the top area and the bottom
+ // button bar. This allows there to be a second child of the parent with
+ // a banner background on top but not on the bottom
+
+ Composite workArea = new Composite(parent, SWT.NONE);
+ workArea = fillInWorkArea(workArea);
+ return workArea;
+ }
+
+
+ private Composite fillInWorkArea(Composite workArea) {
+ if (workArea.isDisposed()) System.err.println("fillInWorkArea: workArea is disposed!!!");
+ GridLayout workLayout = new GridLayout();
+ workLayout.marginHeight = 0;
+ workLayout.marginWidth = 0;
+ workLayout.verticalSpacing = 0;
+ workLayout.horizontalSpacing = 0;
+ workArea.setLayout(workLayout);
+ workArea.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ // page group
+ Color background = JFaceColors.getBannerBackground(parent.getDisplay());
+ Color foreground = JFaceColors.getBannerForeground(parent.getDisplay());
+ Composite top = (Composite) super.createDialogArea(workArea);
+
+ // override any layout inherited from createDialogArea
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ layout.verticalSpacing = 0;
+ layout.horizontalSpacing = 0;
+ top.setLayout(layout);
+ top.setLayoutData(new GridData(GridData.FILL_BOTH));
+ top.setBackground(background);
+ top.setForeground(foreground);
+
+ // the image & text
+ Composite topContainer = new Composite(top, SWT.NONE);
+ topContainer.setBackground(background);
+ topContainer.setForeground(foreground);
+
+ layout = new GridLayout();
+ layout.numColumns = (1);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.verticalSpacing = 0;
+ layout.horizontalSpacing = 0;
+ topContainer.setLayout(layout);
+ GridData data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.grabExcessHorizontalSpace = true;
+ topContainer.setLayoutData(data);
+
+ String levelString = null;
+ if (field.getPreferencesLevel() == null) {
+ levelString = "Details as currently applicable";
+ if (preferencesService.getProject() != null) {
+ levelString += " (including project preferences): ";
+ } else {
+ levelString += " (not including any project preferences): ";
+ }
+ }
+ else if (field.getPreferencesLevel().equals(IPreferencesService.INSTANCE_LEVEL))
+ levelString = PreferenceDialogConstants.INSTANCE_LEVEL_STRING;
+ else if (field.getPreferencesLevel().equals(IPreferencesService.CONFIGURATION_LEVEL))
+ levelString = PreferenceDialogConstants.CONFIGURATION_LEVEL_STRING;
+ else if (field.getPreferencesLevel().equals(IPreferencesService.DEFAULT_LEVEL))
+ levelString = PreferenceDialogConstants.DEFAULT_LEVEL_STRING;
+ else if (field.getPreferencesLevel().equals(IPreferencesService.PROJECT_LEVEL))
+ levelString = PreferenceDialogConstants.PROJECT_LEVEL_STRING;
+ else
+ levelString = PreferenceDialogConstants.UNKNOWN_LEVEL_STRING + field.getPreferencesLevel();
+
+ Label label = null;
+
+ label = new Label(topContainer, SWT.LEAD);
+ label.setText(levelString);
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(topContainer, SWT.LEAD);
+ label.setText("\tCurrent value: '" + field.getFieldEditorFontName() + "'");
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(topContainer, SWT.LEAD);
+ String level = PreferenceDialogConstants.getLevelName(field.getLevelFromWhichLoaded());
+ label.setText("\tLevel at which set: " + level);
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+
+ label = new Label(topContainer, SWT.LEAD);
+// if (field.isEmptyStringAllowed()) {
+// label.setText(PreferenceDialogConstants.EMPTY_OK );
+// } else {
+// label.setText(PreferenceDialogConstants.EMPTY_NOT_OK);
+// }
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(topContainer, SWT.LEAD);
+ if (field.hasSpecialValue()) {
+ label.setText(PreferenceDialogConstants.HAS_SPECIAL + field.getSpecialValue());
+ } else {
+ label.setText(PreferenceDialogConstants.NO_SPECIAL);
+ }
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ if ((field.getPreferencesLevel() != null) && field.getPreferencesLevel().equals(field.getLevelFromWhichLoaded())) {
+ label = new Label(topContainer, SWT.LEAD);
+ if (field.isRemovable()) {
+ label.setText(PreferenceDialogConstants.IS_REMOVABLE);
+ } else {
+ label.setText(PreferenceDialogConstants.NOT_REMOVABLE);
+ }
+ }
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(top, SWT.LEAD);
+ label.setText("~~~");
+ label.setVisible(false);
+
+
+ this.workArea = workArea;
+ return workArea;
+ }
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForRadioGroupFields.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForRadioGroupFields.java
new file mode 100644
index 000000000..901a3eea7
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForRadioGroupFields.java
@@ -0,0 +1,323 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.preferences.fields.details;
+
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesUtilities;
+import org.eclipse.imp.preferences.fields.PreferenceDialogConstants;
+import org.eclipse.imp.preferences.fields.RadioGroupFieldEditor;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TrayDialog;
+import org.eclipse.jface.resource.JFaceColors;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+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.Shell;
+
+public class DetailsDialogForRadioGroupFields extends TrayDialog {
+
+ Shell parent = null;
+ RadioGroupFieldEditor field = null;
+ Composite fieldHolder = null;
+ IPreferencesService preferencesService = null;
+
+ private PreferencesUtilities prefUtils = null;
+
+ public DetailsDialogForRadioGroupFields (
+ Shell parent,
+ RadioGroupFieldEditor field,
+ Composite fieldHolder,
+ IPreferencesService preferencesService)
+ {
+ super(parent);
+
+ this.parent = parent;
+ this.field = field;
+ this.fieldHolder = fieldHolder;
+ this.preferencesService = preferencesService;
+ this.prefUtils = new PreferencesUtilities(this.preferencesService);
+ }
+
+ private final static int COPY_ID = IDialogConstants.CLIENT_ID + 1;
+ private final static int REMOVE_ID = IDialogConstants.CLIENT_ID + 2;
+ private final static int SPECIAL_ID = IDialogConstants.CLIENT_ID + 3;
+ // No empty value for radio groups
+ //private final static int EMPTY_ID = IDialogConstants.CLIENT_ID + 4;
+
+
+
+ /*
+ * Method declared on Dialog.
+ *
+ * The main result is to set the preference field in a particular way,
+ * according to the particular button pressed, but without updating the
+ * underlying preferences node. Thus the effect of this method is to
+ * change the field in the display without making the new value visible
+ * to other fields. For th e new value to take effect it must be later
+ * stored into the preferences node by some oher action (typically the
+ * pressing of an Apply or OK button).
+ *
+ */
+ protected void buttonPressed(int buttonId) {
+ switch (buttonId) {
+ case COPY_ID:
+ if (!field.isInherited()) break;
+ String value = field.getStringValue();
+ prefUtils.setField(field, fieldHolder, value);
+ break;
+ case REMOVE_ID:
+ // Can't clear a field that doesn't have a preference stored to start with;
+ // the following is one way to check that.
+ // Why would you do this if there weren't a preference stored? May want to
+ // clear a field that was edited (or otherwise set) locally but not yet stored.
+ if (field.getPreferencesLevel().equals(field.getLevelFromWhichLoaded())) {
+ preferencesService.clearPreferenceAtLevel(field.getPreferencesLevel(), field.getPreferenceName());
+ }
+ prefUtils.setField(field, fieldHolder);
+ break;
+ case SPECIAL_ID:
+ prefUtils.setField(field, fieldHolder, field.getSpecialStringValue());
+ break;
+// case EMPTY_ID:
+// // No empty value
+// break;
+ default:
+ super.buttonPressed(buttonId);
+ break;
+ }
+ close();
+ }
+
+ public boolean close() {
+ return super.close();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on Window.
+ */
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ newShell.setText(NLS.bind("Details for ''" + field.getLabelText() + "''", null ));
+ //PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell,
+ // IWorkbenchHelpContextIds.ABOUT_DIALOG);
+ }
+
+ protected Button copyButton = null;
+ protected Button specialButton = null;
+ protected Button emptyButton = null;
+ Button removeButton = null;
+
+ /**
+ * Add buttons to the dialog's button bar.
+ *
+ * Subclasses should override.
+ *
+ * @param parent
+ * the button bar composite
+ */
+ protected void createButtonsForButtonBar(Composite parent) {
+ parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ if (!field.getPreferencesLevel().equals(IPreferencesService.DEFAULT_LEVEL)) {
+ copyButton = createButton(parent, COPY_ID, PreferenceDialogConstants.COPY_LABEL, false);
+ copyButton.setEnabled(field.getPreferencesLevel() != null &&
+ field.isInherited() && field.getRadioBoxControl().isEnabled());
+ }
+
+ specialButton = createButton(parent, SPECIAL_ID, PreferenceDialogConstants.SPECIAL_LABEL, false);
+ specialButton.setEnabled(field.getPreferencesLevel() != null &&
+ field.hasSpecialValue() && field.getSpecialValue() != null &&
+ field.getRadioBoxControl().isEnabled());
+
+// emptyButton = createButton(parent, EMPTY_ID, PreferenceDialogConstants.EMPTY_LABEL, false);
+// emptyButton.setEnabled(field.getPreferencesLevel() != null &&
+// field.isEmptyStringAllowed() && field.getEmptyValue() != null &&
+// field.getTextControl().isEnabled() && field.getTextControl().getEditable());
+
+ removeButton = createButton(parent, REMOVE_ID, PreferenceDialogConstants.REMOVE_LABEL, false);
+ removeButton.setEnabled(
+ (field.getPreferencesLevel() != null) &&
+ !field.isInherited() && field.isRemovable() &&
+ field.getRadioBoxControl().isEnabled());
+
+ Label l = new Label(parent, SWT.NONE);
+ l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ GridLayout layout = (GridLayout) parent.getLayout();
+ layout.numColumns++;
+ layout.makeColumnsEqualWidth = false;
+
+ Button b = createButton(parent, IDialogConstants.OK_ID,
+ IDialogConstants.OK_LABEL, true);
+ b.setFocus();
+ }
+
+
+ protected Composite workArea = null;
+ protected Composite dialogAreaParent = null;
+
+ /**
+ * Creates and returns the contents of the upper part
+ * of the dialog (above the button bar).
+ *
+ * Subclasses should override.
+ *
+ * @param parent the parent composite to contain the dialog area
+ * @return the dialog area control
+ */
+ protected Control createDialogArea(Composite parent) {
+
+ dialogAreaParent = parent;
+
+// final Cursor hand = new Cursor(parent.getDisplay(), SWT.CURSOR_HAND);
+// final Cursor busy = new Cursor(parent.getDisplay(), SWT.CURSOR_WAIT);
+// setHandCursor(hand);
+// setBusyCursor(busy);
+// getShell().addDisposeListener(new DisposeListener() {
+// public void widgetDisposed(DisposeEvent e) {
+// setHandCursor(null);
+// hand.dispose();
+// setBusyCursor(null);
+// busy.dispose();
+// }
+// });
+
+ // Create a composite which is the parent of the top area and the bottom
+ // button bar. This allows there to be a second child of the parent with
+ // a banner background on top but not on the bottom
+
+ Composite workArea = new Composite(parent, SWT.NONE);
+ workArea = fillInWorkArea(workArea);
+ return workArea;
+ }
+
+
+ private Composite fillInWorkArea(Composite workArea) {
+ if (workArea.isDisposed()) System.err.println("fillInWorkArea: workArea is disposed!!!");
+ GridLayout workLayout = new GridLayout();
+ workLayout.marginHeight = 0;
+ workLayout.marginWidth = 0;
+ workLayout.verticalSpacing = 0;
+ workLayout.horizontalSpacing = 0;
+ workArea.setLayout(workLayout);
+ workArea.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ // page group
+ Color background = JFaceColors.getBannerBackground(parent.getDisplay());
+ Color foreground = JFaceColors.getBannerForeground(parent.getDisplay());
+ Composite top = (Composite) super.createDialogArea(workArea);
+
+ // override any layout inherited from createDialogArea
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ layout.verticalSpacing = 0;
+ layout.horizontalSpacing = 0;
+ top.setLayout(layout);
+ top.setLayoutData(new GridData(GridData.FILL_BOTH));
+ top.setBackground(background);
+ top.setForeground(foreground);
+
+ // the image & text
+ Composite topContainer = new Composite(top, SWT.NONE);
+ topContainer.setBackground(background);
+ topContainer.setForeground(foreground);
+
+ layout = new GridLayout();
+ layout.numColumns = (1);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.verticalSpacing = 0;
+ layout.horizontalSpacing = 0;
+ topContainer.setLayout(layout);
+ GridData data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.grabExcessHorizontalSpace = true;
+ topContainer.setLayoutData(data);
+
+ String levelString = null;
+ if (field.getPreferencesLevel() == null) {
+ levelString = "Details as currently applicable";
+ if (preferencesService.getProject() != null) {
+ levelString += " (including project preferences): ";
+ } else {
+ levelString += " (not including any project preferences): ";
+ }
+ }
+ else if (field.getPreferencesLevel().equals(IPreferencesService.INSTANCE_LEVEL))
+ levelString = PreferenceDialogConstants.INSTANCE_LEVEL_STRING;
+ else if (field.getPreferencesLevel().equals(IPreferencesService.CONFIGURATION_LEVEL))
+ levelString = PreferenceDialogConstants.CONFIGURATION_LEVEL_STRING;
+ else if (field.getPreferencesLevel().equals(IPreferencesService.DEFAULT_LEVEL))
+ levelString = PreferenceDialogConstants.DEFAULT_LEVEL_STRING;
+ else if (field.getPreferencesLevel().equals(IPreferencesService.PROJECT_LEVEL))
+ levelString = PreferenceDialogConstants.PROJECT_LEVEL_STRING;
+ else
+ levelString = PreferenceDialogConstants.UNKNOWN_LEVEL_STRING + field.getPreferencesLevel();
+
+ Label label = null;
+
+ label = new Label(topContainer, SWT.LEAD);
+ label.setText(levelString);
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(topContainer, SWT.LEAD);
+ label.setText("\tCurrent value: '" + field.getStringValue());
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(topContainer, SWT.LEAD);
+ String level = PreferenceDialogConstants.getLevelName(field.getLevelFromWhichLoaded());
+ label.setText("\tLevel at which set: " + level);
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+
+// label = new Label(topContainer, SWT.LEAD);
+// if (field.isEmptyStringAllowed()) {
+// label.setText(PreferenceDialogConstants.EMPTY_OK );
+// } else {
+// label.setText(PreferenceDialogConstants.EMPTY_NOT_OK);
+// }
+// label.setBackground(prefUtils.colorWhite);
+
+ label = new Label(topContainer, SWT.LEAD);
+ if (field.hasSpecialValue()) {
+ label.setText(PreferenceDialogConstants.HAS_SPECIAL + field.getSpecialValue());
+ } else {
+ label.setText(PreferenceDialogConstants.NO_SPECIAL);
+ }
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ if ((field.getPreferencesLevel() != null) && field.getPreferencesLevel().equals(field.getLevelFromWhichLoaded())) {
+ label = new Label(topContainer, SWT.LEAD);
+ if (field.isRemovable()) {
+ label.setText(PreferenceDialogConstants.IS_REMOVABLE);
+ } else {
+ label.setText(PreferenceDialogConstants.NOT_REMOVABLE);
+ }
+ }
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(top, SWT.LEAD);
+ label.setText("~~~");
+ label.setVisible(false);
+
+
+ this.workArea = workArea;
+ return workArea;
+ }
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForStringFields.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForStringFields.java
new file mode 100644
index 000000000..9ea52e028
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/preferences/fields/details/DetailsDialogForStringFields.java
@@ -0,0 +1,335 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.preferences.fields.details;
+
+import org.eclipse.imp.preferences.IPreferencesService;
+import org.eclipse.imp.preferences.PreferencesUtilities;
+import org.eclipse.imp.preferences.fields.PreferenceDialogConstants;
+import org.eclipse.imp.preferences.fields.StringFieldEditor;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TrayDialog;
+import org.eclipse.jface.resource.JFaceColors;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+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.Shell;
+
+public class DetailsDialogForStringFields extends TrayDialog {
+
+ Shell parent = null;
+ StringFieldEditor field = null;
+ Composite fieldHolder = null;
+ IPreferencesService preferencesService = null;
+
+ private PreferencesUtilities prefUtils = null;
+
+ public DetailsDialogForStringFields (
+ Shell parent,
+ StringFieldEditor field,
+ Composite fieldHolder,
+ IPreferencesService preferencesService)
+ {
+ super(parent);
+
+ this.parent = parent;
+ this.field = field;
+ this.fieldHolder = fieldHolder;
+ this.preferencesService = preferencesService;
+ this.prefUtils = new PreferencesUtilities(this.preferencesService);
+ }
+
+ private final static int COPY_ID = IDialogConstants.CLIENT_ID + 1;
+ private final static int REMOVE_ID = IDialogConstants.CLIENT_ID + 2;
+ private final static int SPECIAL_ID = IDialogConstants.CLIENT_ID + 3;
+ private final static int EMPTY_ID = IDialogConstants.CLIENT_ID + 4;
+
+
+
+ /*
+ * Method declared on Dialog.
+ *
+ * The main result is to set the preference field in a particular way,
+ * according to the particular button pressed, but without updating the
+ * underlying preferences node. Thus the effect of this method is to
+ * change the field in the display without making the new value visible
+ * to other fields. For th e new value to take effect it must be later
+ * stored into the preferences node by some oher action (typically the
+ * pressing of an Apply or OK button).
+ *
+ */
+ protected void buttonPressed(int buttonId) {
+ if (field.getPreferencesLevel().equals(IPreferencesService.PROJECT_LEVEL) &&
+ preferencesService.getProject() == null)
+ {
+ return;
+ }
+ switch (buttonId) {
+ case COPY_ID:
+ if (!field.isInherited()) break;
+ String value = field.getTextControl().getText();
+ prefUtils.setField(field, fieldHolder, value);
+ break;
+ case REMOVE_ID:
+ // Clear the preference if set at this level
+ if (field.getPreferencesLevel().equals(field.getLevelFromWhichLoaded())) {
+ preferencesService.clearPreferenceAtLevel(field.getPreferencesLevel(), field.getPreferenceName());
+ }
+ // Set the field in a way that can find an inherited value
+ prefUtils.setField(field, fieldHolder);
+ break;
+ case SPECIAL_ID:
+ // Set the editor field directly and store it to update preferences node
+ prefUtils.setField(field, fieldHolder, field.getSpecialStringValue());
+ break;
+ case EMPTY_ID:
+ // Set the editor field directly and store it to update preferences node
+ prefUtils.setField(field, fieldHolder, field.getEmptyValue());
+ break;
+ default:
+ super.buttonPressed(buttonId);
+ break;
+ }
+ close();
+ }
+
+ public boolean close() {
+ return super.close();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on Window.
+ */
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ newShell.setText(NLS.bind("Details for ''" + field.getLabelText() + "''", null ));
+ //PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell,
+ // IWorkbenchHelpContextIds.ABOUT_DIALOG);
+ }
+
+ protected Button copyButton = null;
+ protected Button specialButton = null;
+ protected Button emptyButton = null;
+ Button removeButton = null;
+
+ /**
+ * Add buttons to the dialog's button bar.
+ *
+ * Subclasses should override.
+ *
+ * @param parent
+ * the button bar composite
+ */
+ protected void createButtonsForButtonBar(Composite parent) {
+ parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ // boolean enabled;
+
+ if (!field.getPreferencesLevel().equals(IPreferencesService.DEFAULT_LEVEL)) {
+ copyButton = createButton(parent, COPY_ID, PreferenceDialogConstants.COPY_LABEL, false);
+ copyButton.setEnabled(field.getPreferencesLevel() != null &&
+ field.isInherited() &&
+ field.getTextControl().isEnabled() && field.getTextControl().getEditable());
+ }
+
+ specialButton = createButton(parent, SPECIAL_ID, PreferenceDialogConstants.SPECIAL_LABEL, false);
+ specialButton.setEnabled(field.getPreferencesLevel() != null &&
+ field.hasSpecialValue() && field.getSpecialValue() != null &&
+ field.getTextControl().isEnabled() && field.getTextControl().getEditable());
+
+ emptyButton = createButton(parent, EMPTY_ID, PreferenceDialogConstants.EMPTY_LABEL, false);
+ emptyButton.setEnabled(field.getPreferencesLevel() != null &&
+ field.isEmptyValueAllowed() && field.getEmptyValue() != null &&
+ field.getTextControl().isEnabled() && field.getTextControl().getEditable());
+
+ removeButton = createButton(parent, REMOVE_ID, PreferenceDialogConstants.REMOVE_LABEL, false);
+ removeButton.setEnabled(
+ (field.getPreferencesLevel() != null) &&
+ !field.isInherited() &&
+ field.isRemovable() &&
+ field.getTextControl().isEnabled() && field.getTextControl().getEditable());
+
+ Label l = new Label(parent, SWT.NONE);
+ l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ GridLayout layout = (GridLayout) parent.getLayout();
+ layout.numColumns++;
+ layout.makeColumnsEqualWidth = false;
+
+ Button b = createButton(parent, IDialogConstants.OK_ID,
+ IDialogConstants.OK_LABEL, true);
+ b.setFocus();
+ }
+
+
+ protected Composite workArea = null;
+ protected Composite dialogAreaParent = null;
+
+ /**
+ * Creates and returns the contents of the upper part
+ * of the dialog (above the button bar).
+ *
+ * Subclasses should override.
+ *
+ * @param parent the parent composite to contain the dialog area
+ * @return the dialog area control
+ */
+ protected Control createDialogArea(Composite parent) {
+
+ dialogAreaParent = parent;
+
+// final Cursor hand = new Cursor(parent.getDisplay(), SWT.CURSOR_HAND);
+// final Cursor busy = new Cursor(parent.getDisplay(), SWT.CURSOR_WAIT);
+// setHandCursor(hand);
+// setBusyCursor(busy);
+// getShell().addDisposeListener(new DisposeListener() {
+// public void widgetDisposed(DisposeEvent e) {
+// setHandCursor(null);
+// hand.dispose();
+// setBusyCursor(null);
+// busy.dispose();
+// }
+// });
+
+ // Create a composite which is the parent of the top area and the bottom
+ // button bar. This allows there to be a second child of the parent with
+ // a banner background on top but not on the bottom
+
+ Composite workArea = new Composite(parent, SWT.NONE);
+ workArea = fillInWorkArea(workArea);
+ return workArea;
+ }
+
+
+ private Composite fillInWorkArea(Composite workArea) {
+ if (workArea.isDisposed()) System.err.println("fillInWorkArea: workArea is disposed!!!");
+ GridLayout workLayout = new GridLayout();
+ workLayout.marginHeight = 0;
+ workLayout.marginWidth = 0;
+ workLayout.verticalSpacing = 0;
+ workLayout.horizontalSpacing = 0;
+ workArea.setLayout(workLayout);
+ workArea.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ // page group
+ Color background = JFaceColors.getBannerBackground(parent.getDisplay());
+ Color foreground = JFaceColors.getBannerForeground(parent.getDisplay());
+ Composite top = (Composite) super.createDialogArea(workArea);
+
+ // override any layout inherited from createDialogArea
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ layout.verticalSpacing = 0;
+ layout.horizontalSpacing = 0;
+ top.setLayout(layout);
+ top.setLayoutData(new GridData(GridData.FILL_BOTH));
+ top.setBackground(background);
+ top.setForeground(foreground);
+
+ // the image & text
+ Composite topContainer = new Composite(top, SWT.NONE);
+ topContainer.setBackground(background);
+ topContainer.setForeground(foreground);
+
+ layout = new GridLayout();
+ layout.numColumns = (1);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.verticalSpacing = 0;
+ layout.horizontalSpacing = 0;
+ topContainer.setLayout(layout);
+ GridData data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.grabExcessHorizontalSpace = true;
+ topContainer.setLayoutData(data);
+
+ String levelString = null;
+ if (field.getPreferencesLevel() == null) {
+ levelString = "Details as currently applicable";
+ if (preferencesService.getProject() != null) {
+ levelString += " (including project preferences): ";
+ } else {
+ levelString += " (not including any project preferences): ";
+ }
+ }
+ else if (field.getPreferencesLevel().equals(IPreferencesService.INSTANCE_LEVEL))
+ levelString = PreferenceDialogConstants.INSTANCE_LEVEL_STRING;
+ else if (field.getPreferencesLevel().equals(IPreferencesService.CONFIGURATION_LEVEL))
+ levelString = PreferenceDialogConstants.CONFIGURATION_LEVEL_STRING;
+ else if (field.getPreferencesLevel().equals(IPreferencesService.DEFAULT_LEVEL))
+ levelString = PreferenceDialogConstants.DEFAULT_LEVEL_STRING;
+ else if (field.getPreferencesLevel().equals(IPreferencesService.PROJECT_LEVEL))
+ levelString = PreferenceDialogConstants.PROJECT_LEVEL_STRING;
+ else
+ levelString = PreferenceDialogConstants.UNKNOWN_LEVEL_STRING + field.getPreferencesLevel();
+
+ Label label = null;
+
+ label = new Label(topContainer, SWT.LEAD);
+ label.setText(levelString);
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(topContainer, SWT.LEAD);
+ label.setText("\tCurrent value: '" + field.getTextControl().getText() + "'");
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(topContainer, SWT.LEAD);
+ label.setText("\tSubstituted value: '" + this.preferencesService.performSubstitutions(field.getTextControl().getText()) + "'");
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(topContainer, SWT.LEAD);
+ String level = PreferenceDialogConstants.getLevelName(field.getLevelFromWhichLoaded());
+ label.setText("\tLevel at which set: " + level);
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+
+ label = new Label(topContainer, SWT.LEAD);
+ if (field.isEmptyValueAllowed()) {
+ label.setText(PreferenceDialogConstants.EMPTY_OK );
+ } else {
+ label.setText(PreferenceDialogConstants.EMPTY_NOT_OK);
+ }
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(topContainer, SWT.LEAD);
+ if (field.hasSpecialValue()) {
+ label.setText(PreferenceDialogConstants.HAS_SPECIAL + field.getSpecialValue());
+ } else {
+ label.setText(PreferenceDialogConstants.NO_SPECIAL);
+ }
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ if ((field.getPreferencesLevel() != null) && field.getPreferencesLevel().equals(field.getLevelFromWhichLoaded())) {
+ label = new Label(topContainer, SWT.LEAD);
+ if (field.isRemovable()) {
+ label.setText(PreferenceDialogConstants.IS_REMOVABLE);
+ } else {
+ label.setText(PreferenceDialogConstants.NOT_REMOVABLE);
+ }
+ }
+ label.setBackground(PreferencesUtilities.colorWhite);
+
+ label = new Label(top, SWT.LEAD);
+ label.setText("~~~");
+ label.setVisible(false);
+
+
+ this.workArea = workArea;
+ return workArea;
+ }
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/IFileVisitor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/IFileVisitor.java
new file mode 100644
index 000000000..10f950af8
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/IFileVisitor.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.refactoring;
+
+import org.eclipse.core.resources.IFile;
+
+/**
+ *
+ */
+public interface IFileVisitor {
+ public void enterFile(IFile file);
+ public void leaveFile(IFile file);
+} \ No newline at end of file
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/RefactoringStarter.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/RefactoringStarter.java
new file mode 100644
index 000000000..b2095673a
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/RefactoringStarter.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.refactoring;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.ltk.core.refactoring.Refactoring;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
+import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Simple class to wrap the processing flow for user-initiated refactorings.
+ * Copied from a similar class in JDT/UI.
+ * @author rfuhrer
+ */
+public class RefactoringStarter {
+ // TODO re-enable support for the "Save Helper", which had too many claws in the JDT/UI to excise conveniently.
+// private RefactoringSaveHelper fSaveHelper= new RefactoringSaveHelper();
+
+ private RefactoringStatus fStatus;
+
+ public void activate(Refactoring refactoring, RefactoringWizard wizard, Shell parent, String dialogTitle, boolean mustSaveEditors) {
+ if (!canActivate(mustSaveEditors, parent))
+ return;
+ try {
+ RefactoringWizardOpenOperation op= new RefactoringWizardOpenOperation(wizard);
+ int result= op.run(parent, dialogTitle);
+ fStatus= op.getInitialConditionCheckingStatus();
+ if (result == IDialogConstants.CANCEL_ID || result == RefactoringWizardOpenOperation.INITIAL_CONDITION_CHECKING_FAILED)
+ /*fSaveHelper.triggerBuild()*/;
+ } catch (InterruptedException e) {
+ // do nothing. User action got cancelled
+ }
+ }
+
+ public RefactoringStatus getInitialConditionCheckingStatus() {
+ return fStatus;
+ }
+
+ private boolean canActivate(boolean mustSaveEditors, Shell shell) {
+// return !mustSaveEditors || fSaveHelper.saveEditors(shell);
+ return true;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/SourceFileFinder.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/SourceFileFinder.java
new file mode 100644
index 000000000..bf5888073
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/SourceFileFinder.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.refactoring;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.language.ServiceFactory;
+import org.eclipse.imp.model.ISourceProject;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.editors.text.TextFileDocumentProvider;
+import org.eclipse.ui.part.FileEditorInput;
+
+public abstract class SourceFileFinder implements IResourceVisitor {
+ private final TextFileDocumentProvider fProvider;
+
+ protected final ISourceProject fProject;
+
+ protected final IFileVisitor fVisitor;
+
+ protected final Language fLanguage;
+
+ private final Set<String> fFileNameExtensions= new HashSet<String>();
+
+ public SourceFileFinder(TextFileDocumentProvider provider, ISourceProject project, IFileVisitor visitor, Language language) {
+ super();
+ fProvider= provider;
+ fProject= project;
+ fVisitor= visitor;
+ fLanguage= language;
+
+ Language lang= fLanguage;
+
+ // Do we really want to include base language source files? I don't think so...
+ while (lang != null) {
+ for (String ext : lang.getFilenameExtensions()) {
+ fFileNameExtensions.add(ext);
+ }
+ lang= lang.getBaseLanguage();
+ }
+ }
+
+ public boolean visit(IResource resource) throws CoreException {
+ if (resource instanceof IFile) {
+ IFile file= (IFile) resource;
+ if (fFileNameExtensions.contains(file.getFileExtension())) {
+ visitFile(file);
+ }
+ return false;
+ }
+ return true;
+ }
+
+ private void visitFile(IFile file) {
+ System.out.println("Visiting file " + file.getName() + ".");
+ IParseController parseCtrlr= ServiceFactory.getInstance().getParseController(fLanguage);
+ IPath declFilePath= file.getLocation().removeFirstSegments(fProject.getRawProject().getLocation().segmentCount());
+ IFileEditorInput fileInput= new FileEditorInput(file);
+
+ parseCtrlr.initialize(declFilePath, fProject, null);
+ try {
+ fProvider.connect(fileInput);
+ } catch (CoreException e) {
+ e.printStackTrace();
+ return;
+ }
+
+ IDocument document= fProvider.getDocument(fileInput);
+ Object astRoot= parseCtrlr.parse(document.get(), new NullProgressMonitor()); // TODO get a real monitor from somewhere...
+
+ fVisitor.enterFile(file);
+ doVisit(file, document, astRoot);
+ fVisitor.leaveFile(file);
+ }
+
+ public abstract void doVisit(IFile file, IDocument doc, Object astRoot);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/SourceRange.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/SourceRange.java
new file mode 100644
index 000000000..f89aa5be3
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/SourceRange.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.refactoring;
+
+/**
+ * Represents a textual range within some text, expressed as a character offset and a length.
+ */
+public class SourceRange {
+ private final int fOffset;
+ private final int fLength;
+
+ public SourceRange(int off, int len) {
+ fOffset= off;
+ fLength= len;
+ }
+
+ public int getLength() {
+ return fLength;
+ }
+
+ public int getOffset() {
+ return fOffset;
+ }
+
+ public boolean equals(Object o) {
+ if (!(o instanceof SourceRange))
+ return false;
+ SourceRange other= (SourceRange) o;
+ return (fOffset == other.fOffset) && (fLength == other.fLength);
+ }
+
+ public int hashCode() {
+ return 631 + 3191 * fOffset + 4259 * fLength;
+ }
+
+ public String toString() {
+ return "[" + fOffset + ":" + fLength + "]";
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/SourceRangeGroup.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/SourceRangeGroup.java
new file mode 100644
index 000000000..74c8b2213
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/refactoring/SourceRangeGroup.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.refactoring;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+
+/**
+ * Represents a set of <code>SourceRange</code>s in the file corresponding to an <code>IFile</code>.
+ */
+public class SourceRangeGroup {
+ public IFile fFile;
+ public List<SourceRange> fRanges= new ArrayList<SourceRange>();
+
+ public SourceRangeGroup(IFile file) {
+ fFile= file;
+ }
+
+ public void addReference(SourceRange range) {
+ fRanges.add(range);
+ }
+
+ /**
+ * @return Returns the file.
+ */
+ public IFile getFile() {
+ return fFile;
+ }
+
+ public List<SourceRange> getRanges() {
+ return fRanges;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/IPluginLog.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/IPluginLog.java
new file mode 100644
index 000000000..2914c0d58
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/IPluginLog.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+/*
+ * Created on Nov 1, 2005
+ */
+package org.eclipse.imp.runtime;
+
+public interface IPluginLog {
+ public abstract void maybeWriteInfoMsg(String msg);
+
+ public abstract void writeErrorMsg(String msg);
+} \ No newline at end of file
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/ImageDescriptorRegistry.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/ImageDescriptorRegistry.java
new file mode 100644
index 000000000..4e034eecc
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/ImageDescriptorRegistry.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.runtime;
+
+import java.util.HashMap;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.imp.ui.SWTUtil;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * A registry that maps <code>ImageDescriptors</code> to <code>Image</code>.
+ */
+public class ImageDescriptorRegistry {
+ private HashMap<ImageDescriptor,Image> fRegistry= new HashMap<ImageDescriptor,Image>(10);
+
+ private Display fDisplay;
+
+ /**
+ * Creates a new image descriptor registry for the current or default display, respectively.
+ */
+ public ImageDescriptorRegistry() {
+ this(SWTUtil.getStandardDisplay());
+ }
+
+ /**
+ * Creates a new image descriptor registry for the given display. All images managed by this registry will be disposed when the display gets disposed.
+ *
+ * @param display
+ * the display the images managed by this registry are allocated for
+ */
+ public ImageDescriptorRegistry(Display display) {
+ fDisplay= display;
+ Assert.isNotNull(fDisplay);
+ hookDisplay();
+ }
+
+ /**
+ * Returns the image associated with the given image descriptor.
+ *
+ * @param descriptor
+ * the image descriptor for which the registry manages an image
+ * @return the image associated with the image descriptor or <code>null</code> if the image descriptor can't create the requested image.
+ */
+ public Image get(ImageDescriptor descriptor) {
+ if (descriptor == null)
+ descriptor= ImageDescriptor.getMissingImageDescriptor();
+ Image result= (Image) fRegistry.get(descriptor);
+ if (result != null)
+ return result;
+ Assert.isTrue(fDisplay == SWTUtil.getStandardDisplay(), "Allocating image for wrong display."); //$NON-NLS-1$
+ result= descriptor.createImage();
+ if (result != null)
+ fRegistry.put(descriptor, result);
+ return result;
+ }
+
+ /**
+ * Disposes all images managed by this registry.
+ */
+ public void dispose() {
+ for(Image image: fRegistry.values()) {
+ image.dispose();
+ }
+ fRegistry.clear();
+ }
+
+ private void hookDisplay() {
+ fDisplay.disposeExec(new Runnable() {
+ public void run() {
+ dispose();
+ }
+ });
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/PluginBase.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/PluginBase.java
new file mode 100644
index 000000000..ce738dbba
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/PluginBase.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+/*
+ * Created on Nov 1, 2005
+ */
+package org.eclipse.imp.runtime;
+
+import org.eclipse.core.runtime.ILog;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.imp.preferences.PreferencesService;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+public abstract class PluginBase extends AbstractUIPlugin implements IPluginLog {
+ private ILog sLog= null;
+
+ protected boolean fEmitInfoMessages= false;
+
+ public abstract String getID();
+
+ public abstract String getLanguageID();
+
+ public void maybeWriteInfoMsg(String msg) {
+ if (!fEmitInfoMessages)
+ return;
+ if (msg == null) {
+ msg = "No message given";
+ }
+ writeInfoMsg(msg);
+ }
+
+ public void writeInfoMsg(String msg) {
+ if (msg == null)
+ msg = "No message given";
+ Status status= new Status(Status.INFO, getID(), 0, msg, null);
+
+ if (sLog == null)
+ sLog= getLog();
+
+ sLog.log(status);
+ }
+
+ public void writeErrorMsg(String msg) {
+ if (msg == null)
+ msg = "No message given";
+ Status status= new Status(Status.ERROR, getID(), 0, msg, null);
+
+ if (sLog == null)
+ sLog= getLog();
+
+ sLog.log(status);
+ }
+
+ public void logException(String msg, Throwable t) {
+ if (msg == null) {
+ if (t == null || t.getMessage() == null)
+ msg = "No message given";
+ else
+ msg = t.getMessage();
+ }
+
+ Status status= new Status(Status.ERROR, getID(), 0, msg, t);
+
+ if (sLog == null)
+ sLog= getLog();
+
+ sLog.log(status);
+ }
+
+ public void refreshPrefs() {
+ // default: do nothing, no preferences
+ }
+
+ /**
+ * The unique project-independent preferences service for this plugin.
+ * Uses whatever this plugin activator's getLanguageID() method returns as the language.
+ */
+ protected PreferencesService preferencesService = null;
+
+ public PreferencesService getPreferencesService() {
+ if (preferencesService == null) {
+ preferencesService = new PreferencesService();
+ preferencesService.setLanguageName(getLanguageID());
+ // To trigger the automatic invocation of the preferences initializer:
+ try {
+ new DefaultScope().getNode(getID());
+ } catch (Exception e) {
+ // If this ever happens, it will probably be because the preferences
+ // and their initializer haven't been defined yet. In that situation
+ // there's not really anything to do--you can't initialize preferences
+ // that don't exist. So swallow the exception and continue ...
+ }
+ }
+ return preferencesService;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/PluginImages.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/PluginImages.java
new file mode 100644
index 000000000..776859487
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/PluginImages.java
@@ -0,0 +1,218 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.runtime;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.osgi.framework.Bundle;
+
+public class PluginImages {
+ // The plug-in registry
+ private static ImageRegistry fgImageRegistry= null;
+
+ private static Map<String,ImageDescriptor> fgAvoidSWTErrorMap= null;
+
+ public static final IPath ICONS_PATH= new Path("/icons"); //$NON-NLS-1$
+
+ private static final String NAME_PREFIX= ""; //$NON-NLS-1$
+ private static final int NAME_PREFIX_LENGTH= NAME_PREFIX.length();
+
+ public static final String VIEW_MENU_IMAGE= NAME_PREFIX + "view_menu.gif"; //$NON-NLS-1$
+
+ public static final ImageDescriptor viewMenuImageDesc= createManaged(NAME_PREFIX, VIEW_MENU_IMAGE);
+
+ public static final String FILE_IMAGE= NAME_PREFIX + "file.gif"; //$NON-NLS-1$
+
+ public static final ImageDescriptor fileImageDesc= createManaged(NAME_PREFIX, FILE_IMAGE);
+
+ public static final String FOLDER_IMAGE= NAME_PREFIX + "folder.gif"; //$NON-NLS-1$
+
+ public static final ImageDescriptor folderImageDesc= createManaged(NAME_PREFIX, FOLDER_IMAGE);
+
+ public static final String PROJECT_IMAGE= NAME_PREFIX + "project.gif"; //$NON-NLS-1$
+
+ public static final ImageDescriptor projectImageDesc= createManaged(NAME_PREFIX, PROJECT_IMAGE);
+
+ public static final ImageDescriptor DESC_OVR_WARNING= createUnManagedCached(NAME_PREFIX, "warning_co.gif"); //$NON-NLS-1$
+
+ public static final ImageDescriptor DESC_OVR_ERROR= createUnManagedCached(NAME_PREFIX, "error_co.gif"); //$NON-NLS-1$
+
+ private static final class CachedImageDescriptor extends ImageDescriptor {
+ private ImageDescriptor fDescriptor;
+ private ImageData fData;
+
+ public CachedImageDescriptor(ImageDescriptor descriptor) {
+ fDescriptor = descriptor;
+ }
+
+ public ImageData getImageData() {
+ if (fData == null) {
+ fData= fDescriptor.getImageData();
+ }
+ return fData;
+ }
+ }
+
+ /**
+ * Returns the image managed under the given key in this registry.
+ *
+ * @param key the image's key
+ * @return the image managed under the given key
+ */
+ public static Image get(String key) {
+ return getImageRegistry().get(key);
+ }
+
+ /**
+ * Returns the image descriptor for the given key in this registry. Might be called in a non-UI thread.
+ *
+ * @param key the image's key
+ * @return the image descriptor for the given key
+ */
+ public static ImageDescriptor getDescriptor(String key) {
+ if (fgImageRegistry == null) {
+ return fgAvoidSWTErrorMap.get(key);
+ }
+ return getImageRegistry().getDescriptor(key);
+ }
+
+ /**
+ * Sets the three image descriptors for enabled, disabled, and hovered to an action. The actions
+ * are retrieved from the *tool16 folders.
+ *
+ * @param action the action
+ * @param iconName the icon name
+ */
+ public static void setToolImageDescriptors(IAction action, String iconName) {
+ setImageDescriptors(action, "tool16", iconName); //$NON-NLS-1$
+ }
+
+ /**
+ * Sets the three image descriptors for enabled, disabled, and hovered to an action. The actions
+ * are retrieved from the *lcl16 folders.
+ *
+ * @param action the action
+ * @param iconName the icon name
+ */
+ public static void setLocalImageDescriptors(IAction action, String iconName) {
+ setImageDescriptors(action, "lcl16", iconName); //$NON-NLS-1$
+ }
+
+ /*
+ * Helper method to access the image registry from the JavaPlugin class.
+ */
+ /* package */static ImageRegistry getImageRegistry() {
+ if (fgImageRegistry == null) {
+ fgImageRegistry= new ImageRegistry();
+ for(String key: fgAvoidSWTErrorMap.keySet()) {
+ fgImageRegistry.put(key, fgAvoidSWTErrorMap.get(key));
+ }
+ fgAvoidSWTErrorMap= null;
+ }
+ return fgImageRegistry;
+ }
+
+ //---- Helper methods to access icons on the file system --------------------------------------
+ private static void setImageDescriptors(IAction action, String type, String relPath) {
+ ImageDescriptor id= create("d" + type, relPath, false); //$NON-NLS-1$
+ if (id != null)
+ action.setDisabledImageDescriptor(id);
+ /*
+ * id= create("c" + type, relPath, false); //$NON-NLS-1$
+ * if (id != null)
+ * action.setHoverImageDescriptor(id);
+ */
+ ImageDescriptor descriptor= create("e" + type, relPath); //$NON-NLS-1$
+ action.setHoverImageDescriptor(descriptor);
+ action.setImageDescriptor(descriptor);
+ }
+
+ private static ImageDescriptor createManaged(String prefix, String name) {
+ ImageDescriptor result= create(prefix, name.substring(NAME_PREFIX_LENGTH), true);
+ if (fgAvoidSWTErrorMap == null) {
+ fgAvoidSWTErrorMap= new HashMap<String,ImageDescriptor>();
+ }
+ fgAvoidSWTErrorMap.put(name, result);
+ if (fgImageRegistry != null) {
+ RuntimePlugin.getInstance().writeErrorMsg("Image registry already defined"); //$NON-NLS-1$
+ }
+ return result;
+ }
+
+ private static ImageDescriptor createManaged(String prefix, String name, String key) {
+ ImageDescriptor result= create(prefix, name.substring(NAME_PREFIX_LENGTH), true);
+ if (fgAvoidSWTErrorMap == null) {
+ fgAvoidSWTErrorMap= new HashMap<String,ImageDescriptor>();
+ }
+ fgAvoidSWTErrorMap.put(key, result);
+ if (fgImageRegistry != null) {
+ RuntimePlugin.getInstance().writeErrorMsg("Image registry already defined"); //$NON-NLS-1$
+ }
+ return result;
+ }
+
+ /*
+ * Creates an image descriptor for the given prefix and name in the JDT UI bundle and let tye descriptor cache the image data.
+ * If no image could be found, the 'missing image descriptor' is returned.
+ */
+ private static ImageDescriptor createUnManagedCached(String prefix, String name) {
+ return new CachedImageDescriptor(create(prefix, name, true));
+ }
+
+ /*
+ * Creates an image descriptor for the given prefix and name in the JDT UI bundle. The path can
+ * contain variables like $NL$.
+ * If no image could be found, <code>useMissingImageDescriptor</code> decides if either
+ * the 'missing image descriptor' is returned or <code>null</code>.
+ * or <code>null</code>.
+ */
+ private static ImageDescriptor create(String prefix, String name, boolean useMissingImageDescriptor) {
+ IPath path= ICONS_PATH.append(prefix).append(name);
+ return createImageDescriptor(RuntimePlugin.getInstance().getBundle(), path, useMissingImageDescriptor);
+ }
+
+ /*
+ * Creates an image descriptor for the given prefix and name in the JDT UI bundle. The path can
+ * contain variables like $NL$.
+ * If no image could be found, the 'missing image descriptor' is returned.
+ */
+ private static ImageDescriptor create(String prefix, String name) {
+ return create(prefix, name, true);
+ }
+
+ /*
+ * Creates an image descriptor for the given path in a bundle. The path can contain variables
+ * like $NL$.
+ * If no image could be found, <code>useMissingImageDescriptor</code> decides if either
+ * the 'missing image descriptor' is returned or <code>null</code>.
+ * Added for 3.1.1.
+ */
+ public static ImageDescriptor createImageDescriptor(Bundle bundle, IPath path, boolean useMissingImageDescriptor) {
+ URL url= FileLocator.find(bundle, path, null);
+ if (url != null) {
+ return ImageDescriptor.createFromURL(url);
+ }
+ if (useMissingImageDescriptor) {
+ return ImageDescriptor.getMissingImageDescriptor();
+ }
+ return null;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/RuntimePlugin.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/RuntimePlugin.java
new file mode 100644
index 000000000..b8c906a5b
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/runtime/RuntimePlugin.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.runtime;
+
+import java.io.PrintStream;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.imp.language.LanguageRegistry;
+import org.eclipse.imp.model.ISourceEntity;
+import org.eclipse.imp.model.ModelFactory;
+import org.eclipse.imp.model.ModelFactory.ModelException;
+import org.eclipse.imp.preferences.PreferenceCache;
+import org.eclipse.imp.preferences.PreferenceConstants;
+import org.eclipse.imp.utils.ConsoleUtil;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.FontRegistry;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.IStartup;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The bundle activator class for the IMP runtime.
+ */
+public class RuntimePlugin extends PluginBase implements IStartup {
+ /**
+ * An IAdapterFactory implementation that adapts IResources to ISourceEntity's.
+ * @author rfuhrer@watson.ibm.com
+ */
+ private static final class ResourceToSourceEntityAdapter implements IAdapterFactory {
+ private Class[] fTypes= new Class[] { ISourceEntity.class };
+
+ public Object getAdapter(Object adaptableObject, Class adapterType) {
+ if (adaptableObject instanceof IResource && adapterType == ISourceEntity.class) {
+ try {
+ return ModelFactory.open((IResource) adaptableObject);
+ } catch (ModelException e) {
+ RuntimePlugin.getInstance().logException("Unable to adapt " + adaptableObject.getClass().getName() + " to " + adapterType.getName(), e);
+ }
+ }
+ return null;
+ }
+
+ public Class[] getAdapterList() {
+ return fTypes;
+ }
+ }
+
+ private static final String CONSOLE_NAME= "IMP Runtime";
+
+ public static final String IMP_RUNTIME= "org.eclipse.imp.runtime"; // must match plugin ID in MANIFEST.MF
+
+ /**
+ * The (unqualified) ID of the language descriptor extension point.
+ */
+ public static String LANGUAGE_DESCRIPTOR= "languageDescription";
+
+ private FontRegistry fFontRegistry;
+
+ private PrintStream sConsoleStream;
+
+ // The singleton instance.
+ private static RuntimePlugin sPlugin;
+
+ private static boolean EMIT_TIMING_INFO= false;
+
+ public static long PRE_STARTUP_TIME;
+
+ public static long EDITOR_START_TIME;
+
+ public RuntimePlugin() {
+ sPlugin= this;
+ }
+
+ /**
+ * Returns the singleton instance.
+ */
+ public static RuntimePlugin getInstance() {
+ return sPlugin;
+ }
+
+ public String getID() {
+ return IMP_RUNTIME;
+ }
+
+ @Override
+ public String getLanguageID() {
+ return "IMP"; // used only as a preference path prefix
+ }
+
+ public FontRegistry getFontRegistry() {
+ // Hopefully this gets called late enough, i.e., after a Display has been
+ // created on the current thread (see FontRegistry constructor).
+ if (fFontRegistry == null) {
+ fFontRegistry= new FontRegistry();
+ }
+ return fFontRegistry;
+ }
+
+ /**
+ * This method is called upon plug-in activation
+ */
+ public void start(BundleContext context) throws Exception {
+ PRE_STARTUP_TIME= System.currentTimeMillis();
+
+ super.start(context);
+
+ if (EMIT_TIMING_INFO) {
+ getConsoleStream().println("Entered RuntimePlugin.start(); time is " + PRE_STARTUP_TIME);
+ }
+
+ // Initialize the Preferences fields with the preference store data.
+ IPreferenceStore prefStore= getPreferenceStore();
+
+ PreferenceCache.emitMessages= prefStore.getBoolean(PreferenceConstants.P_EMIT_MESSAGES);
+ PreferenceCache.tabWidth= prefStore.getInt(PreferenceConstants.P_TAB_WIDTH);
+
+// PreferenceCache.sourceFont= new Font(PlatformUI.getWorkbench().getDisplay(), PreferenceConverter.getFontData(prefStore, PreferenceConstants.P_SOURCE_FONT));
+
+ Platform.getAdapterManager().registerAdapters(new ResourceToSourceEntityAdapter(), IResource.class);
+ }
+
+ /**
+ * This method is called when the plug-in is stopped
+ */
+ public void stop(BundleContext context) throws Exception {
+ super.stop(context);
+ sPlugin= null;
+ }
+
+ public PrintStream getConsoleStream() {
+ if (sConsoleStream == null) {
+ sConsoleStream= ConsoleUtil.findConsoleStream(CONSOLE_NAME);
+ }
+ return sConsoleStream;
+ }
+
+ /**
+ * Returns an image descriptor for the image file at the given plug-in relative path.
+ *
+ * @param path the path
+ * @return the image descriptor
+ */
+ public static ImageDescriptor getImageDescriptor(String path) {
+ return AbstractUIPlugin.imageDescriptorFromPlugin(IMP_RUNTIME, path);
+ }
+
+ private ImageDescriptorRegistry fImageDescriptorRegistry;
+
+ private synchronized ImageDescriptorRegistry internalGetImageDescriptorRegistry() {
+ if (fImageDescriptorRegistry == null)
+ fImageDescriptorRegistry= new ImageDescriptorRegistry();
+ return fImageDescriptorRegistry;
+ }
+
+ public static ImageDescriptorRegistry getImageDescriptorRegistry() {
+ return getInstance().internalGetImageDescriptorRegistry();
+ }
+
+ public void earlyStartup() {
+ if (EMIT_TIMING_INFO) {
+ final long curTime= System.currentTimeMillis();
+ getConsoleStream().println("Entered RuntimePlugin.earlyStartup(); time is " + curTime);
+ }
+ LanguageRegistry.initializeRegistryAsNeeded();
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/DecorationDescriptor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/DecorationDescriptor.java
new file mode 100644
index 000000000..4ad8cb6be
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/DecorationDescriptor.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+* Copyright (c) 2009 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.language.LanguageRegistry.BundleImageDescriptor;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.osgi.framework.Bundle;
+
+public class DecorationDescriptor {
+ public static enum Quadrant {
+ TOP_LEFT,
+ TOP_RIGHT,
+ BOTTOM_LEFT,
+ BOTTOM_RIGHT
+ }
+
+ /**
+ * the integer attribute value that selects this decoration
+ */
+ public final int mask;
+
+ /**
+ * the bundle containing the image file for this decoration
+ */
+ public final Bundle bundle;
+
+ /**
+ * the Bundle-relative path to the decoration image file
+ */
+ public final String path;
+
+ /**
+ * the quadrant of the base icon image in which the given decoration should be displayed
+ */
+ public final DecorationDescriptor.Quadrant quadrant;
+
+ private ImageDescriptor fImageDesc;
+
+ public DecorationDescriptor(int mask, Bundle bundle, String path, DecorationDescriptor.Quadrant quadrant) {
+ this.mask= mask;
+ this.bundle= bundle;
+ this.path= path;
+ this.quadrant= quadrant;
+ }
+
+ public ImageDescriptor getImageDescriptor() {
+ if (fImageDesc == null) {
+ fImageDesc= new BundleImageDescriptor(path, bundle, "");
+ }
+ return fImageDesc;
+ }
+} \ No newline at end of file
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IASTAdapter.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IASTAdapter.java
new file mode 100644
index 000000000..301982c54
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IASTAdapter.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services;
+
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+/**
+ * @author rfuhrer@watson.ibm.com
+ */
+public interface IASTAdapter extends IASTMatchAdapter {
+ /**
+ * The type of an entity in the target source program, e.g., the declared type of
+ * a variable, or the inferred type of an expression. A construct that does not
+ * produce or declare a value can be considered to have type TARGET_TYPE_VOID.
+ */
+ public static final String TARGET_TYPE= "targetType";
+
+ /**
+ * The name of the AST node type
+ */
+ public static final String KIND= "kind";
+
+ /**
+ * E.g. the name of a method or variable decl/ref
+ */
+ public static final String NAME= "name";
+
+ /**
+ * The void target type (hah! You were probably expecting a more useful JavaDoc comment, weren't you?)
+ */
+ public static final String TARGET_TYPE_VOID= "void";
+
+ /**
+ * @return the name of the child role at the given positional index
+ */
+ public String getChildRoleAtPosition(int pos, String qualNodeType);
+
+ /**
+ * @param roleName refers to a child role, and not a predefined attribute
+ * such as "type" or "kind" (which have no positional index)
+ * @param qualNodeType
+ * @return a positional index, if the roleName is valid
+ * @throws NoSuchElementException if the roleName does not refer to a valid
+ * role for the given AST node type
+ * @throws IllegalArgumentException if the role refers to a predefined attribute
+ * or if the type name is invalid
+ */
+ public int getPositionOfChildRole(String roleName, String qualNodeType);
+
+ /**
+ * @param attributeName refers to a child role or a predefined attribute
+ * such as "type" or "kind"
+ * @return the value of the named attribute for the given AST node
+ * TODO handle "child roles"
+ */
+ public Object getValue(String attributeName, Object astNode);
+
+ /**
+ * @return fully-qualified name of the type with the given simple name
+ */
+ public String lookupSimpleNodeType(String simpleName);
+
+ /**
+ * @return true iff the given AST node is of the given named type, which
+ * must be fully-qualified
+ */
+ public boolean isInstanceOfType(Object astNode, String typeName);
+
+ /**
+ * @return true iff the given AST node type is a sub-type of the given named
+ * type <code>maybeSub</code>, which must be fully-qualified
+ */
+ public boolean isSubTypeOf(String maybeSuper, String maybeSub);
+
+ /**
+ * @return the type of AST node for the given AST node, which is suitable
+ * for use with, e.g., isInstanceOfType()
+ */
+ public String getTypeOf(Object astNode);
+
+ /**
+ * @param qualName the fully-qualified name of the AST node type to construct
+ * @param children array of child AST nodes (even if certain "children" may
+ * not be AST nodes in the target AST representation)
+ * @return newly-constructed AST node
+ */
+ public Object construct(String qualName, Object[] children) throws IllegalArgumentException;
+
+ /**
+ * @param qualName the fully-qualified name of the AST node type to construct
+ * @param children array of child AST nodes (even if certain "children" may
+ * not be AST nodes in the target AST representation)
+ * @param attribs map from attribute names to attribute values
+ * @return newly-constructed AST node
+ */
+ public Object construct(String qualName, Object[] children, Map/*<String,Object>*/ attribs) throws IllegalArgumentException;
+
+ /**
+ * Finds the previous match using the given Matcher occurring before the given offset.<br>
+ * This is essentially a wrapper for the AST traversal surrounding the matching
+ * process. For each node, the implementation should call <code>matcher.match()</code>
+ * to actually perform the match.
+ * @param matcher the matcher to use (encapsulates the pattern)
+ * @param astRoot the top of the AST tree to search
+ * @param startPos the character at which to begin the search
+ * @return the first non-null MatchContext returned by <code>matcher.match()</code>, if any;
+ * otherwise, null
+ */
+ // RMF 5/1/2006 - Don't know how to do this easily, given that the visitor
+ // implementation essentially traverses the AST in order of increasing offset...
+// public MatchContext findPreviousMatch(Matcher matcher, Object astRoot, int offset);
+
+ /**
+ * If the AST node is a meta variable, return its name.
+ */
+ public abstract String getMetaVariableName(Object astNode);
+
+ /**
+ * Returns the file path of the file containing the
+ * source text corresponding to the given AST node <code>astNode</code>.
+ * The path will be the same as what was provided to the AST creator
+ * (e.g. the parser).
+ */
+ public String getFile(Object astNode);
+
+ /**
+ * Returns the length in characters (not bytes) of the source text
+ * corresponding to the given AST node <code>astNode</code>.
+ */
+ public int getLength(Object astNode);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IASTFindReplaceTarget.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IASTFindReplaceTarget.java
new file mode 100644
index 000000000..6d1dffe5b
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IASTFindReplaceTarget.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.swt.graphics.Point;
+
+public interface IASTFindReplaceTarget {
+ String getSelectionText();
+
+ boolean isEditable();
+
+ /**
+ * x coordinate is offset of start of selection, y coordinate is length of selection
+ */
+ Point getSelection();
+
+ boolean canPerformFind();
+
+ IParseController getParseController();
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IASTMatchAdapter.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IASTMatchAdapter.java
new file mode 100644
index 000000000..c01a7eaf5
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IASTMatchAdapter.java
@@ -0,0 +1,36 @@
+package org.eclipse.imp.services;
+
+public interface IASTMatchAdapter {
+
+ /**
+ * @return the value of the child of the given AST node at the given position
+ */
+ public abstract Object getChildAtPosition(int pos, Object astNode);
+
+ /**
+ * @return a possibly empty array of immediate children of the given AST node
+ * <code>astNode</code> in positional order
+ */
+ public abstract Object[] getChildren(Object astNode);
+
+ /**
+ * Returns the character offset (not the byte offset) of the first character of
+ * source text corresponding to the given AST node <code>astNode</code>.
+ */
+ public abstract int getOffset(Object astNode);
+
+ /**
+ * Returns a boolean value indicating whether or not this AST node is
+ * a meta variable (placeholder) for a real AST node. This is used for matching AST patterns
+ * against real AST's.
+ */
+ public abstract boolean isMetaVariable(Object astNode);
+
+ /**
+ * Returns a boolean value indicating whether or not this AST is to be
+ * considered a list. A list node that a varyadic number of children, as
+ * opposed to a normal AST node which has a fixed number of children.
+ */
+ public abstract boolean isList(Object astNode);
+
+} \ No newline at end of file
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IAnnotationHover.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IAnnotationHover.java
new file mode 100644
index 000000000..f9c3d1e19
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IAnnotationHover.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.language.ILanguageService;
+
+public interface IAnnotationHover extends
+ org.eclipse.jface.text.source.IAnnotationHover, ILanguageService {
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IAnnotationTypeInfo.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IAnnotationTypeInfo.java
new file mode 100644
index 000000000..6cca9885e
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IAnnotationTypeInfo.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.services;
+
+import java.util.List;
+
+/**
+ * Operations related to the management of marker types that may be
+ * provided by clients of the parse controller; may be used by cooperating
+ * clients, e.g., editors and builders, to share marker types.
+ *
+ * This is probably a temporary expedient until a more general scheme
+ * of marker management across IDE services can be developed.
+ * @author suttons@us.ibm.com
+ */
+public interface IAnnotationTypeInfo {
+ /**
+ * Add a type of problem marker to the list of problem marker
+ * types to which errors generated by this parser may correspond.
+ *
+ * @param problemMarkerType The name of the problem marker type
+ */
+ public void addProblemMarkerType(String problemMarkerType);
+
+ /**
+ * Provide the list of problem marker types to which errors
+ * generated by this parser may correspond.
+ *
+ * @return The list of problem marker types
+ */
+ public List<String> getProblemMarkerTypes();
+
+ /**
+ * Remove a type of problem marker from the list of problem marker
+ * types to which errors generated by this parser may correspond.
+ *
+ * @param problemMarkerType The name of the problem marker type
+ */
+ public void removeProblemMarkerType(String problemMarkerType);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IAutoEditStrategy.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IAutoEditStrategy.java
new file mode 100644
index 000000000..a5fc7cf5c
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IAutoEditStrategy.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.language.ILanguageService;
+
+public interface IAutoEditStrategy extends
+ org.eclipse.jface.text.IAutoEditStrategy, ILanguageService {
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IContentProposer.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IContentProposer.java
new file mode 100644
index 000000000..d36ca6e63
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IContentProposer.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+
+/*
+ * Licensed Materials - Property of IBM,
+ * (c) Copyright IBM Corp. 1998, 2004 All Rights Reserved
+ */
+
+
+/**
+ * This interface is to be implemented by contributors to the org.eclipse.imp.runtime.contentProposer extension point.
+ * The Universal IDE Editor will locate a suitable parser for the language being edited.
+ * The result of the parser, an Ast describing the syntactical elements in the input, is cached
+ * and used when the mouse is hovered over elements in the editor.
+ *
+ * @author Claffra
+ */
+public interface IContentProposer extends ILanguageService {
+
+ public ICompletionProposal[] getContentProposals(IParseController controller, int offset, ITextViewer viewer);
+
+} \ No newline at end of file
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IDocumentationProvider.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IDocumentationProvider.java
new file mode 100644
index 000000000..d74d996d2
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IDocumentationProvider.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+/*
+ * Created on Mar 8, 2007
+ */
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.imp.parser.IParseController;
+
+public interface IDocumentationProvider extends ILanguageService {
+ String getDocumentation(Object target, IParseController parseController);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IEditorService.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IEditorService.java
new file mode 100644
index 000000000..ad0b5073c
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IEditorService.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+* Copyright (c) 2008 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Stan Sutton (suttons@us.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.editor.UniversalEditor;
+import org.eclipse.imp.parser.IModelListener;
+
+public interface IEditorService
+ extends IModelListener
+{
+
+ public String getName();
+
+ public void setEditor(UniversalEditor editor);
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IEntityImageDecorator.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IEntityImageDecorator.java
new file mode 100644
index 000000000..74a87b504
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IEntityImageDecorator.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+* Copyright (c) 2009 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+package org.eclipse.imp.services;
+
+
+public interface IEntityImageDecorator {
+ /**
+ * @return an array containing DecorationDescriptors for all possible decoration attributes
+ */
+ public DecorationDescriptor[] getAllDecorations();
+
+ /**
+ * @return a bit-wise OR of the decoration attributes for the given entity.
+ * The implementation is free to define the set of valid attributes,
+ * though their range is restricted to what will fit in a 32-bit int.
+ */
+ int getDecorationAttributes(Object entity);
+} \ No newline at end of file
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IEntityNameLocator.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IEntityNameLocator.java
new file mode 100644
index 000000000..5803aaff9
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IEntityNameLocator.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+* Copyright (c) 2009 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.language.ILanguageService;
+
+public interface IEntityNameLocator extends ILanguageService {
+ Object getName(Object srcEntity);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IFoldingUpdater.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IFoldingUpdater.java
new file mode 100644
index 000000000..9e5b962b7
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IFoldingUpdater.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
+
+public interface IFoldingUpdater extends ILanguageService {
+ void updateFoldingStructure(IParseController parseController, ProjectionAnnotationModel annotationModel);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IHelpService.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IHelpService.java
new file mode 100644
index 000000000..9a5eb7474
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IHelpService.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+* Copyright (c) 2008 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.jface.text.IRegion;
+
+public interface IHelpService extends ILanguageService {
+ /**
+ * Returns the language-specific context appropriate for the given base context,
+ * if any. A language-specific
+ * implementation should return a context appropriate for the language.
+ * Note that the IContext can refer to related topics, including that of
+ * the IMP editor, by means of the getRelatedTopics() method.
+ * @param part an IMP-related part for which help has been requested
+ * @return
+ */
+ String getContextId(String baseContextId);
+
+ /**
+ * Typically called when a structured (non-textual) view has focus.
+ * @param target an AST node, ISourceEntity, or other program entity
+ * @return the help text for the given entity, possibly HTML formatted
+ */
+ String getHelp(Object target, IParseController parseController);
+
+ /**
+ * Typically called when a textual view has focus.
+ * @param target a selected text region for which help was requested
+ * @return the help text for the given entity, possibly HTML formatted
+ */
+ String getHelp(IRegion target, IParseController parseController);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IHoverHelper.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IHoverHelper.java
new file mode 100644
index 000000000..180ed8e45
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IHoverHelper.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.jface.text.source.ISourceViewer;
+
+/*
+ * Licensed Materials - Property of IBM,
+ * (c) Copyright IBM Corp. 1998, 2004 All Rights Reserved
+ */
+
+/**
+ * This interface is to be implemented by contributors to the org.eclipse.imp.runtime.hoverHelp extension point.
+ * The Universal IDE Editor will locate a suitable parser for the language being edited.
+ * The result of the parser, an Ast describing the syntactical elements in the input, is cached
+ * and used when the mouse is hovered over elements in the editor.
+ *
+ * @author Claffra
+ */
+public interface IHoverHelper extends ILanguageService {
+
+ /**
+ * Provide language-specific hover help for the token at the given offset.
+ *
+ * @param model the result from the parser (contains an Ast)
+ * @param offset the offset in the original input stream
+ * @return a human-readable text string describing what the element at the given offset
+ */
+ public String getHoverHelpAt(IParseController parseController, ISourceViewer viewer, int offset);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IIdentityMapper.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IIdentityMapper.java
new file mode 100644
index 000000000..c0d8b2c5c
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IIdentityMapper.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.language.ILanguageService;
+
+/**
+ * This interface represents a service that translates between program entities
+ * and unique, persistable keys.
+ * @author rfuhrer
+ */
+public interface IIdentityMapper extends ILanguageService {
+ /**
+ * Maps the given program entity to its corresponding key.
+ * The key must be unique within the workspace containing the given
+ * program entity.<br>
+ * The key may be a String, but if not, its toString() implementation
+ * must satisfy the following constraint:<br>
+ * <code>key1.equals(key2) iff key1.toString().equals(key2.toString())</code><br>
+ * Also, the key must remain valid when persisted/serialized and restored.
+ * However, there is no guarantee that it still refers to an existing entity
+ * when retrieved from a persistent store (e.g., it is permissible that an
+ * index containing a key may fall out of date).
+ * @param entity a program entity, e.g. a compilation unit, a type, a
+ * method, an expression, etc.
+ * @return the key that uniquely represents the given program entity.
+ */
+ Object getKeyFor(Object entity);
+
+ /**
+ * @return the program entity corresponding to the given key
+ */
+ Object getEntityFor(Object key);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ILabelProvider.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ILabelProvider.java
new file mode 100644
index 000000000..86dee126e
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ILabelProvider.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.language.ILanguageService;
+
+public interface ILabelProvider extends
+ org.eclipse.jface.viewers.ILabelProvider, ILanguageService {
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ILanguageActionsContributor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ILanguageActionsContributor.java
new file mode 100644
index 000000000..691c39e40
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ILanguageActionsContributor.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+/**
+ *
+ */
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.editor.UniversalEditor;
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.action.IToolBarManager;
+
+public interface ILanguageActionsContributor extends ILanguageService {
+
+
+ /**
+ * Implement this method to add any kind of action to the popup
+ * menu of an editor.
+ *
+ * @param editor
+ * @param menuManager
+ */
+ public void contributeToEditorMenu(final UniversalEditor editor, IMenuManager menuManager);
+
+ /**
+ * Implement this method to add any kind of element to the toolbar
+ * for this editor.
+ *
+ * @param editor
+ * @param toolbarManager
+ */
+ public void contributeToToolBar(final UniversalEditor editor, IToolBarManager toolbarManager);
+
+
+ /**
+ * Implement this method to add any kind of element to the statusline
+ * for this editor.
+ *
+ * @param editor
+ * @param toolbarManager
+ */
+ public void contributeToStatusLine(final UniversalEditor editor, IStatusLineManager statusLineManager);
+
+ /**
+ * Implement this method to add any kind of element to the menu bar
+ * for this editor.
+ *
+ * @param editor
+ * @param toolbarManager
+ */
+ public void contributeToMenuBar(final UniversalEditor editor, IMenuManager menu);
+} \ No newline at end of file
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ILanguageSyntaxProperties.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ILanguageSyntaxProperties.java
new file mode 100644
index 000000000..c795e51b1
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ILanguageSyntaxProperties.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.language.ILanguageService;
+
+/**
+ * Describes certain syntactic properties of the language used in support of certain editor features, such
+ * as toggling comments, fence matching, and so on.
+ * @author rfuhrer@watson.ibm.com
+ */
+public interface ILanguageSyntaxProperties extends ILanguageService {
+ /**
+ * if null, the language has no single-line comment syntax
+ * @return
+ */
+ public String getSingleLineCommentPrefix();
+
+ /**
+ * @return the character sequence that starts a block comment, if the language has syntax for that, else null
+ */
+ public String getBlockCommentStart();
+
+ /**
+ * @return the character sequence for a line in the middle of a block comment, if the language has syntax
+ * for that, else null
+ */
+ public String getBlockCommentContinuation();
+
+ /**
+ * @return the character sequence that ends a block comment, if the language has syntax for that, else null
+ */
+ public String getBlockCommentEnd();
+
+ /**
+ * If -1, there is no comment column
+ */
+// public int getSingleLineCommentColumn();
+
+ /**
+ * If -1, there is no continuation column
+ */
+// public int getLineContinuationColumn();
+
+ /**
+ * @return an array of arrays each containing a balanced pair
+ * of fence Strings, e.g.:
+ * [ [ "[" "]" ] ["(" ")" ] [ "{" "}" ] [ "/." "./" ]
+ */
+ public String[][] getFences();
+
+ /**
+ * @return the set of characters that are legal in an identifier in this language
+ */
+ public String getIdentifierConstituentChars();
+
+ /**
+ * @param ident an identifier
+ * @return the ordered set of character offsets to the individual components (e.g. words) of an identifier.
+ * May be null.
+ */
+ public int[] getIdentifierComponents(String ident);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IOccurrenceMarker.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IOccurrenceMarker.java
new file mode 100644
index 000000000..a76676b79
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IOccurrenceMarker.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services;
+
+import java.util.List;
+
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.imp.parser.IParseController;
+
+public interface IOccurrenceMarker extends ILanguageService {
+ /**
+ * @return the user-readable name of the kind of occurrence.
+ */
+ public String getKindName();
+
+ /**
+ * @param entity the AST node representing the given entity
+ * @return the list of AST nodes representing occurrences of the given entity
+ * in the same file as the entity.
+ */
+ public List<Object> getOccurrencesOf(IParseController parseCtrlr, Object entity);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IOutlineImage.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IOutlineImage.java
new file mode 100644
index 000000000..8e0bd571c
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IOutlineImage.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services;
+
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+
+public interface IOutlineImage {
+
+ public String getImageRoot();
+ //public static final String IMAGE_ROOT= "icons";
+
+ public ImageDescriptor getOutlineItemDesc();
+ //public static ImageDescriptor OUTLINE_ITEM_DESC= AbstractUIPlugin.imageDescriptorFromPlugin("leg", IMAGE_ROOT + "/outline_item.gif");
+
+ public Image getOutlineItemImage();
+ //public static Image OUTLINE_ITEM_IMAGE= OUTLINE_ITEM_DESC.createImage();
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IOutliner.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IOutliner.java
new file mode 100644
index 000000000..4eca8073a
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IOutliner.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/*
+ * Licensed Materials - Property of IBM,
+ * (c) Copyright IBM Corp. 1998, 2004 All Rights Reserved
+ */
+
+
+/**
+ * This interface is to be implemented by contributors to the org.eclipse.imp.runtime.outliner extension point.
+ * The Universal IDE Editor will locate a suitable parser for the language being edited.
+ * The result of the parser, an Ast describing the syntactical elements in the input, is cached
+ * and used to show an outline view of the elements in the editor.
+ *
+ * @author Claffra
+ */
+public interface IOutliner extends ILanguageService {
+
+ /**
+ * Create a language-specific outline presentation for the parse result.
+ *
+ * @param model the result from the parser (contains an Ast)
+ * @param offset current offset of the caret in the editor
+ */
+ void createOutlinePresentation(IParseController controller, int offset);
+
+ /**
+ * Set the editor that currently controls the outline view
+ * @param editor
+ */
+ void setEditor(ITextEditor editor);
+
+
+ /**
+ * Set the tree widget that contains the outline view. The tree is fully managed by this IOutliner instance.
+ * @param tree
+ */
+ void setTree(Tree tree);
+} \ No newline at end of file
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IRefactoringContributor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IRefactoringContributor.java
new file mode 100644
index 000000000..46e7d79e2
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IRefactoringContributor.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+/**
+ *
+ */
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.editor.UniversalEditor;
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.jface.action.IAction;
+
+public interface IRefactoringContributor extends ILanguageService {
+ public IAction[] getEditorRefactoringActions(UniversalEditor editor);
+} \ No newline at end of file
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IReferenceResolver.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IReferenceResolver.java
new file mode 100644
index 000000000..8ef693206
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IReferenceResolver.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.imp.parser.IParseController;
+
+
+/**
+ * Specifies methods to support the construction of hyperlinks between
+ * AST nodes.
+ *
+ * @author sutton
+ *
+ */
+public interface IReferenceResolver extends ILanguageService {
+
+ /**
+ * Returns the AST node that represents the target of a hyperlink that
+ * has the given AST node as a source and that is interpreted in the
+ * context of the AST represented by the given parse controller.
+ *
+ * Normally the source and target nodes should both occur in the AST
+ * represented by the given parse controller.
+ *
+ * @param node The AST node to be considered as the source
+ * of a hyperlink
+ * @param parseController The parse controller that contains the AST with
+ * respect to which the link is defined
+ * @return The AST node that is the target of the hyperlink,
+ * if found, or null if no target node has been found
+ */
+ public Object getLinkTarget(Object node, IParseController parseController);
+
+
+ /**
+ * Returns a text string to be associated with a hyperlink.
+ *
+ * Historical note: So far in practice we have obtained the link
+ * text from the source node. This method may also be used with the
+ * target node. If a need arises, we can add another method that
+ * would take two nodes. SMS 13 Jun 2006.
+ *
+ * @param node The node with respect to which the link text is
+ * to be determined
+ * @return The link text determined with respect to the
+ * given node.
+ */
+ public String getLinkText(Object node);
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ISourceFormatter.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ISourceFormatter.java
new file mode 100644
index 000000000..a2df1ddaa
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ISourceFormatter.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.imp.parser.IParseController;
+
+/**
+ * Essentially the same as IFormattingStrategy, but the format() method
+ * takes an IParseController as an argument, so that the language-specific
+ * formatter has access to an AST to drive formatting decisions.
+ * @author Dr. Robert M. Fuhrer
+ */
+public interface ISourceFormatter extends ILanguageService {
+ void formatterStarts(String initialIndentation);
+
+ String format(IParseController parseController, String content, boolean isLineStart, String indentation, int[] positions);
+
+ void formatterStops();
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ISourceHyperlinkDetector.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ISourceHyperlinkDetector.java
new file mode 100644
index 000000000..cf5772cdc
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ISourceHyperlinkDetector.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+/*
+ * Created on Feb 8, 2006
+ */
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+public interface ISourceHyperlinkDetector extends ILanguageService {
+ IHyperlink[] detectHyperlinks(IRegion region, ITextEditor editor, ITextViewer textViewer, IParseController parseController);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IToggleBreakpointsHandler.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IToggleBreakpointsHandler.java
new file mode 100644
index 000000000..0faf4265f
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/IToggleBreakpointsHandler.java
@@ -0,0 +1,15 @@
+package org.eclipse.imp.services;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.imp.language.ILanguageService;
+
+public interface IToggleBreakpointsHandler extends ILanguageService {
+ void clearLineBreakpoint(IFile file, int lineNumber) throws CoreException;
+ void setLineBreakpoint(IFile file, int lineNumber) throws CoreException;
+ void disableLineBreakpoint(IFile file, int lineNumber) throws CoreException;
+ void enableLineBreakpoint(IFile file, int lineNumber) throws CoreException;
+
+ // TODO
+ //void toggleEntryBreakpoint(IFile file, int lineNumber);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ITokenColorer.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ITokenColorer.java
new file mode 100644
index 000000000..51b408604
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/ITokenColorer.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services;
+
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.TextAttribute;
+
+/*
+ * Licensed Materials - Property of IBM,
+ * (c) Copyright IBM Corp. 2005 All Rights Reserved
+ */
+
+/**
+ */
+public interface ITokenColorer extends ILanguageService {
+ /**
+ * @param seed the nominal damage area
+ * @return a possibly expanded region of damage
+ */
+ public IRegion calculateDamageExtent(IRegion seed, IParseController ctlr);
+
+ /**
+ * Provide coloring and font to use for a given token in the model.
+ * @param model The model that contains the token
+ * @param token The token to be colored
+ * @return a TextAttribute
+ */
+ public TextAttribute getColoring(IParseController controller, Object token);
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/DefaultAnnotationHover.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/DefaultAnnotationHover.java
new file mode 100644
index 000000000..09fe0e69b
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/DefaultAnnotationHover.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services.base;
+
+import java.util.List;
+
+import org.eclipse.imp.utils.AnnotationUtils;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.ISourceViewer;
+
+public class DefaultAnnotationHover implements IAnnotationHover {
+ /**
+ * @see IVerticalRulerHover#getHoverInfo(ISourceViewer, int)
+ */
+ public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
+ List annotations= AnnotationUtils.getAnnotationsForLine(sourceViewer, lineNumber);
+
+ return AnnotationUtils.formatAnnotationList(annotations);
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/DefaultAutoIndentStrategy.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/DefaultAutoIndentStrategy.java
new file mode 100644
index 000000000..3226068d8
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/DefaultAutoIndentStrategy.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+* Copyright (c) 2008 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Stan Sutton (suttons@us.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+
+
+package org.eclipse.imp.services.base;
+
+import org.eclipse.imp.services.IAutoEditStrategy;
+import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
+
+
+/**
+ * Essentially copied from org.eclipse.jface.text.DefaultAutoIndentStrategy
+ * but implementing an interface that is not deprecated.
+ *
+ * Provides a default implementation that always copies the indentation
+ * of the previous line.
+ *
+ * @author sutton
+ *
+ */
+
+public class DefaultAutoIndentStrategy
+ extends DefaultIndentLineAutoEditStrategy implements IAutoEditStrategy
+{
+
+ /**
+ * Creates a new default auto indent strategy.
+ */
+ public DefaultAutoIndentStrategy() {
+ }
+
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/DefaultLanguageActionsContributor.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/DefaultLanguageActionsContributor.java
new file mode 100644
index 000000000..fb3abf720
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/DefaultLanguageActionsContributor.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+* Copyright (c) 2008
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Jurgen Vinju (jurgenv@cwi.nl) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.services.base;
+
+import org.eclipse.imp.editor.UniversalEditor;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.imp.services.ILanguageActionsContributor;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+
+public class DefaultLanguageActionsContributor implements ILanguageActionsContributor {
+
+ /**
+ * Override this method to add any kind of action to the popup
+ * menu of an editor. The default implementation uses
+ * the deprecated getEditorActions method to provide backward compatibility.
+ *
+ * @param editor
+ * @param menuManager
+ */
+ public void contributeToEditorMenu(final UniversalEditor editor, IMenuManager menuManager) {
+ IMenuManager subMenu = new MenuManager(editor.fLanguage.getName());
+
+ try {
+ IAction[] actions = getEditorActions(editor);
+
+ if (actions != null && actions.length > 0) {
+ for (IAction action : actions) {
+ subMenu.add(action);
+ }
+
+ menuManager.add(subMenu);
+ }
+ }
+ catch (Exception e) {
+ RuntimePlugin.getInstance().logException(
+ "Unable to create language actions for contributor "
+ + this, e);
+ }
+ }
+
+ public void contributeToStatusLine(final UniversalEditor editor, IStatusLineManager statusLineManager) {
+ // do nothing, subclasses can override to implement
+ }
+
+ public void contributeToToolBar(final UniversalEditor editor, IToolBarManager toolbarManager) {
+ // do nothing, subclasses can override to implement
+ }
+
+ public void contributeToMenuBar(final UniversalEditor editor, IMenuManager menuManager) {
+ // do nothing, subclasses can override to implement
+ }
+
+ /**
+ * Implement this method to add actions to a submenu labelled by the
+ * language name.
+ *
+ * @deprecated use contributeToEditorMenu() instead
+ * @param editor
+ * @return
+ */
+ @Deprecated()
+ public IAction[] getEditorActions(UniversalEditor editor) {
+ return null;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/DefaultOutlineImage.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/DefaultOutlineImage.java
new file mode 100644
index 000000000..858baf724
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/DefaultOutlineImage.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services.base;
+
+import org.eclipse.imp.services.IOutlineImage;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+
+
+public class DefaultOutlineImage implements IOutlineImage
+{
+ private DefaultOutlineImage() { }
+
+ private static IOutlineImage image = null;
+
+ public static IOutlineImage getDefaultOutlineImage() {
+ if (image == null) {
+ image = new DefaultOutlineImage();
+ }
+ return image;
+ }
+
+
+ private static final String IMAGE_ROOT= "icons";
+
+ private static ImageDescriptor OUTLINE_ITEM_DESC= AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.imp.runtime", IMAGE_ROOT + "/outline_item.gif");
+
+ private static Image OUTLINE_ITEM_IMAGE= OUTLINE_ITEM_DESC.createImage();
+
+
+ public String getImageRoot() {
+ return IMAGE_ROOT;
+ }
+
+ public ImageDescriptor getOutlineItemDesc() {
+ return OUTLINE_ITEM_DESC;
+ }
+
+ public Image getOutlineItemImage() {
+ return OUTLINE_ITEM_IMAGE;
+ }
+
+}
+
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/EditorServiceBase.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/EditorServiceBase.java
new file mode 100644
index 000000000..9bb831855
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/EditorServiceBase.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+* Copyright (c) 2008 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Stan Sutton (suttons@us.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+
+package org.eclipse.imp.services.base;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.imp.editor.UniversalEditor;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.services.IEditorService;
+
+public abstract class EditorServiceBase implements IEditorService {
+
+ protected String name = null;
+
+ protected UniversalEditor editor = null;
+
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+
+ public void setEditor(UniversalEditor editor) {
+ this.editor = editor;
+ }
+
+ public UniversalEditor getEditor() {
+ return editor;
+ }
+
+
+ /**
+ * @return A value from the enumeration IModelListener.AnalysisREquired,
+ * reflecting the dependence of the implementation of this
+ * service on other analyses that need to be performed
+ * before this one can be executed correctly
+ */
+ public abstract AnalysisRequired getAnalysisRequired();
+
+
+ /**
+ * This method will be called when the AST maintained by the parseController
+ * has been updated (subject to the completion of analyses on which this
+ * service depends and on the apparent availability of time in which to
+ * perform this analysis)
+ */
+ public abstract void update(IParseController parseController, IProgressMonitor monitor);
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/FolderBase.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/FolderBase.java
new file mode 100644
index 000000000..9659fa761
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/FolderBase.java
@@ -0,0 +1,256 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services.base;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.imp.core.ErrorHandler;
+import org.eclipse.imp.parser.ISourcePositionLocator;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.imp.services.IFoldingUpdater;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
+
+
+/**
+ * FolderBase is an abstract base type for a source-text folding service.
+ * It is intended to support extensions for language-specific folders.
+ * The class is abstract only with respect to a method that sends a
+ * visitor to an AST, as both the visitor and AST node types are language
+ * specific.
+ *
+ * @author suttons@us.ibm.com
+ * @author rfuhrer@watson.ibm.com
+ */
+public abstract class FolderBase implements IFoldingUpdater {
+ // For recording annotations
+
+ // Maps new annotations to positions
+ protected HashMap<Annotation,Position> newAnnotations = new HashMap<Annotation, Position>();
+
+ // Lists the new annotations, which are the keys for newAnnotations
+ protected List<Annotation> annotations = new ArrayList<Annotation>();
+
+ protected IParseController parseController = null;
+
+ // Used to support checking of whether annotations have
+ // changed between invocations of updateFoldingStructure
+ // (because, if they haven't, then it's probably best not
+ // to update the folding structure)
+ private ArrayList<Annotation> oldAnnotationsList = null;
+ private Annotation[] oldAnnotationsArray;
+
+ protected boolean fDebugMode = false;
+
+ // Methods to make annotations will typically be called by visitor methods
+ // in the language-specific concrete subtype
+
+ /**
+ * Make a folding annotation that corresponds to the extent of text
+ * represented by a given program entity. Usually, this will be an
+ * AST node, but it can be anything for which the language's
+ * ISourcePositionLocator can produce an offset/end offset.
+ *
+ * @param n an Object representing a program entity
+ */
+ public void makeAnnotation(Object n) {
+ ISourcePositionLocator nodeLocator = parseController.getSourcePositionLocator();
+ int startOffset = 0;
+ int endOffset = 0;
+
+ try {
+ startOffset = nodeLocator.getStartOffset(n);
+ endOffset = nodeLocator.getEndOffset(n);
+ } catch (Exception e) {
+ RuntimePlugin.getInstance().logException("Error while attempting to determine position of a foldable source entity", e);
+ return;
+ }
+ makeAnnotation(startOffset, endOffset-startOffset+1);
+ }
+
+ /**
+ * Make a folding annotation that corresponds to the given range of text.
+ *
+ * @param start The starting offset of the text range
+ * @param len The length of the text range
+ */
+ public void makeAnnotation(int start, int len) {
+ if (fDebugMode) {
+ PrintStream cons= RuntimePlugin.getInstance().getConsoleStream();
+ cons.println("Adding folding annotation for extent [" + start + ":" + len + "]");
+ }
+ ProjectionAnnotation annotation= new ProjectionAnnotation();
+ newAnnotations.put(annotation, new Position(start, len));
+ annotations.add(annotation);
+ }
+
+ /**
+ * Update the folding structure for a source text, where the text and its
+ * AST are represented by a given parse controller and the folding structure
+ * is represented by annotations in a given annotation model.
+ *
+ * This is the principal routine of the folding updater.
+ *
+ * The implementation provided here makes use of a local class
+ * FoldingUpdateStrategy, to which the task of updating the folding
+ * structure is delegated.
+ *
+ * updateFoldingStructure is synchronized because, at least on file opening,
+ * it can be called more than once before the first invocation has completed.
+ * This can lead to inconsistent calculations resulting in the absence of
+ * folding annotations in newly opened files.
+ *
+ * @param parseController A parse controller through which the AST for
+ * the source text can be accessed
+ * @param annotationModel A structure of projection annotations that
+ * represent the foldable elements in the source
+ * text
+ */
+ public synchronized void updateFoldingStructure(
+ IParseController parseController, ProjectionAnnotationModel annotationModel)
+ {
+ if (fDebugMode) {
+ PrintStream cons= RuntimePlugin.getInstance().getConsoleStream();
+ cons.println("Collecting folding annotations");
+ }
+ if (parseController != null)
+ this.parseController = parseController;
+
+ try {
+ Object ast = parseController.getCurrentAst();
+
+ if (ast == null) {
+ // We can't create annotations without an AST
+ return;
+ }
+
+ // But, since here we have the AST ...
+ sendVisitorToAST(newAnnotations, annotations, ast);
+
+ // Update the annotation model if there have been changes
+ // but not otherwise (since update leads to redrawing of the
+ // source in the editor, which is likely to be unwelcome if
+ // there haven't been any changes relevant to folding)
+ boolean updateNeeded = false;
+ if (oldAnnotationsList == null) {
+ // Should just be the first time through
+ updateNeeded = true;
+ } else {
+ // Check to see whether the current and previous annotations
+ // differ in any significant way; if not, then there's no
+ // reason to update the annotation model.
+ // Note: This test may be implemented in various ways that may
+ // be more or less simple, efficient, correct, etc. (The
+ // default test provided below is simplistic although quick and
+ // usually effective.)
+ updateNeeded = differ(oldAnnotationsList, annotations);
+ }
+ if (updateNeeded) {
+ // Save the current annotations to compare for changes the next time
+ oldAnnotationsList = new ArrayList<Annotation>();
+ for (int i = 0; i < annotations.size(); i++) {
+ oldAnnotationsList.add(annotations.get(i));
+ }
+ } else {
+ }
+
+ // Need to curtail calls to modifyAnnotations() because these lead to calls
+ // to fireModelChanged(), which eventually lead to calls to updateFoldingStructure,
+ // which lead back here, which would lead to another call to modifyAnnotations()
+ // (unless those were curtailed)
+ if (updateNeeded) {
+ annotationModel.modifyAnnotations(oldAnnotationsArray, newAnnotations, null);
+ // Capture the latest set of annotations in a form that can be used the next
+ // time that it is necessary to modify the annotations
+ oldAnnotationsArray = (Annotation[]) annotations.toArray(new Annotation[annotations.size()]);
+ } else {
+ }
+
+ newAnnotations.clear();
+ annotations.clear();
+ } catch (Exception e) {
+ ErrorHandler.reportError("FolderBase.updateFoldingStructure: EXCEPTION", e);
+ }
+ }
+
+
+ /**
+ * A method to test whether there has been a significant change in the folding
+ * annotations for a source text. The method works by comparing two lists of
+ * annotations, nominally the "old" and "new" annotations. It returns true iff
+ * there is considered to be a "significant" difference in the two lists, where
+ * the meaning of "significant" is defined by the implementation of this method.
+ *
+ * The default implementation provided here is a simplistic test of the difference
+ * between two lists, considering only their size. This may work well enough much
+ * of the time as the comparisons between lists should be made very frequently,
+ * actually more frequently than the rate at which the typical human user will
+ * edit the program text so as to affect the AST so as to affect the lists. Thus
+ * most changes of lists will entail some change in the number of elements at some
+ * point that will be observed here. This will not work for certain very rapid
+ * edits of source text (e.g., rapid replacement of elements).
+ *
+ * This method should be overridden in language-specific implementations of the
+ * folding updater where a more sophisticated test is desired.
+ *
+ * @param list1 A list of annotations (nominally the "old" annotations)
+ * @param list2 A list of annotations (nominally the "new" annotations)
+ * @return true iff there has been a "significant" difference in the
+ * two given lists of annotations
+ *
+ */
+ protected boolean differ(List<Annotation> list1, List<Annotation> list2) {
+ if (list1.size() != list2.size()) {
+ return true;
+ }
+ return false;
+ }
+
+
+
+ /**
+ * Send a visitor to an AST representing a program in order to construct the
+ * folding annotations. Both the visitor type and the AST node type are language-
+ * dependent, so this method is abstract.
+ *
+ * @param newAnnotations A map of annotations to text positions
+ * @param annotations A listing of the annotations in newAnnotations, that is,
+ * a listing of keys to the map of text positions
+ * @param ast An Object that will be taken to represent an AST node
+ */
+ protected abstract void sendVisitorToAST(HashMap<Annotation,Position> newAnnotations, List<Annotation> annotations, Object ast);
+
+
+
+ protected void dumpAnnotations(final List<Annotation> annotations, final HashMap<Annotation,Position> newAnnotations)
+ {
+ for(int i= 0; i < annotations.size(); i++) {
+ Annotation a= (Annotation) annotations.get(i);
+ Position p= (Position) newAnnotations.get(a);
+
+ if (p == null) {
+ System.out.println("Annotation position is null");
+ continue;
+ }
+
+ System.out.println("Annotation @ " + p.offset + ":" + p.length);
+ }
+ }
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/HoverHelperBase.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/HoverHelperBase.java
new file mode 100644
index 000000000..41b96fa6f
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/HoverHelperBase.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services.base;
+
+import org.eclipse.imp.editor.UniversalEditor;
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.services.IHoverHelper;
+
+/**
+
+ *
+ * @author suttons@us.ibm.com
+ * Updates:
+ * SMS 12 Aug 2007:
+ */
+public abstract class HoverHelperBase implements IHoverHelper
+{
+
+ protected UniversalEditor fEditor = null;
+
+ protected Language fLanguage = null;
+
+ public void setEditor(UniversalEditor editor) {
+ fEditor = editor;
+ }
+
+ public void setLanguage(Language language) {
+ fLanguage = language;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/LPGASTMatchAdapterBase.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/LPGASTMatchAdapterBase.java
new file mode 100644
index 000000000..1fac81e4e
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/LPGASTMatchAdapterBase.java
@@ -0,0 +1,45 @@
+package org.eclipse.imp.services.base;
+
+import lpg.runtime.IAst;
+import lpg.runtime.IToken;
+
+import org.eclipse.imp.services.IASTMatchAdapter;
+
+public abstract class LPGASTMatchAdapterBase implements IASTMatchAdapter {
+ private final Class<?> fNodeListBaseClass;
+
+ public LPGASTMatchAdapterBase(Class<?> nodeListBaseClass) {
+ fNodeListBaseClass= nodeListBaseClass;
+ }
+
+ public Object[] getChildren(Object astNode) {
+ return ((IAst) astNode).getChildren().toArray();
+ }
+
+ public int getOffset(Object astNode) {
+ return ((IAst) astNode).getLeftIToken().getStartOffset();
+ }
+
+ public int getLength(Object astNode) {
+ IAst ast = (IAst) astNode;
+ IToken left = ast.getLeftIToken();
+ IToken right = ast.getRightIToken();
+
+ // special case for epsilon trees
+ if (left.getTokenIndex() > right.getTokenIndex()) {
+ return 0;
+ } else {
+ int start = left.getStartOffset();
+ int end = right.getEndOffset();
+ return end - start + 1;
+ }
+ }
+
+ public Object getChildAtPosition(int pos, Object astNode) {
+ return ((IAst) astNode).getChildren().get(pos);
+ }
+
+ public boolean isList(Object astNode) {
+ return fNodeListBaseClass.isInstance(astNode);
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/LPGFolderBase.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/LPGFolderBase.java
new file mode 100644
index 000000000..413f1620a
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/LPGFolderBase.java
@@ -0,0 +1,79 @@
+package org.eclipse.imp.services.base;
+
+import java.util.List;
+
+import lpg.runtime.Adjunct;
+import lpg.runtime.IAst;
+import lpg.runtime.ILexStream;
+import lpg.runtime.IPrsStream;
+import lpg.runtime.IToken;
+
+public abstract class LPGFolderBase extends FolderBase {
+ protected IPrsStream prsStream;
+
+ protected void makeFoldableByOffsets(int first_offset, int last_offset) {
+ super.makeAnnotation(first_offset, last_offset - first_offset + 1);
+ }
+
+ //
+ // Use this version of makeAnnotation when you have a range of
+ // tokens to fold.
+ //
+ protected void makeFoldable(IToken first_token, IToken last_token) {
+ if (last_token.getEndLine() > first_token.getLine()) {
+ ILexStream lexStream = prsStream.getILexStream();
+ int start = first_token.getStartOffset();
+ int end = last_token.getEndOffset();
+
+ // Following may be necessary if one edits an empty source file; there
+ // may be an AST with an empty textual extent, which causes Position()
+ // a heartache.
+ if (end <= start) {
+ return;
+ }
+
+ while (end < lexStream.getStreamLength() && (lexStream.getCharValue(end) == ' ' || lexStream.getCharValue(end) == '\t')) {
+ end++;
+ }
+ // For some reason, simply testing against Character.LINE_SEPARATOR here doesn't work.
+ if (end < lexStream.getStreamLength()-1 && (lexStream.getCharValue(end+1) == '\n' || lexStream.getCharValue(end+1) == '\r')) {
+ end++;
+ }
+
+ makeFoldableByOffsets(start, end);
+ }
+ }
+
+ protected void makeFoldable(IAst n) {
+ makeFoldable(n.getLeftIToken(), n.getRightIToken());
+ }
+
+ protected void makeAdjunctsFoldable() {
+ ILexStream lexStream = prsStream.getILexStream();
+ if (lexStream == null)
+ return;
+ List<IToken> adjuncts = prsStream.getAdjuncts();
+ for (int i = 0; i < adjuncts.size(); ) {
+ Adjunct adjunct = (Adjunct) adjuncts.get(i);
+
+ IToken previous_token = prsStream.getIToken(adjunct.getTokenIndex()),
+ next_token = prsStream.getIToken(prsStream.getNext(previous_token.getTokenIndex())),
+ comments[] = previous_token.getFollowingAdjuncts();
+
+ for (int k = 0; k < comments.length; k++)
+ {
+ Adjunct comment = (Adjunct) comments[k];
+ if (comment.getEndLine() > comment.getLine())
+ {
+ IToken gate_token = k + 1 < comments.length ? comments[k + 1] : next_token;
+ makeFoldableByOffsets(comment.getStartOffset(),
+ gate_token.getLine() > comment.getEndLine()
+ ? lexStream.getLineOffset(gate_token.getLine() - 1)
+ : comment.getEndOffset());
+ }
+ }
+
+ i += comments.length;
+ }
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/OutlinerBase.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/OutlinerBase.java
new file mode 100644
index 000000000..01263cf60
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/OutlinerBase.java
@@ -0,0 +1,462 @@
+/*******************************************************************************
+* Copyright (c) 2007,2008 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.services.base;
+
+import java.util.List;
+import java.util.Stack;
+
+import lpg.runtime.IPrsStream;
+import lpg.runtime.IToken;
+
+import org.eclipse.imp.core.ErrorHandler;
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.parser.ISourcePositionLocator;
+import org.eclipse.imp.parser.SimpleLPGParseController;
+import org.eclipse.imp.services.IOutlineImage;
+import org.eclipse.imp.services.IOutliner;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * OutlinerBase is an abstract base type for a source-text outlining service.
+ * It is intended to support extensions for language-specific outliners.
+ * It is adapted from DefaultOutliner by Chris Laffra, but whereas that was
+ * intended to provide an operational implementation of a generic outliner,
+ * OutlinerBase explicitly requires completion by language-specific outliner
+ * implementations. This class is actually abstract only with respect to
+ * a method that sends a visitor to an AST, as both the visitor and AST types
+ * are language-specific.
+ *
+ * @see org.eclipse.imp.defaults.DefaultOutliner
+ *
+ * @author suttons@us.ibm.com
+ * Updates:
+ * SMS 21 Jun 2007: Added guards on array indices computed in comparing
+ * individual tokens
+ * @deprecated Please consider providing a TreeContentProvider
+ */
+public abstract class OutlinerBase implements IOutliner
+{
+ protected IParseController fParseController;
+
+ public void setEditor(ITextEditor editor) { }
+
+ protected Tree tree;
+
+ protected class TreeSelectionListener implements SelectionListener
+ {
+ public TreeSelectionListener() {
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ TreeItem ti= (TreeItem) e.item;
+ Object data= ti.getData();
+ // data is assumed to be an instance of an AST node in some
+ // language-specific type
+
+ if (data == null) {
+ System.out.println("Wiget selected for outline item with no node; returning");
+ return;
+ }
+
+ // It's actually possible (if not probable) that the outlining service will be invoked
+ // by the editor so soon in the initialization of a workspace that the following composite
+ // call will fail (e.g., due to null values returned at various points). However, execution
+ // of this method depends on the selection of a widget, which requires that the ActivePage,
+ // ActiveWorkbenchWindow, etc. be established. So for the outliner, this sequence of calls
+ // is not a problem in practice.
+ IEditorPart activeEditor= PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
+ ITextEditor textEditor= (ITextEditor) activeEditor;
+ ISourcePositionLocator nodeLocator = fParseController.getSourcePositionLocator();
+ int startOffset = 0;
+ int endOffset = 0;
+
+ try {
+ // The methods of nodeLocator typically take an object and cast it
+ // to an ASTNode type without any concern for what it actually is,
+ // so try that here and catch any exception that is thrown
+ startOffset = nodeLocator.getStartOffset(data);
+ endOffset = nodeLocator.getEndOffset(data);
+ } catch (ClassCastException x) {
+ System.err.println("OutlinerBase.TreeSelectionListener.wigetSelected: " +
+ "ClassCastException trying to treat event data as AST node type");
+ return;
+ }
+
+ textEditor.selectAndReveal(startOffset, endOffset-startOffset+1);
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) { }
+ }
+
+
+ public void setTree(Tree tree) {
+ this.tree = tree;
+ this.tree.addSelectionListener(new TreeSelectionListener());
+ }
+
+
+
+ /*
+ * Fields and methods for representing and manipulating
+ * the stack of outline items
+ */
+
+ private Stack<TreeItem> fItemStack = new Stack<TreeItem>();
+
+
+ public void pushTopItem(String itemName, Object node) {
+ fItemStack.push(createTopItem(itemName, node));
+ }
+
+
+ public void pushTopItem(String itemName, Object node, IOutlineImage image) {
+ fItemStack.push(createTopItem(itemName, node, image));
+ }
+
+
+ public void pushTopItem(String itemName, Object node, IOutlineImage image, int style) {
+ fItemStack.push(createTopItem(itemName, node, image, style));
+ }
+
+
+
+ public void pushSubItem(String itemName, Object node) {
+ fItemStack.push(createSubItem(itemName, node));
+ }
+
+
+ public void pushSubItem(String itemName, Object node, IOutlineImage image) {
+ fItemStack.push(createSubItem(itemName, node, image));
+ }
+
+
+
+ public void pushSubItem(String itemName, Object node, IOutlineImage image, int style) {
+ fItemStack.push(createSubItem(itemName, node, image, style));
+ }
+
+
+ public void popSubItem() {
+ fItemStack.pop();
+ }
+
+ public void addSubItem(String label, Object node) {
+ createSubItem(label, node);
+ }
+
+ public void addSubItem(String label, Object node, IOutlineImage image) {
+ createSubItem(label, node, image);
+ }
+
+ public void addSubItem(String label, Object node, IOutlineImage image, int style) {
+ createSubItem(label, node, image, style);
+ }
+
+ /*
+ * Following are two pairs of methods, one for creating new top-level
+ * items, and one for creating new sub items, in the outline tree.
+ * The first method of each pair has been hoisted from the outline
+ * template and modified to reference a default outline image (to break
+ * the dependence on a language-specific image). The second method of
+ * each pair is analogous to the first but takes an IOutlineImage
+ * to allow language-specific images to be provided.
+ *
+ * (Note: IOutlineImage and DefaultOutlineImage were newly created
+ * to enable this refactoring.)
+ */
+
+ public TreeItem createTopItem(String label, Object n) {
+ TreeItem treeItem= new TreeItem(tree, SWT.NONE);
+ treeItem.setText(label);
+ treeItem.setImage(DefaultOutlineImage.getDefaultOutlineImage().getOutlineItemImage());
+ if (n != null)
+ treeItem.setData(n);
+ return treeItem;
+ }
+
+ public TreeItem createTopItem(String label, Object n, IOutlineImage image) {
+ TreeItem treeItem= new TreeItem(tree, SWT.NONE);
+ treeItem.setText(label);
+ treeItem.setImage(image.getOutlineItemImage());
+ if (n != null)
+ treeItem.setData(n);
+ return treeItem;
+ }
+
+
+ public TreeItem createTopItem(String label, Object n, IOutlineImage image, int style) {
+ TreeItem treeItem= new TreeItem(tree, style);
+ treeItem.setText(label);
+ treeItem.setImage(image.getOutlineItemImage());
+ if (n != null)
+ treeItem.setData(n);
+ return treeItem;
+}
+
+
+
+ public TreeItem createSubItem(String label, Object n) {
+ TreeItem treeItem= new TreeItem((TreeItem) fItemStack.peek(), SWT.NONE);
+ treeItem.setText(label);
+ if (n != null)
+ treeItem.setData(n);
+ treeItem.setImage(DefaultOutlineImage.getDefaultOutlineImage().getOutlineItemImage());
+ return treeItem;
+ }
+
+
+ public TreeItem createSubItem(String label, Object n, IOutlineImage image) {
+ TreeItem treeItem= new TreeItem((TreeItem) fItemStack.peek(), SWT.NONE);
+ treeItem.setText(label);
+ if (n != null)
+ treeItem.setData(n);
+ treeItem.setImage(image.getOutlineItemImage());
+ return treeItem;
+ }
+
+
+ public TreeItem createSubItem(String label, Object n, IOutlineImage image, int style) {
+ TreeItem treeItem= new TreeItem((TreeItem) fItemStack.peek(), style);
+ treeItem.setText(label);
+ if (n != null)
+ treeItem.setData(n);
+ treeItem.setImage(image.getOutlineItemImage());
+// int itemStyle = treeItem.getStyle();
+ return treeItem;
+ }
+
+
+
+ /**
+ * Create the outline tree representing the AST associated with a given
+ * parse controller. There are two issues of particular concern in the
+ * design of this method: observing the appropriate UI protocol for
+ * redrawing the tree, and filtering out unwanted invocations that
+ * reflect events that should probably not trigger a redrawing of the tree.
+ *
+ * Regarding the protocol for redrawing the tree, it seems that calls to
+ * tree.setRedraw(true) must be balanced by calls to tree.setRedraw(false).
+ * This is because of logic in org.eclipse.swt.widgets.Control, the parent
+ * class of org.eclipse.swt.widgets.TreeItem. If there are excessive calls
+ * to tree.setRedraw(true) then the outline view can become "stuck" on a
+ * particular file; that is, when a new editor is opened or brought to
+ * the foreground, the outline view continues to show the outline for a
+ * previous file. The implementation provided here generally assures,
+ * insofar as possible, that the calls to tree.setRedraw(true) and to
+ * tree.setRedraw(false) are balanced, even in the face of exceptions.
+ * If the logic of this method is modified, care should be taken to assure
+ * that this balance is maintained.
+ *
+ * Regarding unwanted invocations, this method may be called even when
+ * the AST represented has not changed and thus when redrawing of
+ * the outline may be unnecessary. Unnecessary redrawing of the outline
+ * is probably a negligable inefficiency in most cases, but redrawing has
+ * the effect of collapsing an expanded outline, which can be annoying
+ * for users. Folding of the source text in an editor is one case in which
+ * this method is called when there is no change to the underlying AST.
+ * The implementation provided here includes a test for "significantChange"
+ * and avoids redrawing the outline when no significant change has occurred.
+ * The provided version of significantChange(..) tracks changes to the
+ * whole tree, the number of tokens, and the text associated with individual
+ * tokens. Users who want to use an alternative definition of "significant
+ * change" should reimplement the change-detection strategy type.
+ *
+ * @param controller A parse controller from which an AST can be obtained
+ * to serve as the basis of an outline presentation
+ *
+ * @param offset Currently ignored; kept for backward compatibility
+ *
+ * @return void Has no return but has the effect of (re)drawing
+ * an outline tree based on the AST obtained from the
+ * given parse controller, if possible.
+ *
+ * Has no effect under a variety of problematic
+ * conditions: given parse controller is null, outline
+ * tree is null, parse controller has errors, or parse
+ * controller's current AST is null. Also has no
+ * effect if there is no "significant change" from the
+ * the AST on the previous invocation to the AST on this
+ * invocation.
+ *
+ * @exception Throws none; traps all exceptions and reports an
+ * error.
+ */
+ public void createOutlinePresentation(IParseController controller, int offset)
+ {
+ if (controller == null || tree == null) return;
+ if (!significantChange(controller)) return;
+
+ fParseController= controller;
+ boolean redrawSetFalse = false;
+ try {
+ Object root= controller.getCurrentAst();
+ if (root == null) return;
+
+ // SMS 4 Dec 2007: added guard
+ if (!tree.isDisposed()) {
+ tree.setRedraw(false);
+ redrawSetFalse = true;
+ tree.removeAll();
+ }
+ fItemStack.clear();
+ sendVisitorToAST(root);
+ } catch (Throwable e) {
+ ErrorHandler.reportError("Exception generating outlinel", e);
+ } finally {
+ if (redrawSetFalse) {
+ tree.setRedraw(true);
+ }
+ }
+ }
+
+
+
+ /*
+ * To hold in a generic way any data that the method "significantChange(..)"
+ * may require from one invocation to the next.
+ */
+ private Object[] previous = null;
+
+ /**
+ * This method is intended to detect whether there has been a significant
+ * change in the AST represented by the given controller (presumably such
+ * that the outline should be redrawn).
+ *
+ * The default implementation returns true if and only if the parse controller
+ * has changed (implying a different parse stream and token stream in any case)
+ * or, for an unchanged parse controller, if there has been a change in the
+ * number, size, or content of tokens in the current token stream. Note that,
+ * by this definition, changes in white space between tokens are not considered
+ * significant.
+ *
+ * This method should be overridden in subclasses to implement
+ * language-specific tests.
+ *
+ * @param controller Provides access to the AST represented in the outline
+ * @return Whether there has been a significant change in the
+ * AST (by default TRUE)
+ */
+ protected boolean significantChange(IParseController controller) {
+ // TODO: Override this in the language-specific outliner,
+ // adopting a language-specific change-detection strategy as
+ // appropriate
+ //return true;
+
+ boolean previousWasNull = previous == null;
+ boolean result = false;
+
+ // Check for previous values being null (as in uninitialized)
+ if (previousWasNull) {
+ // create and initialize previous
+ previous = new Object[3];
+ for (int i = 0; i < previous.length; i++) {
+ previous[i] = null;
+ }
+
+ // check for current and previous controllers both null
+ if (controller == null) {
+ return false;
+ }
+ }
+
+ // If here then had some previous values (although these
+ // could individually be null); is current controller null?
+ if (controller == null) {
+ for (int i = 0; i < previous.length; i++) {
+ if (previous[i] == null) continue; // not changed
+ result = true; // changed
+ previous[i] = null; // null now
+ }
+ return result;
+ }
+
+ // If here then had some previous values and have some current
+ // values; these need to be compared
+ // (for simplicity assume that current values are not null)
+
+ // Get current values for comparison to previous
+ final IPrsStream parseStream= ((SimpleLPGParseController) controller).getParser().getIPrsStream();
+ List tokens = parseStream.getTokens();
+ char[] chars = parseStream.getInputChars();
+
+ // Get previous values for comparison to current
+ IParseController previousController = (IParseController) previous[0];
+ List previousTokens = (List) previous[1];
+ char[] previousChars = (char[]) previous[2];
+
+ // Update previous values to current values in any case (now that
+ // we've saved previous in local fields)
+ previous[0] = controller;
+ previous[1] = tokens;
+ previous[2] = chars;
+
+ // Compare current and previous values; return true if different
+
+ // Are the whole trees different? (Assume so if controllers differ)
+ if (previousController != controller) return true;
+
+ // Are the sizes of the trees different?
+ if (previousTokens.size() != tokens.size()) {
+ return true;
+ }
+
+ // Are any of the individual tokens different?
+ for (int i = 0; i < previousTokens.size()-1; i++) {
+ IToken previousToken = (IToken)previousTokens.get(i);
+ IToken token = (IToken)tokens.get(i);
+ if (previousToken.getKind() != token.getKind()) {
+ //System.out.println("Previous and current tokens differ at token # = " + i);
+ return true;
+ }
+ int previousStart = previousToken.getStartOffset();
+ int previousEnd = previousToken.getEndOffset();
+ int start = token.getStartOffset();
+ int end = token.getEndOffset();
+ if ((previousEnd - previousStart) != (end - start)) {
+ // System.out.println("Previous and current tokens have different extents at token # = " + i);
+ return true;
+ }
+ for (int j = 0; j < (previousEnd - previousStart + 1); j++) {
+ if (previousStart+j < previousChars.length && start+j < chars.length) {
+ if ((previousChars.length != 0) && previousChars[previousStart+j] != chars[start+j]) {
+ // System.out.println("Previous and current tokens have different characters at token # = " + i +
+ // ", character # = " + j);
+ return true;
+ }
+ }
+ }
+ }
+
+ // No significant differences found
+ return false;
+
+ }
+
+ /**
+ * Intended to treat the given Object as the root of an AST to which an
+ * outline visitor should be sent. Both the AST node and the implicit visitor
+ * are presumed to be language-specific types that will be known in a subclass
+ * of this class.
+ *
+ * @param node Presumably the root of an AST of some language-specific
+ * type
+ */
+ protected abstract void sendVisitorToAST(Object node);
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/TokenColorerBase.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/TokenColorerBase.java
new file mode 100644
index 000000000..deb5b844f
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/TokenColorerBase.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services.base;
+
+import org.eclipse.imp.parser.IParseController;
+import org.eclipse.imp.services.ITokenColorer;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Display;
+
+public abstract class TokenColorerBase implements ITokenColorer {
+ protected TextAttribute keywordAttribute;
+
+ public TokenColorerBase() {
+ this(new TextAttribute(Display.getDefault().getSystemColor(SWT.COLOR_DARK_MAGENTA), null, SWT.BOLD));
+ }
+
+ public TokenColorerBase(TextAttribute keywordAttribute) {
+ this.keywordAttribute = keywordAttribute;
+ }
+
+ public TextAttribute getColoring(IParseController controller, Object token) {
+// switch (token.getKind()) {
+// default:
+// if (isKeyword(token.getKind(), controller))
+// return keywordAttribute;
+// else
+ return null;
+// }
+ }
+
+ public IRegion calculateDamageExtent(IRegion seed, IParseController ctlr) {
+ return seed;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/TreeModelBuilderBase.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/TreeModelBuilderBase.java
new file mode 100644
index 000000000..26ebd955e
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/services/base/TreeModelBuilderBase.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.services.base;
+
+import java.util.Stack;
+
+import org.eclipse.imp.core.ErrorHandler;
+import org.eclipse.imp.editor.ModelTreeNode;
+import org.eclipse.imp.language.ILanguageService;
+
+public abstract class TreeModelBuilderBase implements ILanguageService {
+ protected ModelTreeNode fModelRoot;
+
+ private Stack<ModelTreeNode> fItemStack= new Stack<ModelTreeNode>();
+
+ public final ModelTreeNode buildTree(Object rootASTNode) {
+ fItemStack.push(fModelRoot= createTopItem(new ModelTreeNode(rootASTNode)));
+ try {
+ visitTree(rootASTNode);
+ } catch (Exception e) {
+ ErrorHandler.reportError("Exception caught from invocation of language-specific tree model builder implementation", e);
+ }
+ fItemStack.pop();
+ return fModelRoot;
+ }
+
+ protected abstract void visitTree(Object root);
+
+ protected ModelTreeNode createTopItem(Object n) {
+ return createTopItem(n, ModelTreeNode.DEFAULT_CATEGORY);
+ }
+
+ protected ModelTreeNode createTopItem(Object n, int category) {
+ ModelTreeNode treeNode= new ModelTreeNode(n, category);
+ return treeNode;
+ }
+
+ protected ModelTreeNode createSubItem(Object n) {
+ return createSubItem(n, ModelTreeNode.DEFAULT_CATEGORY);
+ }
+
+ protected ModelTreeNode createSubItem(Object n, int category) {
+ final ModelTreeNode parent= fItemStack.peek();
+ ModelTreeNode treeNode= new ModelTreeNode(n, parent, category);
+
+ parent.addChild(treeNode);
+ return treeNode;
+ }
+
+ protected ModelTreeNode pushSubItem(Object n) {
+ return pushSubItem(n, ModelTreeNode.DEFAULT_CATEGORY);
+ }
+
+ protected ModelTreeNode pushSubItem(Object n, int category) {
+ return fItemStack.push(createSubItem(n, category));
+ }
+
+ protected void popSubItem() {
+ fItemStack.pop();
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/DefaultPartListener.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/DefaultPartListener.java
new file mode 100644
index 000000000..822ee0fcb
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/DefaultPartListener.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+* Copyright (c) 2008
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Jurgen Vinju (jurgenv@cwi.nl) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.ui;
+
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IWorkbenchPart;
+
+public class DefaultPartListener implements IPartListener {
+
+ public void partActivated(IWorkbenchPart part) {
+// override this
+ }
+
+ public void partBroughtToTop(IWorkbenchPart part) {
+// override this
+ }
+
+ public void partClosed(IWorkbenchPart part) {
+// override this
+ }
+
+ public void partDeactivated(IWorkbenchPart part) {
+// override this
+ }
+
+ public void partOpened(IWorkbenchPart part) {
+// override this
+ }
+
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/PixelConverter.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/PixelConverter.java
new file mode 100644
index 000000000..5bff78c3f
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/PixelConverter.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.ui;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.widgets.Control;
+
+public class PixelConverter {
+ private FontMetrics fFontMetrics;
+
+ public PixelConverter(Control control) {
+ GC gc= new GC(control);
+ gc.setFont(control.getFont());
+ fFontMetrics= gc.getFontMetrics();
+ gc.dispose();
+ }
+
+ /**
+ * see org.eclipse.jface.dialogs.DialogPage#convertHeightInCharsToPixels(int)
+ */
+ public int convertHeightInCharsToPixels(int chars) {
+ return Dialog.convertHeightInCharsToPixels(fFontMetrics, chars);
+ }
+
+ /**
+ * see org.eclipse.jface.dialogs.DialogPage#convertHorizontalDLUsToPixels(int)
+ */
+ public int convertHorizontalDLUsToPixels(int dlus) {
+ return Dialog.convertHorizontalDLUsToPixels(fFontMetrics, dlus);
+ }
+
+ /**
+ * see org.eclipse.jface.dialogs.DialogPage#convertVerticalDLUsToPixels(int)
+ */
+ public int convertVerticalDLUsToPixels(int dlus) {
+ return Dialog.convertVerticalDLUsToPixels(fFontMetrics, dlus);
+ }
+
+ /**
+ * see org.eclipse.jface.dialogs.DialogPage#convertWidthInCharsToPixels(int)
+ */
+ public int convertWidthInCharsToPixels(int chars) {
+ return Dialog.convertWidthInCharsToPixels(fFontMetrics, chars);
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/SWTUtil.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/SWTUtil.java
new file mode 100644
index 000000000..1f8874529
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/SWTUtil.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+*******************************************************************************/
+
+package org.eclipse.imp.ui;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DragSource;
+import org.eclipse.swt.dnd.DropTarget;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Caret;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.ScrollBar;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * Utility class to simplify access to some SWT resources.
+ */
+public class SWTUtil {
+ /**
+ * Returns the standard display to be used. The method first checks, if the thread calling this method has an associated display. If so, this display is
+ * returned. Otherwise the method returns the default display.
+ */
+ public static Display getStandardDisplay() {
+ Display display;
+ display= Display.getCurrent();
+ if (display == null)
+ display= Display.getDefault();
+ return display;
+ }
+
+ /**
+ * Returns the shell for the given widget. If the widget doesn't represent a SWT object that manage a shell, <code>null</code> is returned.
+ *
+ * @return the shell for the given widget
+ */
+ public static Shell getShell(Widget widget) {
+ if (widget instanceof Control)
+ return ((Control) widget).getShell();
+ if (widget instanceof Caret)
+ return ((Caret) widget).getParent().getShell();
+ if (widget instanceof DragSource)
+ return ((DragSource) widget).getControl().getShell();
+ if (widget instanceof DropTarget)
+ return ((DropTarget) widget).getControl().getShell();
+ if (widget instanceof Menu)
+ return ((Menu) widget).getParent().getShell();
+ if (widget instanceof ScrollBar)
+ return ((ScrollBar) widget).getParent().getShell();
+ return null;
+ }
+
+ /**
+ * Returns a width hint for a button control.
+ */
+ public static int getButtonWidthHint(Button button) {
+ button.setFont(JFaceResources.getDialogFont());
+ PixelConverter converter= new PixelConverter(button);
+ int widthHint= converter.convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
+ return Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
+ }
+
+ /**
+ * Sets width and height hint for the button control. <b>Note:</b> This is a NOP if the button's layout data is not an instance of <code>GridData</code>.
+ *
+ * @param button
+ * the button for which to set the dimension hint
+ */
+ public static void setButtonDimensionHint(Button button) {
+ Assert.isNotNull(button);
+ Object gd= button.getLayoutData();
+ if (gd instanceof GridData) {
+ ((GridData) gd).widthHint= getButtonWidthHint(button);
+ ((GridData) gd).horizontalAlignment= GridData.FILL;
+ }
+ }
+
+ public static int getTableHeightHint(Table table, int rows) {
+ if (table.getFont().equals(JFaceResources.getDefaultFont()))
+ table.setFont(JFaceResources.getDialogFont());
+ int result= table.getItemHeight() * rows + table.getHeaderHeight();
+ if (table.getLinesVisible())
+ result+= table.getGridLineWidth() * (rows - 1);
+ return result;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/HTML2TextReader.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/HTML2TextReader.java
new file mode 100644
index 000000000..5da8deda9
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/HTML2TextReader.java
@@ -0,0 +1,326 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.imp.ui.textPresentation;
+
+import java.io.IOException;
+import java.io.PushbackReader;
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+
+import org.eclipse.jface.text.TextPresentation;
+
+//import org.eclipse.jdt.internal.ui.JavaUIMessages;
+
+
+/**
+ * Reads the text contents from a reader of HTML contents and translates
+ * the tags or cut them out.
+ */
+public class HTML2TextReader extends SubstitutionTextReader {
+
+ private static final String EMPTY_STRING= ""; //$NON-NLS-1$
+ private static final Map fgEntityLookup;
+ private static final Set fgTags;
+
+ static {
+
+ fgTags= new HashSet();
+ fgTags.add("b"); //$NON-NLS-1$
+ fgTags.add("br"); //$NON-NLS-1$
+ fgTags.add("br/"); //$NON-NLS-1$
+ fgTags.add("div"); //$NON-NLS-1$
+ fgTags.add("h1"); //$NON-NLS-1$
+ fgTags.add("h2"); //$NON-NLS-1$
+ fgTags.add("h3"); //$NON-NLS-1$
+ fgTags.add("h4"); //$NON-NLS-1$
+ fgTags.add("h5"); //$NON-NLS-1$
+ fgTags.add("p"); //$NON-NLS-1$
+ fgTags.add("dl"); //$NON-NLS-1$
+ fgTags.add("dt"); //$NON-NLS-1$
+ fgTags.add("dd"); //$NON-NLS-1$
+ fgTags.add("li"); //$NON-NLS-1$
+ fgTags.add("ul"); //$NON-NLS-1$
+ fgTags.add("pre"); //$NON-NLS-1$
+ fgTags.add("head"); //$NON-NLS-1$
+
+ fgEntityLookup= new HashMap(7);
+ fgEntityLookup.put("lt", "<"); //$NON-NLS-1$ //$NON-NLS-2$
+ fgEntityLookup.put("gt", ">"); //$NON-NLS-1$ //$NON-NLS-2$
+ fgEntityLookup.put("nbsp", " "); //$NON-NLS-1$ //$NON-NLS-2$
+ fgEntityLookup.put("amp", "&"); //$NON-NLS-1$ //$NON-NLS-2$
+ fgEntityLookup.put("circ", "^"); //$NON-NLS-1$ //$NON-NLS-2$
+ fgEntityLookup.put("tilde", "~"); //$NON-NLS-2$ //$NON-NLS-1$
+ fgEntityLookup.put("quot", "\""); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ private int fCounter= 0;
+ private TextPresentation fTextPresentation;
+ private int fBold= 0;
+ private int fStartOffset= -1;
+ private boolean fInParagraph= false;
+ private boolean fIsPreformattedText= false;
+ private boolean fIgnore= false;
+
+ /**
+ * Transforms the HTML text from the reader to formatted text.
+ *
+ * @param reader the reader
+ * @param presentation If not <code>null</code>, formattings will be applied to
+ * the presentation.
+ */
+ public HTML2TextReader(Reader reader, TextPresentation presentation) {
+ super(new PushbackReader(reader));
+ fTextPresentation= presentation;
+ }
+
+ public int read() throws IOException {
+ int c= super.read();
+ if (c != -1)
+ ++ fCounter;
+ return c;
+ }
+
+ protected void startBold() {
+ if (fBold == 0)
+ fStartOffset= fCounter;
+ ++ fBold;
+ }
+
+ protected void startPreformattedText() {
+ fIsPreformattedText= true;
+ setSkipWhitespace(false);
+ }
+
+ protected void stopPreformattedText() {
+ fIsPreformattedText= false;
+ setSkipWhitespace(true);
+ }
+
+ protected void stopBold() {
+ -- fBold;
+ if (fBold == 0) {
+ if (fTextPresentation != null) {
+ fTextPresentation.addStyleRange(new StyleRange(fStartOffset, fCounter - fStartOffset, null, null, SWT.BOLD));
+ }
+ fStartOffset= -1;
+ }
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.SubstitutionTextReader#computeSubstitution(int)
+ */
+ protected String computeSubstitution(int c) throws IOException {
+
+ if (c == '<')
+ return processHTMLTag();
+ else if (fIgnore)
+ return EMPTY_STRING;
+ else if (c == '&')
+ return processEntity();
+ else if (fIsPreformattedText)
+ return processPreformattedText(c);
+
+ return null;
+ }
+
+ private String html2Text(String html) {
+
+ if (html == null || html.length() == 0)
+ return EMPTY_STRING;
+
+ html= html.toLowerCase();
+
+ String tag= html;
+ if ('/' == tag.charAt(0))
+ tag= tag.substring(1);
+
+ if (!fgTags.contains(tag))
+ return EMPTY_STRING;
+
+
+ if ("pre".equals(html)) { //$NON-NLS-1$
+ startPreformattedText();
+ return EMPTY_STRING;
+ }
+
+ if ("/pre".equals(html)) { //$NON-NLS-1$
+ stopPreformattedText();
+ return EMPTY_STRING;
+ }
+
+ if (fIsPreformattedText)
+ return EMPTY_STRING;
+
+ if ("b".equals(html)) { //$NON-NLS-1$
+ startBold();
+ return EMPTY_STRING;
+ }
+
+ if ((html.length() > 1 && html.charAt(0) == 'h' && Character.isDigit(html.charAt(1))) || "dt".equals(html)) { //$NON-NLS-1$
+ startBold();
+ return EMPTY_STRING;
+ }
+
+ if ("dl".equals(html)) //$NON-NLS-1$
+ return LINE_DELIM;
+
+ if ("dd".equals(html)) //$NON-NLS-1$
+ return "\t"; //$NON-NLS-1$
+
+ if ("li".equals(html)) //$NON-NLS-1$
+ // FIXME: this hard-coded prefix does not work for RTL languages, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=91682
+// return LINE_DELIM + JavaUIMessages.HTML2TextReader_listItemPrefix;
+ return LINE_DELIM + "\t-";
+
+
+ if ("/b".equals(html)) { //$NON-NLS-1$
+ stopBold();
+ return EMPTY_STRING;
+ }
+
+ if ("p".equals(html)) { //$NON-NLS-1$
+ fInParagraph= true;
+ return LINE_DELIM;
+ }
+
+ if ("br".equals(html) || "br/".equals(html) || "div".equals(html)) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ return LINE_DELIM;
+
+ if ("/p".equals(html)) { //$NON-NLS-1$
+ boolean inParagraph= fInParagraph;
+ fInParagraph= false;
+ return inParagraph ? EMPTY_STRING : LINE_DELIM;
+ }
+
+ if ((html.startsWith("/h") && html.length() > 2 && Character.isDigit(html.charAt(2))) || "/dt".equals(html)) { //$NON-NLS-1$ //$NON-NLS-2$
+ stopBold();
+ return LINE_DELIM;
+ }
+
+ if ("/dd".equals(html)) //$NON-NLS-1$
+ return LINE_DELIM;
+
+ if ("head".equals(html)) { //$NON-NLS-1$
+ fIgnore= true;
+ return EMPTY_STRING;
+ }
+
+ if ("/head".equals(html)) { //$NON-NLS-1$
+ fIgnore= false;
+ return EMPTY_STRING;
+ }
+
+ return EMPTY_STRING;
+ }
+
+ /*
+ * A '<' has been read. Process a html tag
+ */
+ private String processHTMLTag() throws IOException {
+
+ StringBuffer buf= new StringBuffer();
+ int ch;
+ do {
+
+ ch= nextChar();
+
+ while (ch != -1 && ch != '>') {
+ buf.append(Character.toLowerCase((char) ch));
+ ch= nextChar();
+ if (ch == '"'){
+ buf.append(Character.toLowerCase((char) ch));
+ ch= nextChar();
+ while (ch != -1 && ch != '"'){
+ buf.append(Character.toLowerCase((char) ch));
+ ch= nextChar();
+ }
+ }
+ if (ch == '<'){
+ unread(ch);
+ return '<' + buf.toString();
+ }
+ }
+
+ if (ch == -1)
+ return null;
+
+ int tagLen= buf.length();
+ // needs special treatment for comments
+ if ((tagLen >= 3 && "!--".equals(buf.substring(0, 3))) //$NON-NLS-1$
+ && !(tagLen >= 5 && "--".equals(buf.substring(tagLen - 2)))) { //$NON-NLS-1$
+ // unfinished comment
+ buf.append(ch);
+ } else {
+ break;
+ }
+ } while (true);
+
+ return html2Text(buf.toString());
+ }
+
+ private String processPreformattedText(int c) {
+ if (c == '\r' || c == '\n')
+ fCounter++;
+ return null;
+ }
+
+
+ private void unread(int ch) throws IOException {
+ ((PushbackReader) getReader()).unread(ch);
+ }
+
+ protected String entity2Text(String symbol) {
+ if (symbol.length() > 1 && symbol.charAt(0) == '#') {
+ int ch;
+ try {
+ if (symbol.charAt(1) == 'x') {
+ ch= Integer.parseInt(symbol.substring(2), 16);
+ } else {
+ ch= Integer.parseInt(symbol.substring(1), 10);
+ }
+ return EMPTY_STRING + (char)ch;
+ } catch (NumberFormatException e) {
+ }
+ } else {
+ String str= (String) fgEntityLookup.get(symbol);
+ if (str != null) {
+ return str;
+ }
+ }
+ return "&" + symbol; // not found //$NON-NLS-1$
+ }
+
+ /*
+ * A '&' has been read. Process a entity
+ */
+ private String processEntity() throws IOException {
+ StringBuffer buf= new StringBuffer();
+ int ch= nextChar();
+ while (Character.isLetterOrDigit((char)ch) || ch == '#') {
+ buf.append((char) ch);
+ ch= nextChar();
+ }
+
+ if (ch == ';')
+ return entity2Text(buf.toString());
+
+ buf.insert(0, '&');
+ if (ch != -1)
+ buf.append((char) ch);
+ return buf.toString();
+ }
+} \ No newline at end of file
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/HTMLTextPresenter.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/HTMLTextPresenter.java
new file mode 100644
index 000000000..fbb7a522b
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/HTMLTextPresenter.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.imp.ui.textPresentation;
+
+
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Iterator;
+
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.graphics.Drawable;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.widgets.Display;
+
+
+
+public class HTMLTextPresenter implements DefaultInformationControl.IInformationPresenter, DefaultInformationControl.IInformationPresenterExtension {
+
+ private static final String LINE_DELIM= System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ private int fCounter;
+ private boolean fEnforceUpperLineLimit;
+
+ /**
+ * Enables using bold font in order not to clip the text.
+ * <p>
+ * <em>Enabling this is a hack.</em>
+ *
+ * @since 3.2
+ */
+ private boolean fUseBoldFont= false;
+
+ public HTMLTextPresenter(boolean enforceUpperLineLimit) {
+ super();
+ fEnforceUpperLineLimit= enforceUpperLineLimit;
+ }
+
+ public HTMLTextPresenter() {
+ this(true);
+ }
+
+ protected HTML2TextReader createReader(String hoverInfo, TextPresentation presentation) {
+ return new HTML2TextReader(new StringReader(hoverInfo), presentation);
+ }
+
+ protected void adaptTextPresentation(TextPresentation presentation, int offset, int insertLength) {
+
+ int yoursStart= offset;
+ int yoursEnd= offset + insertLength -1;
+ yoursEnd= Math.max(yoursStart, yoursEnd);
+
+ Iterator e= presentation.getAllStyleRangeIterator();
+ while (e.hasNext()) {
+
+ StyleRange range= (StyleRange) e.next();
+
+ int myStart= range.start;
+ int myEnd= range.start + range.length -1;
+ myEnd= Math.max(myStart, myEnd);
+
+ if (myEnd < yoursStart)
+ continue;
+
+ if (myStart < yoursStart)
+ range.length += insertLength;
+ else
+ range.start += insertLength;
+ }
+ }
+
+ private void append(StringBuffer buffer, String string, TextPresentation presentation) {
+
+ int length= string.length();
+ buffer.append(string);
+
+ if (presentation != null)
+ adaptTextPresentation(presentation, fCounter, length);
+
+ fCounter += length;
+ }
+
+ private String getIndent(String line) {
+ int length= line.length();
+
+ int i= 0;
+ while (i < length && Character.isWhitespace(line.charAt(i))) ++i;
+
+ return (i == length ? line : line.substring(0, i)) + " "; //$NON-NLS-1$
+ }
+
+ /*
+ * @see IHoverInformationPresenter#updatePresentation(Display display, String, TextPresentation, int, int)
+ */
+ public String updatePresentation(Display display, String hoverInfo, TextPresentation presentation, int maxWidth, int maxHeight) {
+ return updatePresentation((Drawable)display, hoverInfo, presentation, maxWidth, maxHeight);
+ }
+
+ /*
+ * @see IHoverInformationPresenterExtension#updatePresentation(Drawable drawable, String, TextPresentation, int, int)
+ * @since 3.2
+ */
+ public String updatePresentation(Drawable drawable, String hoverInfo, TextPresentation presentation, int maxWidth, int maxHeight) {
+
+ if (hoverInfo == null)
+ return null;
+
+ GC gc= new GC(drawable);
+
+ Font font= null;
+ if (fUseBoldFont) {
+ font= gc.getFont();
+ FontData[] fontData= font.getFontData();
+ for (int i= 0; i < fontData.length; i++)
+ fontData[i].setStyle(SWT.BOLD);
+ font= new Font(gc.getDevice(), fontData);
+ gc.setFont(font);
+ }
+
+ try {
+
+ StringBuffer buffer= new StringBuffer();
+ int maxNumberOfLines= Math.round((float)maxHeight / gc.getFontMetrics().getHeight());
+
+ fCounter= 0;
+ LineBreakingReader reader= new LineBreakingReader(createReader(hoverInfo, presentation), gc, maxWidth);
+
+ boolean lastLineFormatted= false;
+ String lastLineIndent= null;
+
+ String line=reader.readLine();
+ boolean lineFormatted= reader.isFormattedLine();
+ boolean firstLineProcessed= false;
+
+ while (line != null) {
+
+ if (fEnforceUpperLineLimit && maxNumberOfLines <= 0)
+ break;
+
+ if (firstLineProcessed) {
+ if (!lastLineFormatted)
+ append(buffer, LINE_DELIM, null);
+ else {
+ append(buffer, LINE_DELIM, presentation);
+ if (lastLineIndent != null)
+ append(buffer, lastLineIndent, presentation);
+ }
+ }
+
+ append(buffer, line, null);
+ firstLineProcessed= true;
+
+ lastLineFormatted= lineFormatted;
+ if (!lineFormatted)
+ lastLineIndent= null;
+ else if (lastLineIndent == null)
+ lastLineIndent= getIndent(line);
+
+ line= reader.readLine();
+ lineFormatted= reader.isFormattedLine();
+
+ maxNumberOfLines--;
+ }
+
+ if (line != null && buffer.length() > 0) {
+ append(buffer, LINE_DELIM, lineFormatted ? presentation : null);
+// append(buffer, JavaUIMessages.HTMLTextPresenter_ellipsis, presentation);
+ append(buffer, "...", presentation);
+ }
+
+ return trim(buffer, presentation);
+
+ } catch (IOException e) {
+
+// JavaPlugin.log(e);
+ RuntimePlugin.getInstance().logException("Exception in updatePresentation", e);
+ return null;
+
+ } finally {
+ if (font != null)
+ font.dispose();
+ gc.dispose();
+ }
+ }
+
+ private String trim(StringBuffer buffer, TextPresentation presentation) {
+
+ int length= buffer.length();
+
+ int end= length -1;
+ while (end >= 0 && Character.isWhitespace(buffer.charAt(end)))
+ -- end;
+
+ if (end == -1)
+ return ""; //$NON-NLS-1$
+
+ if (end < length -1)
+ buffer.delete(end + 1, length);
+ else
+ end= length;
+
+ int start= 0;
+ while (start < end && Character.isWhitespace(buffer.charAt(start)))
+ ++ start;
+
+ buffer.delete(0, start);
+ presentation.setResultWindow(new Region(start, buffer.length()));
+ return buffer.toString();
+ }
+}
+
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/LineBreakingReader.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/LineBreakingReader.java
new file mode 100644
index 000000000..57769b541
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/LineBreakingReader.java
@@ -0,0 +1,131 @@
+package org.eclipse.imp.ui.textPresentation;
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+
+import com.ibm.icu.text.BreakIterator;
+import org.eclipse.swt.graphics.GC;
+
+/*
+ * Not a real reader. Could change if requested
+ */
+public class LineBreakingReader {
+
+ private BufferedReader fReader;
+ private GC fGC;
+ private int fMaxWidth;
+
+ private String fLine;
+ private int fOffset;
+
+ private BreakIterator fLineBreakIterator;
+ private boolean fBreakWords;
+
+ /**
+ * Creates a reader that breaks an input text to fit in a given width.
+ *
+ * @param reader Reader of the input text
+ * @param gc The graphic context that defines the currently used font sizes
+ * @param maxLineWidth The max width (pixels) where the text has to fit in
+ */
+ public LineBreakingReader(Reader reader, GC gc, int maxLineWidth) {
+ fReader= new BufferedReader(reader);
+ fGC= gc;
+ fMaxWidth= maxLineWidth;
+ fOffset= 0;
+ fLine= null;
+ fLineBreakIterator= BreakIterator.getLineInstance();
+ fBreakWords= true;
+ }
+
+ public boolean isFormattedLine() {
+ return fLine != null;
+ }
+
+ /**
+ * Reads the next line. The lengths of the line will not exceed the given maximum
+ * width.
+ *
+ * @return the next line
+ * @throws IOException
+ */
+ public String readLine() throws IOException {
+ if (fLine == null) {
+ String line= fReader.readLine();
+ if (line == null)
+ return null;
+
+ int lineLen= fGC.textExtent(line).x;
+ if (lineLen < fMaxWidth) {
+ return line;
+ }
+ fLine= line;
+ fLineBreakIterator.setText(line);
+ fOffset= 0;
+ }
+ int breakOffset= findNextBreakOffset(fOffset);
+ String res;
+ if (breakOffset != BreakIterator.DONE) {
+ res= fLine.substring(fOffset, breakOffset);
+ fOffset= findWordBegin(breakOffset);
+ if (fOffset == fLine.length()) {
+ fLine= null;
+ }
+ } else {
+ res= fLine.substring(fOffset);
+ fLine= null;
+ }
+ return res;
+ }
+
+ private int findNextBreakOffset(int currOffset) {
+ int currWidth= 0;
+ int nextOffset= fLineBreakIterator.following(currOffset);
+ while (nextOffset != BreakIterator.DONE) {
+ String word= fLine.substring(currOffset, nextOffset);
+ int wordWidth= fGC.textExtent(word).x;
+ int nextWidth= wordWidth + currWidth;
+ if (nextWidth > fMaxWidth) {
+ if (currWidth > 0)
+ return currOffset;
+
+ if (!fBreakWords)
+ return nextOffset;
+
+ // need to fit into fMaxWidth
+ int length= word.length();
+ while (length >= 0) {
+ length--;
+ word= word.substring(0, length);
+ wordWidth= fGC.textExtent(word).x;
+ if (wordWidth + currWidth < fMaxWidth)
+ return currOffset + length;
+ }
+ return nextOffset;
+ }
+ currWidth= nextWidth;
+ currOffset= nextOffset;
+ nextOffset= fLineBreakIterator.next();
+ }
+ return nextOffset;
+ }
+
+ private int findWordBegin(int idx) {
+ while (idx < fLine.length() && Character.isWhitespace(fLine.charAt(idx))) {
+ idx++;
+ }
+ return idx;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/SingleCharReader.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/SingleCharReader.java
new file mode 100644
index 000000000..50f3a4a8b
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/SingleCharReader.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.imp.ui.textPresentation;
+
+
+import java.io.IOException;
+import java.io.Reader;
+
+public abstract class SingleCharReader extends Reader {
+
+ /**
+ * @see Reader#read()
+ */
+ public abstract int read() throws IOException;
+
+ /**
+ * @see Reader#read(char[],int,int)
+ */
+ public int read(char cbuf[], int off, int len) throws IOException {
+ int end= off + len;
+ for (int i= off; i < end; i++) {
+ int ch= read();
+ if (ch == -1) {
+ if (i == off) {
+ return -1;
+ } else {
+ return i - off;
+ }
+ }
+ cbuf[i]= (char)ch;
+ }
+ return len;
+ }
+
+ /**
+ * @see Reader#ready()
+ */
+ public boolean ready() throws IOException {
+ return true;
+ }
+
+ /**
+ * Gets the content as a String
+ */
+ public String getString() throws IOException {
+ StringBuffer buf= new StringBuffer();
+ int ch;
+ while ((ch= read()) != -1) {
+ buf.append((char)ch);
+ }
+ return buf.toString();
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/SubstitutionTextReader.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/SubstitutionTextReader.java
new file mode 100644
index 000000000..d66a5d7cb
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/ui/textPresentation/SubstitutionTextReader.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+
+package org.eclipse.imp.ui.textPresentation;
+
+
+import java.io.IOException;
+import java.io.Reader;
+
+//import org.eclipse.jdt.internal.corext.javadoc.SingleCharReader;
+
+
+/**
+ * Reads the text contents from a reader and computes for each character
+ * a potential substitution. The substitution may eat more characters than
+ * only the one passed into the computation routine.
+ */
+public abstract class SubstitutionTextReader extends SingleCharReader {
+
+ protected static final String LINE_DELIM= System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ private Reader fReader;
+ protected boolean fWasWhiteSpace;
+ private int fCharAfterWhiteSpace;
+
+ /**
+ * Tells whether white space characters are skipped.
+ */
+ private boolean fSkipWhiteSpace= true;
+
+ private boolean fReadFromBuffer;
+ private StringBuffer fBuffer;
+ private int fIndex;
+
+
+ protected SubstitutionTextReader(Reader reader) {
+ fReader= reader;
+ fBuffer= new StringBuffer();
+ fIndex= 0;
+ fReadFromBuffer= false;
+ fCharAfterWhiteSpace= -1;
+ fWasWhiteSpace= true;
+ }
+
+ /**
+ * Implement to compute the substitution for the given character and
+ * if necessary subsequent characters. Use <code>nextChar</code>
+ * to read subsequent characters.
+ */
+ protected abstract String computeSubstitution(int c) throws IOException;
+
+ /**
+ * Returns the internal reader.
+ */
+ protected Reader getReader() {
+ return fReader;
+ }
+
+ /**
+ * Returns the next character.
+ */
+ protected int nextChar() throws IOException {
+ fReadFromBuffer= (fBuffer.length() > 0);
+ if (fReadFromBuffer) {
+ char ch= fBuffer.charAt(fIndex++);
+ if (fIndex >= fBuffer.length()) {
+ fBuffer.setLength(0);
+ fIndex= 0;
+ }
+ return ch;
+ } else {
+ int ch= fCharAfterWhiteSpace;
+ if (ch == -1) {
+ ch= fReader.read();
+ }
+ if (fSkipWhiteSpace && Character.isWhitespace((char)ch)) {
+ do {
+ ch= fReader.read();
+ } while (Character.isWhitespace((char)ch));
+ if (ch != -1) {
+ fCharAfterWhiteSpace= ch;
+ return ' ';
+ }
+ } else {
+ fCharAfterWhiteSpace= -1;
+ }
+ return ch;
+ }
+ }
+
+ /**
+ * @see Reader#read()
+ */
+ public int read() throws IOException {
+ int c;
+ do {
+
+ c= nextChar();
+ while (!fReadFromBuffer) {
+ String s= computeSubstitution(c);
+ if (s == null)
+ break;
+ if (s.length() > 0)
+ fBuffer.insert(0, s);
+ c= nextChar();
+ }
+
+ } while (fSkipWhiteSpace && fWasWhiteSpace && (c == ' '));
+ fWasWhiteSpace= (c == ' ' || c == '\r' || c == '\n');
+ return c;
+ }
+
+ /**
+ * @see Reader#ready()
+ */
+ public boolean ready() throws IOException {
+ return fReader.ready();
+ }
+
+ /**
+ * @see Reader#close()
+ */
+ public void close() throws IOException {
+ fReader.close();
+ }
+
+ /**
+ * @see Reader#reset()
+ */
+ public void reset() throws IOException {
+ fReader.reset();
+ fWasWhiteSpace= true;
+ fCharAfterWhiteSpace= -1;
+ fBuffer.setLength(0);
+ fIndex= 0;
+ }
+
+ protected final void setSkipWhitespace(boolean state) {
+ fSkipWhiteSpace= state;
+ }
+
+ protected final boolean isSkippingWhitespace() {
+ return fSkipWhiteSpace;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/AnnotationUtils.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/AnnotationUtils.java
new file mode 100644
index 000000000..d46647ea3
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/AnnotationUtils.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+ *******************************************************************************/
+
+package org.eclipse.imp.utils;
+
+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.IAnnotationModel;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.projection.AnnotationBag;
+
+public class AnnotationUtils {
+ private AnnotationUtils() {
+ }
+
+ public static String formatAnnotationList(List<Annotation> annotations) {
+ if (annotations != null) {
+ if (annotations.size() == 1) {
+ // optimization
+ Annotation annotation= (Annotation) annotations.get(0);
+ String message= annotation.getText();
+ if (message != null && message.trim().length() > 0)
+ return HTMLPrinter.formatSingleMessage(message);
+ } else {
+ List<String> messages= new ArrayList<String>();
+ for(Annotation annotation : annotations) {
+ String message= annotation.getText();
+ if (message != null && message.trim().length() > 0)
+ messages.add(message.trim());
+ }
+ if (messages.size() == 1)
+ return HTMLPrinter.formatSingleMessage((String) messages.get(0));
+ if (messages.size() > 1)
+ return HTMLPrinter.formatMultipleMessages(messages);
+ }
+ }
+ return null;
+ }
+
+ public static IAnnotationModel getAnnotationModel(ISourceViewer viewer) {
+ // if (viewer instanceof ISourceViewerExtension2) {
+ // ISourceViewerExtension2 extension= (ISourceViewerExtension2) viewer;
+ //
+ // return extension.getVisualAnnotationModel();
+ // }
+ return viewer.getAnnotationModel();
+ }
+
+ /**
+ * Check preferences, etc., to determine whether this annotation is actually showing. (Don't want to show a hover
+ * for a non-visible annotation.)
+ *
+ * @param annotation
+ * @param position
+ * @param messagesAtPosition
+ * @return
+ */
+ public static boolean includeAnnotation(Annotation annotation, Position position) {
+ return true;
+ }
+
+ public static List<Annotation> getAnnotations(ISourceViewer viewer, IPositionPredicate posPred) {
+ IAnnotationModel model= getAnnotationModel(viewer);
+ if (model == null)
+ return null;
+ List<Annotation> annotations= new ArrayList<Annotation>();
+ Iterator<Annotation> iterator= model.getAnnotationIterator();
+ while (iterator.hasNext()) {
+ Annotation annotation= (Annotation) iterator.next();
+ Position position= model.getPosition(annotation);
+ // System.out.println("Checking annotation @ " + position.offset + ":" + position.length + " => " +
+ // annotation.getText());
+ if (annotation.getType().equals("org.eclipse.ui.workbench.texteditor.quickdiffUnchanged"))
+ continue;
+ if (position == null)
+ continue;
+ if (!posPred.matchPosition(position))
+ continue;
+ if (annotation instanceof AnnotationBag) {
+ AnnotationBag bag= (AnnotationBag) annotation;
+ for(Iterator<Annotation> e= bag.iterator(); e.hasNext(); ) {
+ Annotation bagAnnotation= (Annotation) e.next();
+ position= model.getPosition(bagAnnotation);
+ if (position != null && includeAnnotation(bagAnnotation, position))
+ annotations.add(bagAnnotation);
+ }
+ } else {
+ if (includeAnnotation(annotation, position))
+ annotations.add(annotation);
+ }
+ }
+ return annotations;
+ }
+
+ public static List<Annotation> getAnnotationsForLine(ISourceViewer viewer, final int line) {
+ final IDocument document= viewer.getDocument();
+ IPositionPredicate posPred= new IPositionPredicate() {
+ public boolean matchPosition(Position p) {
+ return AnnotationUtils.offsetIsAtLine(p, document, line);
+ }
+ };
+ return getAnnotations(viewer, posPred);
+ }
+
+ public static List<Annotation> getAnnotationsForOffset(ISourceViewer viewer, final int offset) {
+ IPositionPredicate posPred= new IPositionPredicate() {
+ public boolean matchPosition(Position p) {
+ return offset >= p.offset && offset < p.offset + p.length;
+ }
+ };
+ return getAnnotations(viewer, posPred);
+ }
+
+ public static boolean offsetIsAtLine(Position position, IDocument document, int line) {
+ if (position.getOffset() > -1 && position.getLength() > -1) {
+ try {
+ int posLine= document.getLineOfOffset(position.getOffset());
+ // System.out.println(" at line " + posLine);
+ return line == posLine;
+ } catch (BadLocationException x) {
+ }
+ }
+ return false;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/ConsoleUtil.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/ConsoleUtil.java
new file mode 100644
index 000000000..6b0b65699
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/ConsoleUtil.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+* Copyright (c) 2008 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+
+package org.eclipse.imp.utils;
+
+import java.io.PrintStream;
+
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.IConsoleManager;
+import org.eclipse.ui.console.MessageConsole;
+import org.eclipse.ui.console.MessageConsoleStream;
+
+public class ConsoleUtil {
+ public static MessageConsole findConsole(String name) {
+ MessageConsole myConsole= null;
+ final IConsoleManager consoleManager= ConsolePlugin.getDefault().getConsoleManager();
+ IConsole[] consoles= consoleManager.getConsoles();
+ for(int i= 0; i < consoles.length; i++) {
+ IConsole console= consoles[i];
+ if (console.getName().equals(name))
+ myConsole= (MessageConsole) console;
+ }
+ if (myConsole == null) {
+ myConsole= new MessageConsole(name, null);
+ consoleManager.addConsoles(new IConsole[] { myConsole });
+ }
+ consoleManager.showConsoleView(myConsole);
+ return myConsole;
+ }
+
+ public static PrintStream findConsoleStream(String name) {
+ MessageConsole myConsole= findConsole(name);
+ MessageConsoleStream consStream= myConsole.newMessageStream();
+ PrintStream ps= new PrintStream(consStream);
+
+ return ps;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/ExtensionException.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/ExtensionException.java
new file mode 100644
index 000000000..fa5031fc5
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/ExtensionException.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.utils;
+
+public class ExtensionException extends Exception {
+ private static final long serialVersionUID = 6634753150865956173L;
+
+ public ExtensionException() {
+ super();
+ }
+
+ public ExtensionException(String message) {
+ super(message);
+ }
+
+ public ExtensionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/ExtensionFactory.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/ExtensionFactory.java
new file mode 100644
index 000000000..1ad2882f0
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/ExtensionFactory.java
@@ -0,0 +1,395 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.utils;
+
+import java.net.URL;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IContributor;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.imp.language.ILanguageService;
+import org.eclipse.imp.language.Language;
+import org.eclipse.imp.language.LanguageRegistry;
+import org.eclipse.imp.runtime.RuntimePlugin;
+import org.osgi.framework.Bundle;
+
+/*
+ * Licensed Materials - Property of IBM, (c) Copyright IBM Corp. 2005 All Rights
+ * Reserved
+ */
+
+/**
+ * @author Claffra
+ * @author rfuhrer@watson.ibm.com
+ * @author jurgen@vinju.org
+ */
+public class ExtensionFactory {
+
+ /**
+ * Locate the first extension that matches this language and extension point id,
+ * and load the class that implements it and return a handle to an object of that class.
+ *
+ * @param language
+ * @param extensionPointID
+ * @return
+ * @throws ExtensionException
+ */
+ public static ILanguageService createServiceExtension(Language language,
+ String extensionPointID) throws ExtensionException {
+ return createServiceExtensionForPlugin(language, RuntimePlugin.IMP_RUNTIME,
+ extensionPointID);
+ }
+
+ /**
+ * Locate all extensions that match the language and extension point id, load their
+ * classes and collect handles to objects of that class in a set.
+ * @param language
+ * @param extensionPointID
+ * @return
+ * @throws ExtensionException
+ */
+ public static Set<ILanguageService> createServiceExtensionSet(Language language,
+ String extensionPointID) throws ExtensionException {
+ return createServiceExtensionSetForPlugin(language, RuntimePlugin.IMP_RUNTIME,
+ extensionPointID);
+ }
+
+ /**
+ * Find a language name in a language descriptor extension.
+ *
+ * @param pluginID
+ * @return
+ */
+ public static String retrieveLanguageIdFromPlugin(String pluginID) {
+ IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
+ .getExtensionPoint(RuntimePlugin.IMP_RUNTIME,
+ RuntimePlugin.LANGUAGE_DESCRIPTOR);
+ IConfigurationElement[] configElements = extensionPoint
+ .getConfigurationElements();
+
+ for (int i = 0; i < configElements.length; i++) {
+ IContributor contrib = configElements[i].getContributor();
+
+ if (contrib.getName().equals(pluginID)) {
+ return configElements[i]
+ .getAttribute(Language.LANGUAGE_ID_ATTR);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Locate the first extension that matches this language, plugin, and extensionpoint id,
+ * then load a class from the element named 'elementName', and return a handle to an
+ * object of this class.
+ *
+ * @param language
+ * @param pluginID
+ * @param extensionPointId
+ * @param elementName
+ * @return
+ * @throws ExtensionException
+ */
+ public static ILanguageService createServiceExtensionForPlugin(
+ Language language, String pluginID, String extensionPointId,
+ String elementName) throws ExtensionException {
+ IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
+ .getExtensionPoint(pluginID, extensionPointId);
+
+ if (extensionPoint == null) {
+ throw new ExtensionException(
+ "No such language service extension point defined: "
+ + pluginID + "." + extensionPointId);
+ }
+
+ ILanguageService service = getLanguageServiceForElement(
+ extensionPoint, language.getName(), elementName);
+
+ if (service == null && languageIsDerived(language)) {
+ service = createServiceExtensionForPlugin(LanguageRegistry
+ .findLanguage(language.getDerivedFrom()), pluginID,
+ extensionPointId, elementName);
+ }
+
+ return service;
+ }
+
+ /**
+ * Detmermine wether a language was declared to be derived from another language,
+ * and whether this other language actually is registered.
+ * @param language
+ * @return
+ */
+ private static boolean languageIsDerived(Language language) {
+ final boolean hasParent = language.getDerivedFrom() != null
+ && LanguageRegistry.findLanguage(language.getDerivedFrom()) != null;
+ return hasParent;
+ }
+
+ /**
+ * Finds the first extension that matches this language, plugin and extension point id,
+ * and then loads the class that implements this extension and returns a handle to it.
+ *
+ * @param language
+ * @param pluginID
+ * @param extensionPointId
+ * @return
+ * @throws ExtensionException
+ */
+ public static ILanguageService createServiceExtensionForPlugin(Language language,
+ String pluginID, String extensionPointId) throws ExtensionException {
+ return createServiceExtensionForPlugin(language, pluginID,
+ extensionPointId, "class");
+ }
+
+ /**
+ * Find all extensions that match this pluginId, language and extension point id,
+ * then loads the classes that implement these extenstions and returns them as
+ * a set of ILanguageServices.
+ *
+ * @param language
+ * @param pluginID
+ * @param extensionPointId
+ * @return
+ * @throws ExtensionException
+ */
+ public static Set<ILanguageService> createServiceExtensionSetForPlugin(Language language,
+ String pluginID, String extensionPointId) throws ExtensionException {
+ IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
+ .getExtensionPoint(pluginID, extensionPointId);
+
+ if (extensionPoint == null) {
+ throw new ExtensionException(
+ "No such language service extension point defined: "
+ + pluginID + "." + extensionPointId);
+ }
+
+ Set<ILanguageService> services = getLanguageServiceSet(
+ extensionPoint, language.getName());
+
+ if (services.isEmpty() && languageIsDerived(language)) {
+ final ILanguageService baseServiceImpl = createServiceExtensionForPlugin(
+ LanguageRegistry.findLanguage(language.getDerivedFrom()),
+ pluginID, extensionPointId);
+ if (baseServiceImpl != null) {
+ services.add(baseServiceImpl);
+ }
+ }
+
+ return services;
+ }
+
+ /**
+ * detect whether a certain plugin defines a certain extension for a certain language
+ * @param pluginID
+ * @param extensionPointID
+ * @param language
+ * @return
+ */
+ @SuppressWarnings("deprecation")
+ public static boolean languageServiceExists(String pluginID,
+ String extensionPointID, Language language) {
+ if (language == null)
+ return false;
+
+ IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
+ .getExtensionPoint(pluginID, extensionPointID);
+ IConfigurationElement[] elements = extensionPoint
+ .getConfigurationElements();
+ String lowerLang = language.getName().toLowerCase();
+
+ if (elements != null) {
+ for (int n = 0; n < elements.length; n++) {
+ IConfigurationElement element = elements[n];
+ Bundle bundle = Platform.getBundle(element
+ .getDeclaringExtension().getNamespace());
+
+ if (bundle != null) {
+ final String attrValue = element
+ .getAttribute(Language.LANGUAGE_ID_ATTR);
+
+ if (attrValue != null
+ && lowerLang.equals(attrValue.toLowerCase())) {
+ return true;
+ }
+ }
+ }
+ }
+
+ if (languageIsDerived(language)) {
+ return languageServiceExists(pluginID, extensionPointID,
+ LanguageRegistry.findLanguage(language.getDerivedFrom()));
+ }
+
+ return false;
+ }
+
+ /**
+ * Locates all elements that match the language and the particular extension point id,
+ * and returns a set of loaded ILanguageServices using these elements.
+ * @param extensionPoint
+ * @param language
+ * @return
+ * @throws ExtensionException
+ */
+ private static Set<ILanguageService> getLanguageServiceSet(
+ IExtensionPoint extensionPoint, String language)
+ throws ExtensionException {
+ IConfigurationElement[] elements = extensionPoint
+ .getConfigurationElements();
+ Set<ILanguageService> result = new HashSet<ILanguageService>();
+
+ if (elements != null) {
+ for (int n = 0; n < elements.length; n++) {
+ IConfigurationElement element = elements[n];
+ ILanguageService service = loadLanguageService(extensionPoint, language, "class", element);
+
+ if (service != null) {
+ result.add(service);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Locates the first element that matches the ,anguage and the elementName,
+ * and tries to load a language service from it.
+ *
+ * @param extensionPoint
+ * @param language
+ * @param elementName
+ * @return
+ * @throws ExtensionException
+ */
+ private static ILanguageService getLanguageServiceForElement(
+ IExtensionPoint extensionPoint, String language, String elementName)
+ throws ExtensionException {
+ IConfigurationElement[] elements = extensionPoint
+ .getConfigurationElements();
+
+ if (elements != null) {
+ for (int n = 0; n < elements.length; n++) {
+ IConfigurationElement element = elements[n];
+ ILanguageService service = loadLanguageService(extensionPoint, language, elementName, element);
+ if (service != null) {
+ return service;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Convenience method for actuallys creating an object from an element in an
+ * extension point. Catches common exceptions that may be thrown and tries to
+ * translate them into ServiceExceptions.
+ *
+ * @param extensionPoint
+ * @param language
+ * @param elementName
+ * @param element
+ * @return
+ * @throws ExtensionException
+ */
+ @SuppressWarnings("deprecation")
+ private static ILanguageService loadLanguageService(IExtensionPoint extensionPoint, String language, String elementName, IConfigurationElement element) throws ExtensionException {
+ Bundle bundle = Platform.getBundle(element
+ .getDeclaringExtension().getNamespace());
+ String lowerLang = language.toLowerCase();
+
+ if (bundle != null) {
+ final String attrValue = element
+ .getAttribute(Language.LANGUAGE_ID_ATTR);
+
+ if (attrValue != null
+ && lowerLang.equals(attrValue.toLowerCase())) {
+ try {
+ return (ILanguageService) element
+ .createExecutableExtension(elementName);
+ } catch (ClassCastException e) {
+ throw new ExtensionException(
+ "Extension does not point to a class that implements an ILanguageService:"
+ + element, e);
+ } catch (IncompatibleClassChangeError e) {
+ throw new ExtensionException("Unable to instantiate implementation of "
+ + extensionPoint.getLabel()
+ + " plugin for language '"
+ + language
+ + "' because some class in the plugin is incompatible (out-of-date)", e);
+ } catch (CoreException e) {
+ throw new ExtensionException(
+ "Unable to instantiate implementation of "
+ + extensionPoint.getLabel()
+ + " plugin for language '"
+ + language
+ + "' because of the following low level exception: "
+ + e.getStatus().getException(), e);
+ } catch (NoClassDefFoundError e) {
+ throw new ExtensionException(
+ "Unable to instantiate implementation of "
+ + extensionPoint.getLabel()
+ + " plugin for language '"
+ + language
+ + "' because it may not have a public zero argument constructor, or some class referenced by the plugin could not be found in the class path.",
+ e);
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Retrieves from an extension an attribute that represents a resource URL
+ * @param language language that the extension is for
+ * @param extensionPoint extension point identifier
+ * @param the label of the attribute that contains the resource URL
+ */
+ @SuppressWarnings("deprecation")
+ public static URL createResourceURL(String language,
+ IExtensionPoint extensionPoint, String label) {
+ IConfigurationElement[] elements = extensionPoint
+ .getConfigurationElements();
+ String lowerLabel = label.toLowerCase();
+ String lowerLang = language.toLowerCase();
+
+ if (elements != null) {
+ for (int n = 0; n < elements.length; n++) {
+ IConfigurationElement element = elements[n];
+ Bundle bundle = Platform.getBundle(element
+ .getDeclaringExtension().getNamespace());
+
+ if (bundle != null) {
+ final String attrValue = element
+ .getAttribute(Language.LANGUAGE_ID_ATTR);
+
+ if (attrValue != null
+ && lowerLang.equals(attrValue.toLowerCase())) {
+ String resourceName = element.getAttribute(lowerLabel);
+ return bundle.getResource(resourceName);
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/HTMLPrinter.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/HTMLPrinter.java
new file mode 100644
index 000000000..2297f0433
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/HTMLPrinter.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.utils;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTError;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Provides a set of convenience methods for creating HTML pages.
+ * A copy of an internal class from org.eclipse.jdt.ui.
+ */
+public class HTMLPrinter {
+ private static RGB BG_COLOR_RGB= null;
+ static {
+ final Display display= Display.getDefault();
+ if (display != null && !display.isDisposed()) {
+ try {
+ display.asyncExec(new Runnable() {
+ /*
+ * @see java.lang.Runnable#run()
+ */
+ public void run() {
+ BG_COLOR_RGB= display.getSystemColor(SWT.COLOR_INFO_BACKGROUND).getRGB();
+ }
+ });
+ } catch (SWTError err) {
+ // see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=45294
+ if (err.code != SWT.ERROR_DEVICE_DISPOSED)
+ throw err;
+ }
+ }
+ }
+
+ private HTMLPrinter() {}
+
+ private static String replace(String text, char c, String s) {
+ int previous= 0;
+ int current= text.indexOf(c, previous);
+ if (current == -1)
+ return text;
+ StringBuffer buffer= new StringBuffer();
+ while (current > -1) {
+ buffer.append(text.substring(previous, current));
+ buffer.append(s);
+ previous= current + 1;
+ current= text.indexOf(c, previous);
+ }
+ buffer.append(text.substring(previous));
+ return buffer.toString();
+ }
+
+ public static String convertToHTMLContent(String content) {
+ content= replace(content, '&', "&amp;"); //$NON-NLS-1$
+ content= replace(content, '"', "&quot;"); //$NON-NLS-1$
+ content= replace(content, '<', "&lt;"); //$NON-NLS-1$
+ return replace(content, '>', "&gt;"); //$NON-NLS-1$
+ }
+
+ public static String read(Reader rd) {
+ StringBuffer buffer= new StringBuffer();
+ char[] readBuffer= new char[2048];
+ try {
+ int n= rd.read(readBuffer);
+ while (n > 0) {
+ buffer.append(readBuffer, 0, n);
+ n= rd.read(readBuffer);
+ }
+ return buffer.toString();
+ } catch (IOException x) {
+ }
+ return null;
+ }
+
+ public static void insertPageProlog(StringBuffer buffer, int position, RGB bgRGB, URL styleSheetURL) {
+ if (bgRGB == null)
+ insertPageProlog(buffer, position, styleSheetURL);
+ else {
+ StringBuffer pageProlog= new StringBuffer(300);
+ pageProlog.append("<html>"); //$NON-NLS-1$
+ appendStyleSheetURL(pageProlog, styleSheetURL);
+ pageProlog.append("<body text=\"#000000\" bgcolor=\""); //$NON-NLS-1$
+ appendColor(pageProlog, bgRGB);
+ pageProlog.append("\"><font size=-1>"); //$NON-NLS-1$
+ buffer.insert(position, pageProlog.toString());
+ }
+ }
+
+ public static void insertStyles(StringBuffer buffer, String[] styles) {
+ if (styles == null || styles.length == 0)
+ return;
+ StringBuffer styleBuf= new StringBuffer(10 * styles.length);
+ for(int i= 0; styles != null && i < styles.length; i++) {
+ styleBuf.append(" style=\""); //$NON-NLS-1$
+ styleBuf.append(styles[i]);
+ styleBuf.append('"');
+ }
+ // Find insertion index
+ int index= buffer.indexOf("<body "); //$NON-NLS-1$
+ if (index == -1)
+ return;
+ buffer.insert(index + 5, styleBuf);
+ }
+
+ public static void insertPageProlog(StringBuffer buffer, int position, RGB bgRGB) {
+ if (bgRGB == null)
+ insertPageProlog(buffer, position);
+ else {
+ StringBuffer pageProlog= new StringBuffer(60);
+ pageProlog.append("<html><body text=\"#000000\" bgcolor=\""); //$NON-NLS-1$
+ appendColor(pageProlog, bgRGB);
+ pageProlog.append("\"><font size=-1>"); //$NON-NLS-1$
+ buffer.insert(position, pageProlog.toString());
+ }
+ }
+
+ private static void appendStyleSheetURL(StringBuffer buffer, URL styleSheetURL) {
+ if (styleSheetURL == null)
+ return;
+ buffer.append("<head>"); //$NON-NLS-1$
+ buffer.append("<LINK REL=\"stylesheet\" HREF= \""); //$NON-NLS-1$
+ buffer.append(styleSheetURL);
+ buffer.append("\" CHARSET=\"ISO-8859-1\" TYPE=\"text/css\">"); //$NON-NLS-1$
+ buffer.append("</head>"); //$NON-NLS-1$
+ }
+
+ private static void appendColor(StringBuffer buffer, RGB rgb) {
+ buffer.append('#');
+ buffer.append(Integer.toHexString(rgb.red));
+ buffer.append(Integer.toHexString(rgb.green));
+ buffer.append(Integer.toHexString(rgb.blue));
+ }
+
+ public static void insertPageProlog(StringBuffer buffer, int position) {
+ insertPageProlog(buffer, position, getBgColor()); //$NON-NLS-1$
+ }
+
+ public static void insertPageProlog(StringBuffer buffer, int position, URL styleSheetURL) {
+ insertPageProlog(buffer, position, getBgColor(), styleSheetURL); //$NON-NLS-1$
+ }
+
+ private static RGB getBgColor() {
+ if (BG_COLOR_RGB != null)
+ return BG_COLOR_RGB;
+ else
+ return new RGB(255, 255, 225); // RGB value of info bg color on WindowsXP
+ }
+
+ public static void addPageProlog(StringBuffer buffer) {
+ insertPageProlog(buffer, buffer.length());
+ }
+
+ public static void addPageEpilog(StringBuffer buffer) {
+ buffer.append("</font></body></html>"); //$NON-NLS-1$
+ }
+
+ public static void startBulletList(StringBuffer buffer) {
+ buffer.append("<ul>"); //$NON-NLS-1$
+ }
+
+ public static void endBulletList(StringBuffer buffer) {
+ buffer.append("</ul>"); //$NON-NLS-1$
+ }
+
+ public static void addBullet(StringBuffer buffer, String bullet) {
+ if (bullet != null) {
+ buffer.append("<li>"); //$NON-NLS-1$
+ buffer.append(bullet);
+ buffer.append("</li>"); //$NON-NLS-1$
+ }
+ }
+
+ public static void addSmallHeader(StringBuffer buffer, String header) {
+ if (header != null) {
+ buffer.append("<h5>"); //$NON-NLS-1$
+ buffer.append(header);
+ buffer.append("</h5>"); //$NON-NLS-1$
+ }
+ }
+
+ public static void addParagraph(StringBuffer buffer, String paragraph) {
+ if (paragraph != null) {
+ buffer.append("<p>"); //$NON-NLS-1$
+ buffer.append(paragraph);
+ buffer.append("</p>");
+ }
+ }
+
+ public static void addParagraph(StringBuffer buffer, Reader paragraphReader) {
+ if (paragraphReader != null)
+ addParagraph(buffer, read(paragraphReader));
+ }
+
+ /**
+ * Formats several messages as HTML text.
+ */
+ public static String formatMultipleMessages(List/*<String>*/ messages) {
+// if (true) { // until we hook in the HTML-enabled hover viewer
+// StringBuffer buff= new StringBuffer();
+// buff.append("Multiple messages:\n");
+// for(Iterator iter= messages.iterator(); iter.hasNext();) {
+// String msg= (String) iter.next();
+// buff.append(" ");
+// buff.append(msg);
+// if (iter.hasNext())
+// buff.append('\n');
+// }
+// return buff.toString();
+// }
+ StringBuffer buffer= new StringBuffer();
+ addPageProlog(buffer);
+ addParagraph(buffer, convertToHTMLContent("There are multiple markers on this line."));
+ startBulletList(buffer);
+ Iterator e= messages.iterator();
+ while (e.hasNext())
+ addBullet(buffer, convertToHTMLContent((String) e.next()));
+ endBulletList(buffer);
+ addPageEpilog(buffer);
+ return buffer.toString();
+ }
+
+ /**
+ * Formats a message as HTML text.
+ */
+ public static String formatSingleMessage(String message) {
+// if (true) // until we hook in the HTML-enabled hover viewer
+// return message;
+ StringBuffer buffer= new StringBuffer();
+ addPageProlog(buffer);
+ addParagraph(buffer, convertToHTMLContent(message));
+ addPageEpilog(buffer);
+ return buffer.toString();
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/IPositionPredicate.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/IPositionPredicate.java
new file mode 100644
index 000000000..e41ef0e97
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/IPositionPredicate.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+/**
+ *
+ */
+package org.eclipse.imp.utils;
+
+import org.eclipse.jface.text.Position;
+
+/**
+ * Interface that represents a single-argument predicate taking a textual Position.
+ * Used by AnnotationUtils to detect annotations associated with a particular range
+ * or location in source text.
+ * @author rfuhrer
+ */
+public interface IPositionPredicate {
+ boolean matchPosition(Position p);
+} \ No newline at end of file
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/MarkerUtils.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/MarkerUtils.java
new file mode 100644
index 000000000..084b6c8f0
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/MarkerUtils.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.utils;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.imp.runtime.RuntimePlugin;
+
+public class MarkerUtils {
+ private MarkerUtils() { }
+
+ /**
+ * Returns the maximum problem marker severity for the given resource, and, if
+ * depth is IResource.DEPTH_INFINITE, its children. The return value will be
+ * one of IMarker.SEVERITY_ERROR, IMarker.SEVERITY_WARNING, IMarker.SEVERITY_INFO
+ * or 0, indicating that no problem markers exist on the given resource.
+ * @param depth TODO
+ */
+ public static int getMaxProblemMarkerSeverity(IResource res, int depth) {
+ if (res == null || !res.isAccessible())
+ return 0;
+
+ boolean hasWarnings= false; // if resource has errors, will return error image immediately
+ IMarker[] markers= null;
+
+ try {
+ markers= res.findMarkers(IMarker.PROBLEM, true, depth);
+ } catch (CoreException e) {
+ RuntimePlugin.getInstance().logException("Error obtaining markers on resource " + res.getName(), e);
+ }
+ if (markers == null)
+ return 0; // don't know - say no errors/warnings/infos
+
+ for(int i= 0; i < markers.length; i++) {
+ IMarker m= markers[i];
+ int priority= m.getAttribute(IMarker.SEVERITY, -1);
+
+ if (priority == IMarker.SEVERITY_WARNING) {
+ hasWarnings= true;
+ } else if (priority == IMarker.SEVERITY_ERROR) {
+ return IMarker.SEVERITY_ERROR;
+ }
+ }
+ return hasWarnings ? IMarker.SEVERITY_WARNING : 0;
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/Pair.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/Pair.java
new file mode 100644
index 000000000..14fa4d2fc
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/Pair.java
@@ -0,0 +1,42 @@
+/**
+ *
+ */
+package org.eclipse.imp.utils;
+
+/**
+ * @author rfuhrer@watson.ibm.com
+ */
+public class Pair<T1,T2> {
+ public final T1 first;
+ public final T2 second;
+
+ public Pair(T1 v1, T2 v2) {
+ first= v1;
+ second= v2;
+ }
+
+ @Override
+ public int hashCode() {
+ return 6143 + 2399 * first.hashCode() + 7433 * second.hashCode();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Pair)) return false;
+ Pair other= (Pair) obj;
+
+ return other.first.equals(first) && other.second.equals(second);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb= new StringBuilder();
+ sb.append('<');
+ sb.append(first);
+ sb.append(',');
+ sb.append(second);
+ sb.append('>');
+ return sb.toString();
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/StreamUtils.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/StreamUtils.java
new file mode 100644
index 000000000..3491b980b
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/StreamUtils.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.utils;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+
+import org.eclipse.compare.IEncodedStreamContentAccessor;
+import org.eclipse.compare.IStreamContentAccessor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+
+public class StreamUtils {
+ private StreamUtils() { }
+
+ /**
+ * Given an IStreamContentAccessor, determines the appropriate encoding to use
+ * and reads the stream's contents as a String. Specifically, if the IStreamContentAccessor
+ * is also an IEncodedStreamContentAccessor, that encoding is used. Otherwise, the
+ * platform default encoding is used.
+ */
+ public static String readStreamContents(IStreamContentAccessor sca) throws CoreException {
+ InputStream is= sca.getContents();
+ if (is != null) {
+ String encoding= null;
+ if (sca instanceof IEncodedStreamContentAccessor) {
+ try {
+ encoding= ((IEncodedStreamContentAccessor) sca).getCharset();
+ } catch (Exception e) {
+ }
+ }
+ if (encoding == null)
+ encoding= ResourcesPlugin.getEncoding();
+ return readStreamContents(is, encoding);
+ }
+ return null;
+ }
+
+ /**
+ * Reads the contents of the given reader into a string using the encoding
+ * associated with the reader. Returns null if an error occurred.
+ */
+ public static String readReaderContents(Reader r) {
+ BufferedReader reader= null;
+ try {
+ StringBuffer buffer= new StringBuffer();
+ char[] part= new char[2048];
+ int read= 0;
+ reader= new BufferedReader(r);
+
+ while ((read= reader.read(part)) != -1)
+ buffer.append(part, 0, read);
+
+ return buffer.toString();
+ } catch (IOException ex) {
+ System.err.println("I/O Exception: " + ex.getMessage());
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException ex) {
+ // silently ignored
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Reads the contents of the given input stream into a string using the given encoding.
+ * Returns null if an error occurred.
+ */
+ public static String readStreamContents(InputStream is, String encoding) {
+ try {
+ return readReaderContents(new InputStreamReader(is, encoding));
+ } catch (UnsupportedEncodingException e) {
+ return null;
+ }
+ }
+
+ public static String readStreamContents(InputStream is) {
+ return readStreamContents(is, ResourcesPlugin.getEncoding());
+ }
+}
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/UnimplementedError.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/UnimplementedError.java
new file mode 100644
index 000000000..bf3b8d733
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/utils/UnimplementedError.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+* Copyright (c) 2007 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation
+
+*******************************************************************************/
+
+package org.eclipse.imp.utils;
+
+public class UnimplementedError extends Error {
+ private static final long serialVersionUID= 5077799745785575339L;
+
+ public UnimplementedError() {
+ super();
+ }
+
+ public UnimplementedError(String s) {
+ super(s);
+ }
+}

Back to the top